Android Can';在设备上看不到纹理,但在模拟器上可以看到。OpenGL错误0x502
我正在尝试使用OpenGL在Android上的正方形上渲染512x512纹理。当我使用emulator时,我的程序运行良好,但是如果我使用Nexus7(旧的),glGetError()返回1282。这发生在我在渲染循环中调用glUseProgram之后。GLUtils.getEGLErrorString表示错误1282对应于错误0x502,表示GL_无效_操作 我试过答案、答案和文章中提到的解决方案。我已经尝试将我的纹理放入可绘制的nodpi中,并且我还确保我的纹理大小是二的幂。我还尝试将我的纹理放入res/raw中,并采用另一种加载纹理的方法,但这也不起作用 有人能给我指出正确的方向吗 如果有什么我可以做,以改善我的问题,请让我知道 我的着色器:Android Can';在设备上看不到纹理,但在模拟器上可以看到。OpenGL错误0x502,android,opengl-es,Android,Opengl Es,我正在尝试使用OpenGL在Android上的正方形上渲染512x512纹理。当我使用emulator时,我的程序运行良好,但是如果我使用Nexus7(旧的),glGetError()返回1282。这发生在我在渲染循环中调用glUseProgram之后。GLUtils.getEGLErrorString表示错误1282对应于错误0x502,表示GL_无效_操作 我试过答案、答案和文章中提到的解决方案。我已经尝试将我的纹理放入可绘制的nodpi中,并且我还确保我的纹理大小是二的幂。我还尝试将我的纹
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
// Per-vertex texture coordinate info we will pass in
"attribute vec2 a_TexCoordinate;" +
// This will be passed into the fragment shader
"varying vec2 v_TexCoordinate;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
" gl_Position = vPosition * uMVPMatrix;" +
" v_TexCoordinate = a_TexCoordinate;" +
"}";
private final String fragmentShaderCode =
// The input texture
"uniform sampler2D u_Texture;" +
// Interpolated texture coordinate per fragment
"varying vec2 v_TexCoordinate;" +
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = (vColor * texture2D(u_Texture, v_TexCoordinate));" +
"}";
我的抽签电话:
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(shaderProgramHandle);
// POSITION INFO - Get a handle to the position attribute in the shader and
// associate the vertices with it
int vPositionHandle = GLES20.glGetAttribLocation(shaderProgramHandle, "vPosition");
GLES20.glEnableVertexAttribArray(vPositionHandle);
GLES20.glVertexAttribPointer(
vPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
COORDS_PER_VERTEX * BYTES_PER_COORD,
vertexBuffer);
// COLOR INFO - Get a handle to the color attribute in the shader and associate
// the color with it
int vColorHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "vColor");
GLES20.glUniform4fv(vColorHandle, 1, vertexColor, 0);
// TRANSFORM INFO - Get a handle to the MVP matrix uniform in the shader and
// associate the MVP matrix with it
int uMVPHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "uMVPMatrix");
GLES20.glUniformMatrix4fv(uMVPHandle, 1, false, mvpMatrix, 0);
// TEXTURE INFO
int texCoordinateHandle = GLES20.glGetAttribLocation(shaderProgramHandle, "a_TexCoordinate");
GLES20.glEnableVertexAttribArray(texCoordinateHandle);
GLES20.glVertexAttribPointer(
texCoordinateHandle,
COORDS_PER_TEX,
GLES20.GL_FLOAT,
false,
0,
textureCoordinatesBuffer);
int texUniformHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "u_Texture");
// Set the active texture unit to texture unit 0
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureDataHandle);
// Tell the texture uniform sampler to use this texture in the shader
// by binding to texture unit 0
GLES20.glUniform1i(texUniformHandle, 0);
// Draw the square
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
// Cleanup
GLES20.glDisableVertexAttribArray(vPositionHandle);
GLES20.glDisableVertexAttribArray(texCoordinateHandle);
}
我正在GLSurfaceView.Renderer的onSurfaceCreated实现中加载纹理。
下面是一个显示如何加载纹理的片段
int loadTexture(final Context context, final int resourceId) {
final int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
Utils.checkGLError("glGenTextures");
if (textureHandle[0] != 0) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false; // No pre-scalings
// Read in the resource
final Bitmap bitmap = BitmapFactory.decodeResource(
context.getResources(),
resourceId,
options);
// InputStream is = context.getResources().openRawResource(resourceId);
// Bitmap bitmap = null;
// try {
// bitmap = BitmapFactory.decodeStream(is);
// } finally {
// //Always clear and close
// try {
// is.close();
// is = null;
// } catch (IOException e) {
// }
// }
// Bind to the texture in OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
// 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);
// GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
// GLES20.GL_CLAMP_TO_EDGE);
// GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
// GLES20.GL_CLAMP_TO_EDGE);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Recycle the bitmap, since its data has been loaded into OpenGL.
bitmap.recycle();
}
if (textureHandle[0] == 0) {
throw new RuntimeException("Error loading texture.");
}
return textureHandle[0];
}
所有OpenGL枚举常量(例如错误代码)都是base-16,以供将来参考。如果您试图查找十进制表示形式,您会遇到很大的困难,但是如果您使用十六进制,您可以通过在
gl.h
中的任何文本编辑器中查找0x…
立即找到令牌名称,其形式为:\define gl\uu。。。0x…
。我知道您使用的是Java,但是gl.h
很容易找到,另一方面,十进制OpenGL常量值很难找到。这个程序在模拟器中运行正常吗?我这样问是因为如果您使用OpenGL中预期的列主矩阵,“+无效。在这句话中,矩阵应该在左边。在实际问题上:glUseProgram(…)
在您尝试使用未正确链接的程序时,通常会生成GL\u INVALID\u操作。查看着色器/程序信息日志,它们会告诉您这里到底发生了什么。看:。@AndonM.Coleman:是的,我刚想到使用hex可能是个好主意。@AndonM.Coleman:非常感谢!!我修好了!glGetShaderInfoLog和glGetProgramInfoLog是一个很大的帮助!!我没有在片段着色器中正确声明精度。我把我的声明放在了我计划的顶端,现在它似乎起作用了。Re:矩阵乘法-是的,它在模拟器中运行良好,现在似乎在设备上也能正常工作。嗯,这是一个很好的观点。我想知道它为什么有效?