您的位置:首页 > 移动开发 > Android开发

Android Training - 使用OpenGL ES(3) - 绘制形状

2012-09-17 20:01 489 查看
初始化形状

在绘制前,你必须初始化和加载形状。除非形状的构造在运行中会改变,不然你应该在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()方法,运行效果如下:





上面的实例代码还有一些问题,第一,不能给别人留下深刻的印象。第二,旋转屏幕的时候,三角形被压扁了。原因是顶点坐标没有根据屏幕区域进行调整。下面章节会使用投射和摄像视图来解决这个问题。

最后,三角形的静止不动的,在下面的添加动画课程中,我们实现旋转等效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: