php小编鱼仔带来的本期java问答将重点探讨OpenGL ES 3.0中关于黑色纹理的相关问题。在OpenGL ES 3.0中,纹理处理是一个重要的主题,而黑色纹理问题也是开发者们经常会遇到的挑战之一。本文将针对此问题进行详细解答,帮助开发者更好地理解和解决相关疑惑。
我尝试在正方形上渲染一个简单的纹理 .png,但它始终显示为黑色。 在我的示例代码中,渲染了 2 个正方形,其中一个带有纹理 wall.png,第二个带有用于测试的 4 像素字节缓冲区。 我检查了位图的一些像素和大小,它们都没有问题。 4 像素字节缓冲区正在工作,但出现奇怪的故障。 字节缓冲区需要 2 个额外字节的数据,我不知道是什么原因导致的。
感谢您的帮助!!!
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 ); } }
截图
android 提供了简单的 api 用于将位图加载为 opengl 纹理:
GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0);
编辑:您可以在此处找到有关此内容的更多信息https://www.php.cn/link/afd7de3f825e55b48cbc839e095326a4
以上是OpenGL ES 3.0 - 黑色紋理的詳細內容。更多資訊請關注PHP中文網其他相關文章!