Heim  >  Artikel  >  OpenGL ES 3.0 – schwarze Textur

OpenGL ES 3.0 – schwarze Textur

WBOY
WBOYnach vorne
2024-02-22 12:30:10896Durchsuche

Diese Java-Fragen und Antworten des PHP-Editors Yuzai konzentrieren sich auf die Probleme im Zusammenhang mit der schwarzen Textur in OpenGL ES 3.0. In OpenGL ES 3.0 ist die Texturverarbeitung ein wichtiges Thema, und das Problem der schwarzen Textur ist auch eine der Herausforderungen, mit denen Entwickler häufig konfrontiert sind. Dieser Artikel bietet eine detaillierte Antwort auf diese Frage, um Entwicklern zu helfen, damit verbundene Zweifel besser zu verstehen und auszuräumen.

Inhalt der Frage

Ich versuche, eine einfache PNG-Textur auf einem Quadrat zu rendern, aber sie erscheint immer schwarz. In meinem Beispielcode werden 2 Quadrate gerendert, eines mit der Textur wall.png und das zweite mit einem 4-Pixel-Byte-Puffer zum Testen. Ich habe einige Pixel und Größen der Bitmap überprüft und sie sind alle in Ordnung. Der 4-Pixel-Byte-Puffer funktioniert, es treten jedoch seltsame Störungen auf. Der Bytepuffer benötigt 2 zusätzliche Bytes an Daten, ich weiß nicht, was die Ursache ist.

Danke für deine Hilfe! ! !

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

Lösung

Android bietet eine einfache API zum Laden von Bitmaps als OpenGL-Texturen:

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

EDIT: Weitere Informationen zu diesem Inhalt finden Sie hierhttps://www.php.cn/link/afd7de3f825e55b48cbc839e095326a4

Das obige ist der detaillierte Inhalt vonOpenGL ES 3.0 – schwarze Textur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen