特定の問題について申し訳ありませんが、私の問題の説明が見つかりません。私が見落としているのはばかげた間違いだとほぼ確信しています。
基本的な多色の長方形を画面に描画したいだけです。それは問題なく動作し、モデル ビュー プロジェクション マトリックスが機能するコードも取得しました。しかし、MVP マトリックスとして使用するユニフォームの値を再割り当てしようとすると、数百回レンダリングした後にプログラムが突然失敗することがわかりました。最初の数分間はまさに私が望むものを持っていますが、uniform-update メソッドを約 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
これは、狂ったときの様子です。
もう一つの例:
(巨大な画像で申し訳ありません)
注: 結果は常に上記のようになるとは限りません。以前は、通常、黒い画面が表示されていました。