Displaying Graphics with OpenGL ES(三)——Drawing Shapes
来源:互联网 发布:嵌入式linux启动 编辑:程序博客网 时间:2024/09/21 06:32
Drawing Shapes
在用OpenGl定义shapes后,就要画出他们了。画出形状需要大量的代码,因为API提供了强大的图形渲染通道。
1.初始化 Shapes
在你画之前,必须初始化和加载shape。除非执行程序期间改变shapes的构造( 原始坐标),你应该初始化他们在onSurfaceCreate()方法里为了渲染消耗内存和执行效率。
public class MyGLRenderer implements GLSurfaceView.Renderer { ... private Triangle mTriangle; private Square mSquare; public void onSurfaceCreated(GL10 unused, EGLConfig config) { ... // initialize a triangle mTriangle = new Triangle(); // initialize a square mSquare = new Square(); } ...}
2.Draw a Shape
通过绘制OpenGL ES 2.0的定义shape需要的代码量较大,因为你必须提供很多细节的图形渲染通道。具体而言,您必须定义如下:
~Vertex Shader:为渲染图形顶点的OpenGL ES图形代码。
~Fragment Shader:渲染shape正面的颜色和纹理的OpenGL ES 代码。
~Program:一个OpenGL ES对象,其中包含要用于绘制一个或多个shapes的着色器。
至少需要一个vertex shader 和 一个fragment shader。这些shaders必须被编译和添加到OpenGL ES program。下面是一个最基本的三角形shaders,你可以在Triangle.class里定义:
public class Triangle { 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;" + "}"; ...}
包含着色器,必须先在OpenGL ES的环境中使用该编译OpenGL着色语言(GLSL)代码。编译这段代码,在你的渲染器类创建一个实用方法:
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;}
为了绘制shape,您必须编译shader代码,将其添加到OpenGL ES的程序对象,然后链接程序。这是绘制的对象的构造函数,所以只进行一次。
Note: 编译的OpenGL ES着色器和链接程序在CPU周期和处理时间方面的代价较大,所以你应该避免做更多的操作在这里。如果你不知道你的着色器在运行时的内容,你应该建立你的代码,他们只获得创建一次,然后缓存以备后用。
public class Triangle() { ... private final int mProgram; public Triangle() { ... int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); // create empty OpenGL ES Program mProgram = GLES20.glCreateProgram(); // add the vertex shader to program GLES20.glAttachShader(mProgram, vertexShader); // add the fragment shader to program GLES20.glAttachShader(mProgram, fragmentShader); // creates OpenGL ES program executables GLES20.glLinkProgram(mProgram); }}
下面,你就可以添加绘制shape的实际调用。绘制形状与OpenGL ES需要您指定几个参数来告诉画什么渲染通道以及如何绘制它。由于绘图选项可以通过形状有所不同,所以在你的形状类包含自己的绘画逻辑是个好想法。
创建绘制形状的draw()方法。此代码设置形状的顶点着色器颜色值和fragment着色器的位置,然后执行绘图功能。
private int mPositionHandle;private int mColorHandle;private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertexpublic 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);}
一但你有了所有到位的代码,绘制这个对象只需要调用draw()方法从渲染的onDrawFrame()方法里:
public void onDrawFrame(GL10 unused) { ... mTriangle.draw();}
然后运行程序,可以看到:
Figure 1. Triangle绘制没有用到Projection或Camera View。
此代码示例的一些问题。首先,它不会打动你的朋友。其次,三角形是有点压扁,并改变形状,当您更改设备的屏幕方向。形状歪斜的原因是由于对象的顶点未针对其中显示GLSurfaceView屏幕区域的比例校正。可以使用在下一章的投影和相机视图解决这个问题。
最后,三角形是固定的,这是一个有点无聊。在Add Motion 章节里,可以使这种形状旋转,做更多有趣的使用的OpenGL ES图形通道。
- Displaying Graphics with OpenGL ES(三)——Drawing Shapes
- Displaying Graphics with OpenGL ES(二)——定义形状Defining Shapes
- Displaying Graphics with OpenGL ES(一)——构建一个OpenGL ES环境
- Displaying Graphics with OpenGL ES(四)——Applying Projection and Camera Views
- Displaying Graphics with OpenGL ES (五)——Add Motion
- Displaying Graphics with OpenGL ES (六)——Responding to Touch Events
- android-Displaying Graphics with OpenGL ES
- Building Apps with Graphics 之 Animation Displaying Graphics with OpenGL ES
- Week 13: Displaying Data With OpenGL ES 2.0
- Mobile 3D Graphics: with OpenGL ES and M3G
- android.graphics(一)shapes
- Android API Guide for Animation and Graphics(六)—— 动画与图形(OpenGL ES)
- OpenGL ES 光照(三)
- OpenGL ES for iPhone: Drawing a Circle
- Android OpenGL ES(三):OpenGL ES API 命名习惯
- Drawing Shapes 绘制形状
- 8-5 用OpenGL绘图(Graphics with OpenGL)
- UIKit Graphics System--Drawing Shapes Using Bezier Paths学习笔记2
- copy与mutableCopy
- 记录下而已
- OpenCV3.0或OpenCV3.1的SVM操作
- OC_实现UITableviewCell之间的间距
- oracle 恢复到之前某个时间点
- Displaying Graphics with OpenGL ES(三)——Drawing Shapes
- jquery中mouseover和mouseout以及mouseenter和mouseleave的区别
- Java--计算中英文长度的若干种方法
- Google Guava之--cache
- 求两个数组中都出现的元素
- IOS研究之iOS7适配的使用详细说明
- 如何实现云时代的高效运维?
- archlinux安装笔记
- 微信开放平台开发(3) 移动应用微信登录