<style type="text/css"><!--
@page { margin: 0.79in }
PRE.western { font-family: "Courier New", monospace }
PRE.cjk { font-family: "新宋体", monospace }
PRE.ctl { font-family: "Courier New", monospace }
H2 { margin-bottom: 0.08in }
H2.western { font-family: "Times New Roman", serif }
H2.cjk { font-family: "宋体" }
H2.ctl { font-family: "Mangal" }
H1 { margin-bottom: 0.08in }
H1.western { font-family: "Times New Roman", serif }
H1.cjk { font-family: "宋体" }
H1.ctl { font-family: "Mangal" }
P { margin-bottom: 0.08in }
STRONG { font-style: italic; font-weight: normal }
A:link { so-language: zxx }
CODE.western { font-family: "Courier New", monospace }
CODE.cjk { font-family: "新宋体", monospace }
CODE.ctl { font-family: "Courier New", monospace }
--></style>
绘制形状
你定义了要绘制的形状后,你就要画它们了。使用OpenGLES 2.0会形状会有一点点复杂,因为API提供了大量的对渲染管线的控制能力。
本文讲解如何绘制你在前文中定义的那些形状们。
初始化形状
在你做任何绘制之前,你必须初始化形状然后加载它。除非形状的结构(指原始的坐标们)在执行过程中发生改变,你都应该在你的Renderer的方法onSurfaceCreated()
中进行内存和效率方面的初始化工作。
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
...
// 初始化一个三角形
mTriangle = new Triangle();
// 初始化一个正方形
mSquare = new Square();
}
绘制一个形状
使用OpenGLES 2.0画一个定义好的形状需要一大坨代码,因为你必须为图形渲染管线提供一大堆信息。典型的,你必须定义以下几个东西:
VertexShader-用于渲染形状的顶点的OpenGLES 图形代码。
FragmentShader-用于渲染形状的外观(颜色或纹理)的OpenGLES 代码。
Program-一个OpenGLES对象,包含了你想要用来绘制一个或多个形状的shader。
你至少需要一个vertexshader来绘制一个形状和一个fragmentshader来为形状上色。这些形状必须被编译然后被添加到一个OpenGLES program中,program之后被用来绘制形状。下面是一个展示如何定义一个可以用来绘制形状的基本shader的例子:
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;" +
"}";
Shader们包含了OpenGLShading Language (GLSL)代码,必须在使用前编译。要编译这些代码,在你的Renderer类中创建一个工具类方法:
public static int loadShader(int type, String shaderCode){
// 创建一个vertex shader类型(GLES20.GL_VERTEX_SHADER)
// 或fragment shader类型(GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// 将源码添加到shader并编译之
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
为了绘制你的形状,你必须编译shader代码,添加它们到一个OpenGLES program 对象然后链接这个program。在renderer对象的构造器中做这些事情,从而只需做一次即可。
注:编译OpenGLES shader们和链接linkingprogram们是很耗CPU的,所以你应该避免多次做这些事。如果在运行时你不知道shader的内容,你应该只创建一次code然后缓存它们以避免多次创建。
public Triangle() {
...
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // 创建一个空的OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // 将vertex shader添加到program
GLES20.glAttachShader(mProgram, fragmentShader); // 将fragment shader添加到program
GLES20.glLinkProgram(mProgram); // 创建可执行的 OpenGL ES program
}
此时,你已经准备好增加真正的绘制调用了。需要为渲染管线指定很多参数来告诉它你想画什么以及如何画。因为绘制操作因形状而异,让你的形状类包含自己的绘制逻辑是个很好主意。
创建一个draw()
方法负责绘制形状。下面的代码设置位置和颜色值到形状的vertexshader和fragmentshader,然后执行绘制功能。
public void draw() {
// 将program加入OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// 获取指向vertex shader的成员vPosition的 handle
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// 启用一个指向三角形的顶点数组的handle
GLES20.glEnableVertexAttribArray(mPositionHandle);
// 准备三角形的坐标数据
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// 获取指向fragment shader的成员vColor的handle
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// 设置三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// 画三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// 禁用指向三角形的顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
一旦你完成这些代码,画这个对象只需要在Renderer的onDrawFrame()
调用draw()
方法。当你运行应用时,它应该看起来这样:
图1.没有投射和视口时画三角形
此例子中的代码还有很多问题。首先,它不会给人留下印像。其次,三角形会在你从竖屏变为横屏时被压扁。三角形变形的原因是其顶点们没有跟据屏幕的宽高比进行修正。你可以使用投射和视口更正这个问题。那在下一讲了。
上一讲
下一讲
分享到:
相关推荐
OpenGL ES 2.0编程的入门基础书籍。适合初学者。
《OpenGL ES 《OpenGL ES 2.0 编程指南 中文版》2.0 编程指南 中文版》
作者: (美) 马鲁基-弗伊诺(Marucchi-Foino, R.) 著 ...原作名: Game and Graphics Programming for iOS and Android with OpenGL ES 2.0 译者: 王净 译. 出版年: 2014-2 页数: 288 装帧: 平装 ISBN: 9787302352303
OpenGL ES 2.0应用开发实践指南-Android卷。非常实用的OpenGL ES Android游戏开发指南。
源码非常齐全,Android、iOS、BlackBerry、LinuxX11,Windows,WebGL全平台同步代码
OpenGLES2.0游戏与图形编程适用于iOS 和Android [(美)RomainMarucchi-Foino 著] 2014年版例子源码。
移动终端-游戏程序-程序设计 Ⅳ. ①TN929.53 ②TP311.5
OpenGL ES 2.0编程指南,是官方正式文档。详细讲述了OpenGL ES 2.0版本中所有API的细节和使用描述,另外还有一些简单的sample.
介绍OpenGL 在iOS Android 上 游戏和图形编程.
华章 OpenGL ES 3.0编程指南(原书第2版)由资深OpenGL技术专家亲笔撰写,全面介绍OpenGL ES 3.0的各种特性及新增功能,通过大量已经编译和测试过的实例,详细讲解OpenGL ES 3.0中的应用程序接口(API)和图形管线,...
教程名称:OpenGL ES经典教程大全课程目录:【】Android应用OpenGLES制作3D图像【技术文档】【】OpenGL ES 2.0 官方手册【】OpenGL ES 2.0 编程指南【】OpenGL ES 2.0【】OpenGL ES【】OpenGL ES教程以及COCOS 2D...
本资源包含有OpenGL ES 2.0 编程指南、OpenGL_ES基础入门、Beginning Android Games.2011等文档,适合学习OPENGL ES开发,希望对大家有用
ES2.x针对可编程管线硬件.OpenGL ES1.0是以OpenGL1.3规范为基础的,OpenGL ES1.1是以OpenGL1.5为基础 的,他们分别又支持common和common lite两种profile.OpenGL ES2.0是参照OpenGL2.0规范定义的”
OpenGL(全写Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。它用于三维图像(二维的亦可),是一个功能强大,调用方便的底层图形库。 OpenGL在不同的平台上有不同...
OpenGL ES的中文翻译版本 OpenGL ES 2.0 编程向导 Aaftab Munshi Dan Ginsburg Dave Shrener
普利亚框架(教育项目) 通过Wirune Kaewjai ========信息======== 项目名称: Android平台的赛车游戏框架(原始名称为Plia-Framework) 部门:数字媒体和游戏系统工程(Dhurakij Pundit大学) 学年: 2012 项目顾问...
第1部分: 您可以选择使用 OpenGL ES 2.0 或 3.0 构建全屏 OpenGL ES 视图。 为了节省时间,您可以使用像 Apple 的 GLKView 这样的平台级便利来构建视图,但如果您直接使用 OpenGL ES API 调用自己构建它,您将获得...
OpenGL ES 2.0 则是参照 OpenGL 2.0 规范定义的,common profile发布于2005-8,引入了对可编程管线的支持。 在解析Android ApiDemos 中OpenGL ES示例前,有必要对OpenGL ES 开发单独做个简明开发教程,可以帮助...