抱歉具体问题,但我找不到我的问题的任何解释。我几乎可以肯定这是我忽略的一个愚蠢的错误。
我只想在屏幕上绘制一个基本的多色矩形。它工作得很好,我什至得到了模型-视图-投影矩阵的代码。但是,我发现当我尝试重新分配我用作MVP矩阵的uniform的值时,程序会在渲染几百次后突然失败。虽然最初的几分钟我得到了我想要的东西,但在调用了大约 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
这是它发疯时的样子:
另一个例子:
(对不起,巨大的图像)
注意:结果并不总是如上所示。以前,它通常会导致黑屏。