Hello Triangle:OpenGL ES 2.0 版的“Hello world”

Hello Triangle:OpenGL ES 2.0 版的“Hello world”

本文的文字大部分都是从《OpenGL ES 2.0 编程向导》中摘抄而来,特此说明。

该文是基于OpengGL ES 2.0的,算是本人学习OpenGL的“Hello world”吧。

一个OpengGL ES 2.0程序的实现大致如下所示:

准备工作

作为一个“Hello world”类的程序,功能就是在手机上绘制一个三角形。因而代码就会比较简陋,预先准备的食材也就比较简单,就是下面这五个文件(连布局文件都省了):

AndroidManifest.xml

=”0x00020000″ android:required=”true” />

MainActivity.java

{private TriangleGLSurfaceView mTriangleGLSurfaceView;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mTriangleGLSurfaceView = new TriangleGLSurfaceView(getApplication());setContentView(mTriangleGLSurfaceView);}}

TriangleGLSurfaceView.java

{public TriangleGLSurfaceView(Context context) {super(context);setEGLContextClientVersion(2);setRenderer(new TriangleRender());}}

TriangleRender.java

{private Triangle mTriangle;(GL10 gl, EGLConfig config) {GLES20.glClearColor(0, 0, 0, 1);mTriangle = new Triangle();}(GL10 gl, int width, int height) {GLES20.glViewport(0, 0, width, height);}(GL10 gl) {// Clear the color bufferGLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);mTriangle.draw();}}

Triangle.java

public class Triangle {…省略大段文字,会在下面补充啦…}具体实现

下面这些操作大都在Triangle.java这个类里面实现的。

创建一个简单的顶点和片段着色器

OpenGL ES 2.0 中,在有效的顶点和片段着色器被装载前,什么渲染都做不了。定义定点着色器:

String VERTEX_SHADER =”attribute vec4 vPosition;\n” +”void main()\n” +”{\n” +” gl_Position = vPosition;\n” +”}”;

顶点着色器定义一个输入attribute,它是4 个成员的矢量vPosition。后面的draw函数将为每个顶点设置位置变量值。main函数声明着色器宣布着色器开始执行。着色器主体非常简单,它复制输入vPosition 属性到gl_Position 输出变量中,每个顶点着色器必须输出位置值到gl_Position变量中,这个变量传入到管线的下一个阶段中。

顶点着色器如下:

String FRAGMENT_SHADER =”precision mediump float;\n” +”void main()\n” +”{\n” +” gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n” +”}”;

第一行宣布着色器默认的浮点变量精度。main 函数上,它的输出值(1.0, 0.0, 0.0, 1.0)赋给变量gl_FragColor,gl_FragColor是片段着色器最终的输出值,本例中输出值是红色。

典型的一个游戏或应用将不会内联一个着色器源码串,大多数的实际应用着色器应该填充文字或数据,然后被API 装载,我们为简化起见,在程序源码上直接赋值。

编译和装载着色器

定义了着色器源码后,我们将着色器装入OpenGL ES,这由loadShader函数完成,检查没有错误后,这个函数返回着色器对象,这个对象在后面被用于连接项目对象

(int type, String shaderCode){int shader;int[] compiled = new int[1];// Create the shader objectshader = GLES20.glCreateShader(type);if (shader == 0) {return 0;}// Load the shader sourceGLES20.glShaderSource(shader, shaderCode);// Compile the shaderGLES20.glCompileShader(shader);// Check the compile statusGLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e(TAG, “Could not compile shader ” + type + “:”);Log.e(TAG, GLES20.glGetShaderInfoLog(shader));GLES20.glDeleteShader(shader);shader = 0;}return shader;}

如果着色器对象装载成功,一个新的着色器对象被返回,在后面将连接到项目对象上。

创建项目对象链接着色器

一旦应用程序已经创建了顶点、片段着色器对象,它需要去创建项目对象,项目是最终的链接对象,每个着色器在被绘制前都应该联系到项目或者项目对象。

1.创建项目对象// Create the program object.mProgram = GLES20.glCreateProgram();if (mProgram == 0) {return;}GLES20.glAttachShader(mProgram, vertexShader);GLES20.glAttachShader(mProgram, fragmentShader);2.设定顶点着色器vPosition 属性:// Bind vPosition GLES20.glBindAttribLocation(mProgram, 0, “vPosition”);

顶点属性、顶点矩阵、缓冲区对象, 讲述更多的细节现在我们看glBindAttribLocation函数绑定vPosition 属性到顶点着色器位置0,当我们指定顶点数据后,位置指针指向下一个位置。

3.链接项目检查错误:// Link the programGLES20.glLinkProgram(mProgram);// Check the link statusint[] linkStatus = new int[1];GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);if (linkStatus[0] != GLES20.GL_TRUE) {Log.e(TAG, “Could not link program: “);Log.e(TAG, GLES20.glGetProgramInfoLog(mProgram));GLES20.glDeleteProgram(mProgram);mProgram = 0;}

所有这些步骤后,编译着色器,检查错误,创建项目对象,附加上着色器,链接项目,检查链接错误。成功后可以使用项目对象去渲染。

设定窗口和清除缓冲区你曾经说,等我们老的时候,

Hello Triangle:OpenGL ES 2.0 版的“Hello world”

相关文章:

你感兴趣的文章:

标签云: