对不起特定问题,但我找不到任何解释我的问题。我几乎可以肯定这是我忽略的一个愚蠢的错误。
我只想在屏幕上绘制一个基本的多色矩形。它工作正常,我甚至得到了模型 - 视图 - 投影矩阵的代码工作。但是,我发现当我尝试重新分配我用作MVP矩阵的统一值时,程序在渲染几百次后会突然失败。虽然最初几分钟我完全得到了我想要的东西,但在300次调用统一更新方法之后,我得到了一个完全不同的屏幕,其中有一个我从未要求的奇怪形状和颜色。
我尝试将代码减少到最低限度。我的片段着色器:
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
我的顶点着色器:
uniform mat4 u_MVP;
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
v_Color = a_Color;
gl_Position = u_MVP * a_Position;
}
调用它的Java:
package com.ulyssecarion.openglsandbox;
import static android.opengl.GLES20.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.util.Log;
import com.ulyssecarion.openglsandbox.util.ShaderHelper;
import com.ulyssecarion.openglsandbox.util.TextResourceReader;
public class OpenGLSandboxRenderer implements Renderer {
private static final String TAG = "SandboxRenderer";
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int BYTES_PER_FLOAT = 4;
private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT)
* BYTES_PER_FLOAT;
private static final String U_MVP = "u_MVP";
private static final String A_COLOR = "a_Color";
private static final String A_POSITION = "a_Position";
private float[] mvp;
private float time;
private int width;
private int height;
private int uMVP;
private int aColor;
private int aPosition;
private Context context;
private int program;
public OpenGLSandboxRenderer(Context context) {
time = 0;
this.context = context;
}
@Override
public void onDrawFrame(GL10 arg0) {
glClear(GL_COLOR_BUFFER_BIT);
setMVP(width, height);
glUniformMatrix4fv(uMVP, 1, false, mvp, 0);
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
}
private static FloatBuffer toFB(float[] x) {
ByteBuffer byteBuf = ByteBuffer.allocateDirect(x.length
* BYTES_PER_FLOAT);
byteBuf.order(ByteOrder.nativeOrder());
FloatBuffer buffer = byteBuf.asFloatBuffer();
buffer.put(x);
buffer.position(0);
return buffer;
}
@Override
public void onSurfaceChanged(GL10 arg0, int width, int height) {
glViewport(0, 0, width, height);
uMVP = glGetUniformLocation(program, U_MVP);
aColor = glGetAttribLocation(program, A_COLOR);
aPosition = glGetAttribLocation(program, A_POSITION);
Log.d(TAG, "MVP at: " + uMVP);
setMVP(width, height);
glUniformMatrix4fv(uMVP, 1, false, mvp, 0);
// @formatter:off
float[] points = {
0.0f, 0.0f, 1, 1, 1,
-0.5f, -0.5f, 0, 1, 0,
0.5f, -0.5f, 0, 0, 1,
0.5f, 0.5f, 1, 1, 0,
-0.5f, 0.5f, 0, 1, 1,
-0.5f, -0.5f, 0, 1, 0
};
// @formatter:on
FloatBuffer pointData = toFB(points);
glVertexAttribPointer(aPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, pointData);
glEnableVertexAttribArray(aPosition);
pointData.position(POSITION_COMPONENT_COUNT);
glVertexAttribPointer(aColor, COLOR_COMPONENT_COUNT, GL_FLOAT, false,
STRIDE, pointData);
glEnableVertexAttribArray(aColor);
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
glClearColor(0, 0, 0, 0);
String vertexShaderSrc = TextResourceReader.readTextFileFromResource(
context, R.raw.simple_vertex_shader);
String fragmentShaderSrc = TextResourceReader.readTextFileFromResource(
context, R.raw.simple_fragment_shader);
int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSrc);
int fragmentShader = ShaderHelper
.compileFragmentShader(fragmentShaderSrc);
program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
glUseProgram(program);
}
private void setMVP(int width, int height) {
mvp = new float[16];
Matrix.setIdentityM(mvp, 0);
Log.d(TAG, "Setting MVP: " + time++);
}
}
TextResourceReader
和ShaderHelper
类是样板类,我确信它们可以正常工作。
有什么想法吗?
编辑:
通常情况如下:
编辑#2
这就是疯狂时的样子:
另一个例子:
(抱歉这些巨大的图片)
注意:结果并不总是如上所示。以前,它通常会导致黑屏。