-1

我是 Android 中 OpenGl 的初学者,并试图制作一个 Triange,正如您在 Triangle 类下面看到的那样。问题是,当我只是想绘制一个简单的三角形时,代码会在我的设备上运行,但是当我通过矩阵应用投影和相机变换时,应用程序就会崩溃。我正在 Samsun Galaxy Grand 上测试应用程序,该应用程序具有“Broadcom VideoCore IV”作为支持 OpenGL ES 2.0 的 GPU,那么为什么应用程序会崩溃?是三角形类的代码还是设备的渲染器还是设备图形处理单元???(下面给出了三角形和渲染器的类)

三角班:

class Triangle {

    int mProgram;

    private FloatBuffer vertexBuffer;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    float triangleCoords[] = { // in counterclockwise order:
         0.0f,  0.622008459f, 0.0f,   // top
        -0.5f, -0.311004243f, 0.0f,   // bottom left
         0.5f, -0.311004243f, 0.0f    // bottom right
    };

    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    // Set color with red, green, blue and alpha (opacity) values
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

    private final String vertexShaderCode =
            "uniform mat4 uMVPMatrix;   \n" +
            "attribute vec4 vPosition;  \n" +
            "void main() {  \n" +
            "  gl_Position = uMVPMatrix * vPosition;    \n" +
            "}  \n";

    private final String fragmentShaderCode =
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = vColor;" +
            "}";


    public Triangle() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (number of coordinate values * 4 bytes per float)
                triangleCoords.length * 4);
        // use the device hardware's native byte order
        bb.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        vertexBuffer = bb.asFloatBuffer();
        // add the coordinates to the FloatBuffer
        vertexBuffer.put(triangleCoords);
        // set the buffer to read the first coordinate
        vertexBuffer.position(0);

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

        mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables



    }

    public void draw(float[] mvpMatrix) {
        // Add program to OpenGL ES environment

        GLES20.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT, false,
                                     vertexStride, vertexBuffer);

        // get handle to fragment shader's vColor member
        int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        // get handle to shape's transformation matrix
        int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }

    public int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }
}

}

渲染器类:

    public class MyRenderer implements GLSurfaceView.Renderer {

    Triangle mTriangle;
    float ratio;
    int width,height;
    float[] mProjMatrix=new float[16];
    float[] mVMatrix=new float[16];
    float[] mMVPMatrix=new float[16];

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;

        // this projection matrix is applied to object coordinates
        // in the onDrawFrame() method
        Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

        // Set the camera position (View matrix)
        Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // mTriangle=new Triangle();

    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

        // Draw shape
        mTriangle.draw(mMVPMatrix);

    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }

}
4

3 回答 3

1

该错误消息通常意味着 EGL 驱动程序找不到对 OpenGL ES 渲染所需的表面类型的支持,通常是 GL_RGBA。您可能没有为您的 AVD 模拟器启用 OpenGL ES 支持。本指南将对此有所帮助:

http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1

另外,我强烈建议您从一个好的示例程序开始您的 OpenGL ES 开发。本指南也对此有所帮助。

于 2013-06-22T23:56:01.220 回答
0

编辑:您仍然没有澄清崩溃发生的确切位置......

但在这里我发现:

onDrawFrame 中,您尝试绘制实际上不存在的三角形(崩溃的典型原因):

public void onDrawFrame(GL10 unused) {
...
// Draw shape
mTriangle.draw(mMVPMatrix);
}

您必须首先在onSurfaceCreated中初始化三角形:

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
...
// initialize a triangle
mTriangle = new Triangle();

}

请参考这篇 Android 培训文章:

使用 OpenGL ES 显示图形 > 初始化形状

于 2013-06-25T09:53:09.293 回答
0

最初我也面临同样的问题,我的问题是相似的,我可以说如果我在 MainActivity.java 中有你的 MyGLSurfaceView 类, 我已经添加了 super.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 在 setRenderer(mRenderer) 之前;这解决了我的问题。

class MyGLSurfaceView extends GLSurfaceView {

private final MyGLRenderer mRenderer;

public MyGLSurfaceView(Context context){
    super(context);

    // Create an OpenGL ES 2.0 context
    setEGLContextClientVersion(2);

    mRenderer = new MyGLRenderer();

    super.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
    // Set the Renderer for drawing on the GLSurfaceView
    setRenderer(mRenderer);
    }
}

希望即使你有同样的问题

于 2015-06-05T12:03:05.590 回答