Rumah  >  Artikel  >  OpenGL ES 3.0 - tekstur hitam

OpenGL ES 3.0 - tekstur hitam

WBOY
WBOYke hadapan
2024-02-22 12:30:10939semak imbas

Soal Jawab java yang dibawakan oleh editor php Yuzai ini akan memfokuskan kepada isu berkaitan tekstur hitam dalam OpenGL ES 3.0. Dalam OpenGL ES 3.0, pemprosesan tekstur adalah topik penting, dan masalah tekstur hitam juga merupakan salah satu cabaran yang sering dihadapi oleh pembangun. Artikel ini akan memberikan jawapan terperinci kepada soalan ini untuk membantu pembangun lebih memahami dan menyelesaikan keraguan yang berkaitan.

Kandungan soalan

Saya cuba menghasilkan tekstur mudah .png pada segi empat sama, tetapi ia sentiasa kelihatan hitam. Dalam kod contoh saya, 2 petak diberikan, satu dengan wall.png tekstur dan yang kedua dengan penimbal bait 4 piksel untuk ujian. Saya menyemak beberapa piksel dan saiz bitmap dan semuanya baik-baik saja. Penampan bait 4 piksel berfungsi tetapi dengan gangguan pelik. Penampan bait memerlukan 2 bait data tambahan, saya tidak tahu apa yang menyebabkannya.

Terima kasih atas bantuan anda! ! !

