初始化形状
在绘制前,你必须初始化和加载形状。除非形状的构造在运行中会改变,不然你应该在onSurfaceCreated()方法中初始化它们。
绘制前你需要做下面这些定义:
在绘制前,你必须初始化和加载形状。除非形状的构造在运行中会改变,不然你应该在onSurfaceCreated()方法中初始化它们。
public void onSurfaceCreated(GL10 unused, EGLConfig config) { ... // initialize a triangle mTriangle = new Triangle(); // initialize a square mSquare = new Square(); }
绘制形状
绘制前你需要做下面这些定义:
- 顶点着色器 - OpenGL ES图形代码通过顶点渲染一个形状。
- 碎片着色器 - 绘制形状表面的颜色或者纹理。
- 工程 - 包含使用的着色器。
你至少需要一个顶点着色器和一个碎片着色器。它们必须被编译然后添加到一个OpenGL ES工程中:
private final String vertexShaderCode = "attribute vec4 vPosition;" + "void main() {" + " gl_Position = vPosition;" + "}"; private final String fragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}";
着色器包含GLSL代码,需要在OpenGL ES环境下编译:
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; }
一般在构造函数中完成编译和连接到工程:
public Triangle() { ... 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 }
创建一个draw()方法来绘制形状。代码设置了位置和颜色值给顶点着色器和碎片着色器使用,然后执行绘制功能:
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 the triangle coordinate data GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 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); }
完成这些后,在renderer的onDrawFrame()方法中调用draw()方法,运行效果如下:
![](https://img-my.csdn.net/uploads/201209/17/1347883533_9936.png)
上面的实例代码还有一些问题,第一,不能给别人留下深刻的印象。第二,旋转屏幕的时候,三角形被压扁了。原因是顶点坐标没有根据屏幕区域进行调整。下面章节会使用投射和摄像视图来解决这个问题。
最后,三角形的静止不动的,在下面的添加动画课程中,我们实现旋转等效果。