android - onDrawFrame 内 glDrawArrays 上的致命信号(GLSurfaceView.Renderer、SurfaceTexture.OnFrameAvailableListener)

标签 android opengl-es-2.0 shader textures

我收到了 Fatal Signal 11 之后

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

在我的 OnDrawFrame 函数中调用。纹理在崩溃前绘制正确,我相信这意味着我的顶点和 fragment 着色器工作正常。

我想做的是使用 GLSurfaceView.Renderer 和 SurfaceTexture.OnFrameAvailableListener 将两个纹理混合在一起。

第一个纹理是一个实时相机预览 SurfaceTexture,它自己可以很好地工作。第二个 tetxure 只是一个位图图像,它自己也可以正常工作。但将它们结合起来会导致崩溃。

我的OnDrawFrame如下:

public void onDrawFrame(GL10 glUnused) { 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    synchronized(this) { 
        if (updateSurface) {
            mSurface.updateTexImage();
            mSurface.getTransformMatrix(mSTMatrix);
            updateSurface = false;
        }
    } 

    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
    muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");

    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
    //        GLES20.glUniform1i(t1h, textures[0]);
    GLES20.glUniform1i(t1h, 1);

    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    int t2h = GLES20.glGetUniformLocation ( mProgram, "sTexture2" );
    GLES20.glUniform1i(t2h, 2);

    GLES20.glUseProgram(mProgram);

    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

    mTriangleVertices.position(0);
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
            4*5, mTriangleVertices);

    mTriangleVertices.position(3);
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
            4*5, mTriangleVertices);

    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);  
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
    GLES20.glUniform1f(muCRatioHandle, mCameraRatio);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    GLES20.glDisableVertexAttribArray(maPositionHandle);
    GLES20.glDisableVertexAttribArray(maTextureHandle);
    //        GLES20.glFlush();
}

mTriangleVertices 在哪里:

mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length
            * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleVertices.put(mTriangleVerticesData).position(0);

mTriangleVerticesData 是:

private final float[] mTriangleVerticesData = {
    // X, Y, Z, U, V
    -1.0f, -1.0f, 0, 0.f, 0.f,
    1.0f, -1.0f, 0, 1.f, 0.f,
    -1.0f,  1.0f, 0, 0.f, 1.f,
    1.0f,   1.0f, 0, 1.f, 1.f,
};

任何提示、链接甚至代码 fragment 都将不胜感激!

提前致谢

最佳答案

不知道这是否是导致崩溃的原因,但您至少为着色器分配了一个过高的纹理 ID。例如;

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
GLES20.glUniform1i(t1h, 1);

应该阅读

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
GLES20.glUniform1i(t1h, 0);

编辑:啊,这可能是崩溃的原因:

GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
        4*5, mTriangleVertices);

应该是

GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
        4*5, mTriangleVertices);

更有可能,因为每个顶点有两个纹理值。

关于android - onDrawFrame 内 glDrawArrays 上的致命信号(GLSurfaceView.Renderer、SurfaceTexture.OnFrameAvailableListener),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15955430/

相关文章:

ios - 将向量 <float> 转换为 GLfloat

c++ - OpenGL 中的着色器问题

java - LWJGL 顶点着色器 gl_PointSize 不工作

c++ - in vec 和 out vec 是什么意思?

android - GPS 位置更改通知

android - 延迟 MockWebServer 响应

java - 如何使用着色器为使用 GL_LINES 和 OpenGL ES 2.0 绘制的线条着色

ios - 使用 GLKit 加载立方体贴图后,iOS 上 openGL ES 2.0 的正确立方体贴图坐标是多少?

java - 检索 HashMap 数据 SharedPreferences

android - RecyclerView 中的快速滚动