0

FloatBufferの代わりにAndroidのOpenGLES2.0で頂点にフロートの配列を使用しようとしていますが、使用すると、glDrawArraysでエラー0x502またはGL_INVALID_OPERATIONが発生します。

このエラーは発生せず、FloatBuffersを使用するとすべてが正常に機能します。

このエラーは通常、プログラムが設定されていないことが原因であると読みました。シェーダープログラムを1つだけ使用し、すべてが初期化されたときに設定します。

これが私のコードです

public class LineEngine {
    private static final float[] IDENTIY = new float[16];
    private float[] mLinePoints;
    private float[] mLineColors;
    private int mCount;

    public LineEngine(int maxLines) {
        Matrix.setIdentityM(IDENTIY, 0);

        mLinePoints = new float[maxLines * 2 * 4];
        mLineColors = new float[maxLines * 2 * 4];

        reset();
    }

    public void addLine(float[] position, float[] color) {
        int offset = mCount * 2 * 4;
        System.arraycopy(position, 0, mLinePoints, offset, 8);
        System.arraycopy(color, 0, mLineColors, offset, 4);
        System.arraycopy(color, 0, mLineColors, offset + 4, 4);

        mCount++;
    }

    public void reset() {
        mCount = 0;
    }

    public void draw() {
        if (mCount > 0) {
            GraphicsEngine.setMMatrix(IDENTIY);
            GraphicsEngine.setColors(mLineColors);
            GraphicsEngine.setVertices4d(mLinePoints);
            GraphicsEngine.disableTexture();
            GLES20.glDrawArrays(GLES20.GL_LINES, 0, mCount * 2);

            int error = GLES20.glGetError();
            if (error != 0)
                Log.e("OpenGL", "Draw " + error); // Prints error 1282

            GraphicsEngine.disableColors();
            reset();
        }
    }
}

このコードはエラーなしで正常に動作します

public class LineEngine {
    private static final float[] IDENTIY = new float[16];
    private FloatBuffer mLinePoints;
    private FloatBuffer mLineColors;
    private int mCount;

    public LineEngine(int maxLines) {
        Matrix.setIdentityM(IDENTIY, 0);

        ByteBuffer byteBuf = ByteBuffer.allocateDirect(maxLines * 2 * 4 * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        mLinePoints = byteBuf.asFloatBuffer();

        byteBuf = ByteBuffer.allocateDirect(maxLines * 2 * 4 * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        mLineColors = byteBuf.asFloatBuffer();

        reset();
    }

    public void addLine(float[] position, float[] color) {
        mLinePoints.put(position, 0, 8);
        mLineColors.put(color, 0, 4);
        mLineColors.put(color, 0, 4);
        mCount++;
    }

    public void reset() {
        mLinePoints.position(0);
        mLineColors.position(0);
        mCount = 0;
    }

    public void draw() {
        if (mCount > 0) {
            mLinePoints.position(0);
            mLineColors.position(0);
            GraphicsEngine.setMMatrix(IDENTIY);
            GraphicsEngine.setColors(mLineColors);
            GraphicsEngine.setVertices4d(mLinePoints);
            GraphicsEngine.disableTexture();
            GLES20.glDrawArrays(GLES20.GL_LINES, 0, mCount * 2);

            int error = GLES20.glGetError();
            if (error != 0)
                Log.e("OpenGL", "Draw " + error); // no errors

            GraphicsEngine.disableColors();
            reset();
        }
    }
}

関連するGraphicsEngineコードはこちらです

public static void setVertices4d(FloatBuffer vertices) {
    GLES20.glVertexAttribPointer(aVertexHandle, 4, GLES20.GL_FLOAT, false,
            16, vertices);
    GLES20.glEnableVertexAttribArray(aVertexHandle);
    mState.shape = -1;
}

public static void setVertices4d(float[] vertices) {
    GLES20.glVertexAttrib4fv(aVertexHandle, vertices, 0);
    GLES20.glEnableVertexAttribArray(aVertexHandle);
    mState.shape = -1;
}

public static void setColors(FloatBuffer colors){
    GLES20.glVertexAttribPointer(aColor, 4, GLES20.GL_FLOAT, false,
            16, colors);
    GLES20.glEnableVertexAttribArray(aColor);
    GLES20.glUniform1i(GraphicsEngine.uEnableColors, 1);
}

public static void setColors(float[] colors){
    GLES20.glVertexAttrib4fv(aColor, colors, 0);
    GLES20.glEnableVertexAttribArray(aColor);
    GLES20.glUniform1i(GraphicsEngine.uEnableColors, 1);
}

FloatBuffersは、floatの配列よりも変更が遅いため、使用したくありません。

4

1 に答える 1

3

このコードにはFloatBuffersを使用する以外に選択肢はありません。

setVertices4dを取るメソッドが壊れているため、 glVertexAttrib4fvfloat[]をそのように使用することはできません。glVertexAttrib4は単一の頂点のみを指定し、vバージョンを使用すると、属性の値を配列としてその単一の頂点に渡すだけで、ポインター関数のような頂点配列は設定されません。

于 2012-05-29T05:58:53.980 に答える