SOでこのような質問をいくつか見ましたが、これまでのところ何も役に立ちませんでした。GLTriangleクラスとGLRectangleクラスを作成しました。この2つの形を色で問題なく描くことができます。テクスチャを実装しようとしていますが、動作させる(およびデバッグする)のに問題があります。
私がこれまでに持っているものの関連するコードを投稿しようとします。もっと見る必要がある場合は、私に知らせてください。
編集:わかりました。texcoordハンドラーの間違いを修正した後も、まだ黒い四角が表示されています。glGetErrorが何かを報告するのは、GLES20.glEnable(GLES20.GL_TEXTURE_2D);を呼び出した後だけです。
GLRectangle関連コード:
@Override
public void onSurfaceCreated() {
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = vertexByteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = createAndLinkProgram(VertexShaderHandle(), FragmentShaderHandle(), new String[] { "uMVPMatrix", "vPosition", "a_TexCoordinate" });
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
loadTexture(context, imageId);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
textureCoordBuffer = tbb.asFloatBuffer();
textureCoordBuffer.put(texCoords).position(0);
}
そしてonDrawFrameで:
GLES20.glUseProgram(mProgram);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle);
Matrix.multiplyMM(mMVPMatrix, 0, projMatrix, 0, mvMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
GLES20.glUniform1i(mTextureUniformHandle, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
ロード時にintハンドルが返されるので、ビットマップがロードされていることはわかっています。少なくとも、かなり確信しています(intが0の場合、ランタイムエラーが発生します)。
テクスチャの座標と関係があると思います。
これが私のtex座標のために持っているものです:
texCoords = new float[] {
0, 0,
0, 1,
1, 1,
1, 0
};
それがテクスチャローダーを備えたものである場合に備えて、ここにあります:
int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
if (textureHandle[0] != 0) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
final Bitmap bitmap = BitmapFactory.decodeResource(view.getContext().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_LINEAR);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
if (textureHandle[0] == 0) {
throw new RuntimeException("Unable to load texture!");
}
mTextureDataHandle = textureHandle[0];
編集:シェーダーを追加するのを忘れました。今はコードで文字列を設定しています:
setVertexShader(
"uniform mat4 uMVPMatrix; \n" +
"uniform mat4 MVMatrix; \n" +
"attribute vec4 vPosition; \n" +
"attribute vec2 a_TexCoordinate; \n" +
"varying vec2 v_TexCoordinate; \n" +
"void main() { \n" +
"v_TexCoordinate = a_TexCoordinate; \n" +
"gl_Position = uMVPMatrix * vPosition; \n" +
"} \n");
setFragmentShader("precision mediump float; \n" +
"uniform sampler2D u_Texture; \n" +
"varying vec2 v_TexCoordinate; \n" +
"void main() { \n" +
"gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n" +
"} \n");