Android OpenGL Es 3.0 创建圆

Android OpenGL Es 3.0 Create Circle

我已经尝试实施其他帖子的建议,例如:

以及 Stack OverFlow 上的许多其他人,但 none 正在工作。

要么我打电话给

draw()

方法但没有得到输出或代码已过时并且使用起来有点毫无意义。

我正在尝试创建一个基本圆。我可以完美地创建三角形和正方形,但是我不知道如何正确地创建一个圆。

根据我目前的知识,只需添加更多顶点即可创建一个圆,如下图所示。但是我不知道如何实现这个。

这是我当前的 SurfaceView 渲染器:

public class MyGLRenderer implements GLSurfaceView.Renderer {
//Project Matrix
private float mMatrix[] = new float[16];
private Circle mCircle;
private Triangle mTriangle;

// Called once to set up the view's opengl es environment
public void onSurfaceCreated(GL10 unused, EGLConfig config){

    //Set the background frame color
    GLES30.glClearColor(1.0f,1.0f,1.0f,1.0f);

    mTriangle = new Triangle();
    mCircle = new Circle();
}

// Called for each redraw of the view
public void onDrawFrame(GL10 gl){
    //gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    //Redraw background color
    //GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);


    //mTriangle.draw();

   Matrix.orthoM(mMatrix, 0, -1, 1, -1, 1, -1, 1);
   mCircle.draw(mMatrix);
}

// Called if the geometry of the view changes (example is when the screen orientation changes from landscape to portrait
public void onSurfaceChanged(GL10 unused, int width, int height){
    // Called if the geometry of the viewport changes
    GLES30.glViewport(0, 0, width, height);
}

public static int loadShader(int type, String shaderCode){

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

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

    return shader;
}

}

我的SurfaceView如下:

public class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

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

        //Create an OpenGl 3.0 context
        setEGLContextClientVersion(3);

        mRenderer = new MyGLRenderer();

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

        //Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }

我目前的Circle实现如下:

 public class Circle {

    private  int mProgram, mPositionHandle, mColorHandle, mMVPMatrixHandle ;
    private FloatBuffer mVertexBuffer;
    private float vertices[] = new float[364 * 3];
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

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

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

    Circle(){
        vertices[0] = 0;
        vertices[1] = 0;
        vertices[2] = 0;

        for(int i =1; i <364; i++){
            vertices[(i * 3)+ 0] = (float) (0.1 * Math.cos((3.14/180) * (float)i ));
            vertices[(i * 3)+ 1] = (float) (0.2 * Math.sin((3.14/180) * (float)i ));
            vertices[(i * 3)+ 2] = 0;
        }


        Log.v("Thread", "" + vertices[0] + "," + vertices[1] + "," + vertices[2]);
        ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
        vertexByteBuffer.order(ByteOrder.nativeOrder());
        mVertexBuffer = vertexByteBuffer.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);
        int vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragmentShaderCode);

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

    }

    public static int loadShader(int type, String shaderCode){

        int shader = GLES30.glCreateShader(type);
        GLES30.glShaderSource(shader, shaderCode);
        GLES30.glCompileShader(shader);
        return shader;
    }


    public void draw (float[] mvpMatrix){

        GLES30.glUseProgram(mProgram);

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

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

        // Prepare the triangle coordinate data
        GLES30.glVertexAttribPointer(mPositionHandle, 3,
                GLES30.GL_FLOAT, false,12
                ,mVertexBuffer);

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



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

        mMVPMatrixHandle = GLES30.glGetUniformLocation(mProgram, "uMVPMatrix");

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



        // Draw the triangle
        GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN, 0, 364);

        // Disable vertex array
        GLES30.glDisableVertexAttribArray(mPositionHandle);

    }

}
  1. 使用来自 的答案。
  2. 将 GLES20 替换为 GLES30
  3. 在渲染器中声明投影矩阵为

    private float mMatrix[] = new float[16];

  4. 初始矩阵为

    Matrix.orthoM(mMatrix, 0, -1, 1, -1, 1, -1, 1);

  5. 画圆

    mCircle.draw(m矩阵);