0

OpenGL ES の仕組みを学びながら、テクスチャ付きの正方形を画面に表示しようとしています。正方形に関連するコードは次のとおりです。コードは Google の例に基づいています。

public class Shape2Square {

private static final String TAG = "Shape2Square";
private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "attribute vec2 a_TexCoordinate;"+
        "varying vec2 v_TexCoordinate;"+
        "void main() {" +
        "v_TexCoordinate = a_TexCoordinate;"+
        "gl_Position = uMVPMatrix * vPosition;" +
        "}";

    private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform sampler2D u_Texture"+
        "varying vec2 v_TexCoordinate;"+
        "void main() {" +
        "gl_FragColor = texture2D(u_Texture, v_TexCoordinate);"+
        "}";
    private final FloatBuffer vertexBuffer;
    private final FloatBuffer textureBuffer;
    private final ShortBuffer drawListBuffer;
    private final int mProgram;
    private int mPositionHandle;
    private int mMVPMatrixHandle;
    private int mtexture;
    private int mtexCoordHandler;
    private int mtextureHandler;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = { -0.3f,  -0.3f, 0.0f,   // top left
                                    -0.3f, 0.3f, 0.0f,   // bottom left
                                     0.3f, 0.3f, 0.0f,   // bottom right
                                     0.3f,  -0.3f, 0.0f }; // top right
    // u,v 
    static float texturedata[] =   {0.0f, 0.0f,
                           0.0f, 1.0f,
                           1.0f, 1.0f,
                           1.0f, 0.0f};


    private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 };

    private final int vertexStride = COORDS_PER_VERTEX * 4;

    public Shape2Square() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);

        ByteBuffer bbtexture = ByteBuffer.allocateDirect(texturedata.length*4);
        bbtexture.order(ByteOrder.nativeOrder());
        textureBuffer = bbtexture.asFloatBuffer();
        textureBuffer.put(texturedata);
        textureBuffer.position(0);

        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);

        int vertexShader = CommonMethods.loadShader(GLES20.GL_VERTEX_SHADER,
                                                   vertexShaderCode);
        int fragmentShader = CommonMethods.loadShader(GLES20.GL_FRAGMENT_SHADER,
                                                     fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();       
        Shape2Square.checkGlError("glCreateProgram");     
        GLES20.glAttachShader(mProgram, vertexShader); 
        Shape2Square.checkGlError("glAttachShader"); 
        GLES20.glAttachShader(mProgram, fragmentShader);
        Shape2Square.checkGlError("glAttachShader"); 
        GLES20.glLinkProgram(mProgram);
        Shape2Square.checkGlError("glLinkProgram");                 
    }

私が logcat から得た問題は、この正方形の「描画」メソッドを指しています。CommonMethods.loadTextureビットマップ コードを OPEN GL にロードするだけであることに注意してください。

EDIT1: (コード全体に checkGlErrors を追加)

    public void draw(float[] mvpMatrix, int textureid) {
        GLES20.glUseProgram(mProgram);
        Shape2Square.checkGlError("glUseProgram");



        vertexBuffer.position(0);
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        Shape2Square.checkGlError("glVertexAttribPointer");
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
        Shape2Square.checkGlError("glVertexAttribPointer");
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        Shape2Square.checkGlError("glEnableVertexAttribArray");


        textureBuffer.position(0);  
        mtexCoordHandler = GLES20.glGetAttribLocation(mProgram,"a_TexCoordinate");
        Shape2Square.checkGlError("glGetAttribLocation");
        GLES20.glEnableVertexAttribArray(mtexCoordHandler);
        Shape2Square.checkGlError("glEnableVertexAttribArray");
        GLES20.glVertexAttribPointer(mtexCoordHandler, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);            
        Shape2Square.checkGlError("glVertexAttribPointer");


        mtextureHandler = GLES20.glGetUniformLocation(mProgram, "u_Texture");
        Shape2Square.checkGlError("mtextureHandler");
        mtexture = CommonMethods.loadTexture(textureid);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        Shape2Square.checkGlError("glActiveTexture");
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mtexture);
        Shape2Square.checkGlError("glBindTexture");
        GLES20.glUniform1i(mtextureHandler, 0);      
        Shape2Square.checkGlError("glUniform1i");

        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        Shape2Square.checkGlError("glGetUniformLocation");

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        Shape2Square.checkGlError("glUniformMatrix4fv");

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
                              GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
        Shape2Square.checkGlError("glDrawElements");

        GLES20.glDisableVertexAttribArray(mPositionHandle);
        Shape2Square.checkGlError("glDisableVertexAttribArray");



    }
    public static void checkGlError(String glOperation) {
        int error;
        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
            Log.e(TAG, glOperation + ": glError " + error);
            throw new RuntimeException(glOperation + ": glError " + error);
        }
    }

これを行うと、エラーが発生し、アプリケーションが強制的にシャットダウンされます。logcat は、コードをいじった後glGetUniformLocationの最も可能性の高い犯人につながりmMVPMatrixHandleます。これは、以前は機能していたため、奇妙です。私の主張を証明するために、すべてのテクスチャ コードを削除し、代わりに (実際のコードと fragmentShadercode の両方で) vColor を通常の関連性をすべて追加すると、色付きの正方形が得られます。間違いの原因や修正方法がわからないglGetUniformLocationので、助けていただければ幸いです。

EDIT1:「glgetuniformlocation」の checkglerror を消去しようとしましたが、エラーが「glUniformMatrix4fv」の形式で表示されるようになったため、これはがっかりしました。何かがひどく間違っている...

EDIT2: コード全体で checkglerror を使用することにしましたが、これまでのところ、描画メソッド全体 (glUseProgram を含む) にエラーがあるようです。draw メソッド (シェーダーのアタッチとリンクを含む) の前に発生する gl ビットは問題なく問題ありません。

4

1 に答える 1