package com.example.opengles3_test1;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class Renderer_Texture implements GLSurfaceView.Renderer {
    private static String TAG = "Renderer"; //For LOG
    final int VERTEX_POS_SIZE = 3; // x, y and z
    final int VERTEX_COLOR_SIZE = 4; // r, g, b, and a
    final int VERTEX_TEXTUR_SIZE=2; //x,y
    final int VERTEX_POS_INDX = 0;
    final int VERTEX_COLOR_INDX = 1;
    final int VERTEX_TEXTUR_INDX = 2;
    final int VERTEX_STRIDE = (4 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE+VERTEX_TEXTUR_SIZE));
    // 3 vertices, with (x,y,z) ,(r, g, b, a), (x,y) per-vertex
    final int[] textures = new int[2];
    private final float[] mVerticesData =
            {
            // positions          // colors           // texture coords
            -0.1f,  0.4f, 0.0f,   1.0f, 0.0f, 0.0f, 1.0f,  1.0f, 1.0f, // top right
            -0.1f, -0.4f, 0.0f,   0.0f, 1.0f, 0.0f, 1.0f,  1.0f, 0.0f, // bottom right
            -0.8f, -0.4f, 0.0f,   0.0f, 0.0f, 1.0f, 1.0f,  0.0f, 0.0f, // bottom left
            -0.8f,  0.4f, 0.0f,   1.0f, 1.0f, 0.0f, 1.0f,  0.0f, 1.0f  // top left

            };
    private final float[] mVerticesData2 =
            {
                    // positions          // colors           // texture coords
                    0.8f,  0.4f, 0.0f,   1.0f, 0.0f, 0.0f, 1.0f,  1.0f, 1.0f, // top right
                    0.8f, -0.4f, 0.0f,   0.0f, 1.0f, 0.0f, 1.0f,  1.0f, 0.0f, // bottom right
                    0.1f, -0.4f, 0.0f,   0.0f, 0.0f, 1.0f, 1.0f,  0.0f, 0.0f, // bottom left
                    0.1f,  0.4f, 0.0f,   1.0f, 1.0f, 0.0f, 1.0f,  0.0f, 1.0f  // top left

            };
      private final short[] mIndicesData =
            {
                    0, 1, 3 , 1, 2, 3
            };
    ShaderV1 Shaderprog1;
    private int[] VBOIds = new int[4]; // VertexBufferObject Ids
    private int[] VAOId = new int[2]; // VertexArrayObject Id
       private int mWidth;
    private int mHeight;
    private FloatBuffer mVertices;
    private ShortBuffer mIndices;
    private FloatBuffer mVertices2;

    public Renderer_Texture(Context context) {
        mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        mVertices.put(mVerticesData).position(0);
        mVertices2 = ByteBuffer.allocateDirect(mVerticesData2.length * 4)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        mVertices2.put(mVerticesData2).position(0);
        mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2)
                .order(ByteOrder.nativeOrder()).asShortBuffer();
        mIndices.put(mIndicesData).position(0);
    }

        private static Bitmap convertBitmapToConfig(Bitmap bitmap, Bitmap.Config config) {
            if (bitmap.getConfig() == config) {
                return bitmap;
            }
            Bitmap result = bitmap.copy(config, false);
            bitmap.recycle();
            return result;
        }

    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {

        Shaderprog1= new ShaderV1("res/raw/vertext_shader1.vs", "res/raw/fragment_shader1.fs");

        GLES30.glGenBuffers(4, VBOIds, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBOIds[0]);
        mVertices.position(0);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, mVerticesData.length * 4,
                mVertices, GLES30.GL_STATIC_DRAW);
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, VBOIds[1]);
        mIndices.position(0);
        GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER, 2 * mIndicesData.length,
                mIndices, GLES30.GL_STATIC_DRAW);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBOIds[2]);
        mVertices2.position(0);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, mVerticesData2.length * 4,
                mVertices2, GLES30.GL_STATIC_DRAW);

        GLES30.glGenVertexArrays(2, VAOId, 0);

        GLES30.glBindVertexArray(VAOId[0]);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBOIds[0]);
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, VBOIds[1]);
        GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX);
        GLES30.glEnableVertexAttribArray(VERTEX_COLOR_INDX);
        GLES30.glEnableVertexAttribArray(VERTEX_TEXTUR_INDX);
        GLES30.glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                0);
        GLES30.glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                (VERTEX_POS_SIZE * 4));
        GLES30.glVertexAttribPointer(VERTEX_TEXTUR_INDX, VERTEX_TEXTUR_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                (VERTEX_POS_SIZE * 4+VERTEX_COLOR_SIZE*4));
        //second:
        GLES30.glBindVertexArray(VAOId[1]);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBOIds[2]);
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, VBOIds[1]);
        GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX);
        GLES30.glEnableVertexAttribArray(VERTEX_COLOR_INDX);
        GLES30.glEnableVertexAttribArray(VERTEX_TEXTUR_INDX);
        GLES30.glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                0);
        GLES30.glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                (VERTEX_POS_SIZE * 4));
        GLES30.glVertexAttribPointer(VERTEX_TEXTUR_INDX, VERTEX_TEXTUR_SIZE,
                GLES30.GL_FLOAT, false, VERTEX_STRIDE,
                (VERTEX_POS_SIZE * 4+VERTEX_COLOR_SIZE*4));
        // Reset to the default VAO
        GLES30.glBindVertexArray(0);

        GLES30.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);

        GLES30.glGenTextures(2, textures,0);
        if (textures[0] == 0) {
           Log.e(TAG,"could not bind texture");
           return;
        }
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0]);
        // set the texture wrapping parameters
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
        // set texture filtering parameters
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);

            Bitmap bitmap = null;
            try {
                bitmap =convertBitmapToConfig(BitmapFactory.decodeStream(ShaderV1.class.getClassLoader().getResourceAsStream("res/raw/wall.jpg")), Bitmap.Config.ARGB_8888);
                ByteBuffer buffer = ByteBuffer.allocateDirect(bitmap.getByteCount());
                bitmap.copyPixelsToBuffer(buffer);
                buffer.rewind();
                GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0]);
                GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D,0, GLES30.GL_RGB, bitmap.getWidth(), bitmap.getHeight(),  0,  GLES30.GL_RGBA,  GLES30.GL_UNSIGNED_BYTE, buffer);
                //Log.e(TAG,"pixel "+ String.format("#%06X", (0xFFFFFF & bitmap.getPixel(200,200)))); //looks correct
                //Log.d(TAG,"bitmapsize:" + bitmap.getWidth() +" " + bitmap.getHeight()); //looks correct
                GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);
            } catch (Exception e) {
                Log.e(TAG,"texture error "+ e.getLocalizedMessage());
            } finally {
                if (bitmap != null) {
                    bitmap.recycle();
                }
            }
                byte[] bytes = {
            //  R           G            B      
                (byte) 0xcf,(byte) 0x00,(byte) 0x00,  //EDGE 1
                (byte) 0x8f,(byte) 0x00,(byte) 0x50,(byte) 0x00,(byte) 0x00, //EDGE 2 WTF 2 extra?!?
                (byte) 0x5f,(byte) 0x80,(byte) 0x00, //EDGE 3
                (byte) 0x3f,(byte) 0x00,(byte) 0x80}; //EDGE 4
        ByteBuffer b = ByteBuffer.wrap(bytes);

        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[1]);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE); //GLES30.GL_REPEAT also work
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE); //GLES30.GL_REPEAT also work
        // set texture filtering parameters
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);

        GLES30.glTexImage2D ( GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGB, 2, 2, 0, GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, b );
        GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);
            Shaderprog1.use();
        GLES30.glUniform1i(GLES30.glGetUniformLocation(Shaderprog1.getID(), "texture1"), 0);
    }

    public void onDrawFrame(GL10 glUnused) {
        GLES30.glViewport(0, 0, mWidth, mHeight);
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);

        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[1]);
        Shaderprog1.use();

        GLES30.glBindVertexArray(VAOId[0]);
        GLES30.glDrawElements(GLES30.GL_TRIANGLES, mIndicesData.length, GLES30.GL_UNSIGNED_SHORT, 0);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0]);
        GLES30.glBindVertexArray(VAOId[1]);
        GLES30.glDrawElements(GLES30.GL_TRIANGLES, mIndicesData.length, GLES30.GL_UNSIGNED_SHORT, 0);

        GLES30.glBindVertexArray(0);
    }

    public void onSurfaceChanged(GL10 glUnused, int width, int height) {
        mWidth = width;
        mHeight = height;
        Log.d ( TAG, width +" "+ height );
    }
}

Screenshot

Solution

android menyediakan api mudah untuk memuatkan bitmap sebagai tekstur opengl:

GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0);

EDIT: Anda boleh mendapatkan maklumat lanjut tentang kandungan ini di sinihttps://www.php.cn/link/afd7de3f825e55b48cbc839e095326a4

Atas ialah kandungan terperinci OpenGL ES 3.0 - tekstur hitam. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam