使用OpeGL ES创建三角形时获得黑屏

时间:2018-02-13 13:43:18

标签: android opengl-es-2.0

我正在制作一个示例OpenGL ES android应用程序,引用android开发者网站。 我想画一个三角形。 我已经完成了他们所说的一切,但我最终得到了黑屏。 请帮我解决这个问题。

我把所有的类都写成了主要活动的内部类。

这是主要活动

public class MainActivity extends AppCompatActivity {

private GLSurfaceView surfaceView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    surfaceView=new MyGLSurfaceView(this);
    setContentView(surfaceView);
}

class MyGLSurfaceView extends GLSurfaceView{

    MyGLRenderer myGLRenderer;
    Triangle triangle;

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

        //initialiging triangle
        triangle=new Triangle();

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

        myGLRenderer=new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(myGLRenderer);

    }
}

static class MyGLRenderer implements GLSurfaceView.Renderer{
    Triangle triangle=new Triangle();

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        // Set the background frame color
        GLES20.glClearColor(0.0f,0.0f,0.0f,3.0f);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int i, int i1) {
        //redraw color backgroung
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        GLES20.glViewport(0, 0, 10, 10);
        triangle.draw();
    }

    public static 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;
    }
}


//triangle class
static class Triangle{
    private int mPositionHandle;
    private int mColorHandle;
    int mprogram;
    private FloatBuffer vertexBuffer;
    static final int cordinates=3;
    float triangle_coordinates[]={
            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=triangle_coordinates.length/cordinates;
    private final int vertexStride=cordinates*4;

    public void draw(){
        // Add program to OpenGL ES environment
        GLES20.glUseProgram(mprogram);

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

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

        //prepare triangle coordinates data
        GLES20.glVertexAttribPointer(mPositionHandle,cordinates,GLES20.GL_FLOAT,false,vertexStride,vertexBuffer);

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

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

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

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
    String vertexShadeColor="attribute vec4 vPosition;"+"void main(){gl_Position=vPosition;}";
    String fragmentShadeColor="precision mediump float; uniform vec4 vColor;"+"void main(){gl_FragColor=vColor;}";

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

    public Triangle(){

        int vertexShader=MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexShadeColor);
        int fragmentShader=MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShadeColor);

        // create empty OpenGL ES Program
        mprogram=GLES20.glCreateProgram();

        //add vertex shader to program
        GLES20.glAttachShader(mprogram,vertexShader);

        //add fragment shader to program
        GLES20.glAttachShader(mprogram,fragmentShader);

        // creates OpenGL ES program executables
        GLES20.glLinkProgram(mprogram);

        ByteBuffer bb=ByteBuffer.allocateDirect(triangle_coordinates.length*4);
        bb.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        vertexBuffer = bb.asFloatBuffer();

        vertexBuffer.put(triangle_coordinates);

        vertexBuffer.position(0);
    }
}
}

任何帮助都会感激不尽。

1 个答案:

答案 0 :(得分:0)

修改你的onDrawFrame方法MyGLRenderer类,你应该清除背景,你不必使用glViewport。你应该在onSurfaceCreated中初始化MyGLRenderer中的Triangle类,所以你的MyGLRenderer类看起来像这样

static class MyGLRenderer implements GLSurfaceView.Renderer{
        Triangle triangle;

        @Override
        public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
            // Set the background frame color
            GLES20.glClearColor(0.0f,0.0f,0.0f,3.0f);
            triangle=new Triangle();
        }

        @Override
        public void onSurfaceChanged(GL10 gl10, int i, int i1) {
            //redraw color backgroung
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        }

        @Override
        public void onDrawFrame(GL10 gl10) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//            GLES20.glViewport(0, 0, 10, 10);
            triangle.draw();
        }

        public static 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;
        }
    }