Textures that aren't 16x16 fail to load in OpenGL ES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public static int loadTexture(int resourceID) { int textureHandle[] = new int[1]; GLES20.glGenTextures(1, textureHandle, 0); if (textureHandle[0] != 0) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; Bitmap b = BitmapFactory.decodeResource(SlingBall.context.getResources(), resourceID, options); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, b, 0); b.recycle(); } if (textureHandle[0] == 0) { throw new RuntimeException("RUFK"); } return textureHandle[0]; } |
这是我从资源中加载纹理的代码。
这对于加载 16x16 PNG 文件效果很好,但是当尝试加载任何 ISN\\'T 16x16(更小或更大)的文件时,它会变成完全黑色。
我尝试过创建几个新的 PNG,是的,每个 16x16 的文件都能正确加载。
这个函数在 onSurfaceCreated() 中被调用,顺便说一句。
这是怎么回事?
编辑:不妨添加着色器,但我认为它不应该是相关的,因为它们在 16x16 上工作得很好。
顶点
1 2 3 4 5 6 7 8 9 10 | uniform mat4 u_mvpMatrix; attribute vec3 a_vertexPosition; attribute vec2 a_texturePosition; varying vec2 v_texturePosition; void main() { v_texturePosition = a_texturePosition; gl_Position = u_mvpMatrix * vec4(a_vertexPosition, 1.0); } |
片段
1 2 3 4 5 6 7 8 9 10 | precision mediump float; uniform vec4 u_color; uniform sampler2D u_texture; varying vec2 v_texturePosition; void main() { gl_FragColor = texture2D(u_texture, v_texturePosition); } |
(实际上它更多,但我已将其全部用于调试。但没有任何区别。现在甚至没有使用 u_color)
顶点数据
1 2 3 4 5 6 | private static final float vertexData[] = { -1f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f, 1f, 1f, -1f, 0f, 1f, 0f, 1f, 1f, 0f, 1f, 1f }; |
3 表示位置,2 表示纹理位置。
如果我没有应用足够的数据,我很抱歉,但我不知道问题出在哪里,我只是想可能是我在纹理加载时做错了,因为其他一切都适用于 16x16。如果您认为问题可能出在代码中,请告诉我,我将在数据中进行编辑。
如果您使用非二次幂 (NPOT) 纹理,事情可能会变得有点复杂。摘自 OpenGL ES 2.0 规范(第 3.8.2 节 pp.87-88):
1 2 3 4 5 6 7 8 9 | Calling a sampler from a fragment shader will return (R; G; B; A) = (0; 0; 0; 1) if any of the following conditions are true: ... - A two-dimensional sampler is called, the corresponding texture image is a non-power-of-two image (as described in the Mipmapping discussion of section 3.7.7), and either the texture wrap mode is not CLAMP_TO_EDGE, or the mini???cation ???lter is neither NEAREST nor LINEAR. |
因此,请确保您的纹理环绕模式也是
或者你可以尽量避免使用 NPOT 纹理。