Maison  >  Article  >  OpenGL ES 3.0 - texture noire

OpenGL ES 3.0 - texture noire

WBOY
WBOYavant
2024-02-22 12:30:10897parcourir

Cette séance de questions-réponses Java présentée par l'éditeur php Yuzai se concentrera sur les problèmes liés à la texture noire dans OpenGL ES 3.0. Dans OpenGL ES 3.0, le traitement des textures est un sujet important, et le problème de la texture noire est également l'un des défis souvent rencontrés par les développeurs. Cet article fournira une réponse détaillée à cette question pour aider les développeurs à mieux comprendre et résoudre les doutes associés.

Contenu de la question

J'essaie de restituer une texture simple .png sur un carré, mais elle apparaît toujours noire. Dans mon exemple de code, 2 carrés sont rendus, un avec la texture wall.png et le second avec un tampon d'octets de 4 pixels pour les tests. J'ai vérifié certains pixels et tailles du bitmap et tout va bien. Le tampon d'octets de 4 pixels fonctionne mais avec des problèmes étranges. Le tampon d'octets nécessite 2 octets de données supplémentaires, je ne sais pas quelle en est la cause.

Merci pour votre aide ! ! !

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 );
    }
}

Capture d'écran

Solution

android fournit une API simple pour charger des bitmaps en tant que textures opengl :

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

EDIT : Vous pouvez trouver plus d'informations sur ce contenu icihttps://www.php.cn/link/afd7de3f825e55b48cbc839e095326a4

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer