Android OpenGL ES绘图教程之三 : 绘制图形

在定义了将要被OpenGL绘制的形状之后,你当然想要绘制它们。使用OpenGL ES 2.0绘制图形需要的代码可能比你想象的要多,因为API提供了大量的图形渲染管道控制接口。

这一章将介绍如何使用OpenGL ES 2.0 API绘制上一章中定义的形状

1. 初始化形状

在你做任何的绘制操作之前,你都必须进行初始化和加载计划绘制的形状。除非在执行的过程中形状所在的结构(原坐标)发生变化,你应该在render中的onSurfaceCreated()方法中初始化它们以提高内存和执行效率。

public void onSurfaceCreated(GL10 unused, EGLConfig config) {

...

// initialize a triangle

mTriangle = new Triangle();

// initialize a square

mSquare = new Square();

}

2. 绘制形状

使用OpenGL ES 2.0绘制定义的形状需要大量的代码,因为你必须给图形渲染管线提供许多细节,特别是,你需要定义下面的细节:

Vertex Shader - OpenGL ES graphics code for rendering the vertices of a shape.

译:顶点着色器 - 渲染形状顶点的OpenGL ES图形代码

Fragment Shader - OpenGL ES code for rendering the face of a shape with colors or textures.

译:片元着色器 - 使用颜色或者纹理渲染形状表面的OpenGL ES图形代码

Program - An OpenGL ES object that contains the shaders you want to use for drawing one or more shapes.

译:Program - 包含了用来绘制形状的着色器的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;" +

"}";

着色器使用了OpenGL着色语言(GLSL)代码,在OpenGL ES环境中使用之前必须被编译,为了编译这些代码,在你的renderer类中创建一个方法:

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;

}

为了绘制图形,你必须编译着色器代码,将它们添加到OpenGL ES编程对象中,链接程序,在绘制对象的构造方法中执行这些操作,所以只会执行一次。

注意:编译OpenGL着色器和链接程序从CPU处理周期和时间来看消耗是比较昂贵的,所以你应该避免执行超过一次。如果你在运行时还不知道着色器的内容,你应该只在着色器被创建的时候编译一次,然后缓存起来使用。

public class 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

}

这个时候,你已经准备好执行实际的绘图命令了,使用OpenGL ES绘图需要指定一些参数来告诉渲染管线画什么和怎么画。因为绘图选项可以通过形状区分,所以让你的shape类包含绘制逻辑是个不错的方法。

创建draw()方法来进行绘制,下面的代码设置了顶点着色器和片元着色器的position和color值,然后执行绘制方法。

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方法。下面是程序的执行效果:

这个代码示例还有一些问题。首先它不会让你的朋友印象深刻,其次当屏幕方向改变的时候形状会改变,有点被压扁。形状被扭曲的原因是对象的顶点没有跟着屏幕上GLSurfaceView展示的区域的比例进行修正,你可以使用下一节介绍的projection and camera view来修复这个问题。

最后,这个三角形是固定的,有点枯燥。在后面的课程中,你可以学习使这个形状旋转,使OpenGL ES图形管线更加有趣。

时间: 2024-10-29 19:12:24

Android OpenGL ES绘图教程之三 : 绘制图形的相关文章

Android OpenGL ES绘图教程之一 : 构建OpenGL ES 环境

为了在Android应用中使用OpenGL ES绘图,首先必须要创建一个view容器.一个最简单的方法是实现GLSurfaceView和GLSurfaceView.Renderer.GLSurfaceView一个view容器,用来显示OpenGL绘制的图形,GLSurfaceView.Renderer用来控制GLSurfaceView里面图形的绘制.更多的信息,请参考 OpenGL ES 开发向导. GLSurfaceView是将OpenGL ES图形用到应用的一种方式,对于全屏或者接近全屏的图

Android OpenGL ES绘图教程之六 :响应触摸事件

使对象根据预设的程序进行运动,比如旋转三角形,可以吸引人的注意力.但是如果你想让用户同你的OpenGL ES图形进行交互会怎么样呢?使你的OpenGL ES应用程序触摸互动的关键是要扩展GLSurfaceView,复写onTouchEvent()方法,来监听touch事件.本教程展示了,如何监听透出事件,让用户旋转一个OpenGL ES对象. 1.   设置一个Touch Listener 为了使你的OpenGL ES应用响应touch事件,你必须在GLSurfaceView类中实现OnTouc

Android OpenGL ES绘图教程之二 : 定义形状

在OpenGL ES view中可以定义要绘制图形的形状,是你创建高端图形杰作的第一步.在不知道一些基础的情况下来绘制会有点棘手,比如OpenGL ES是如何定义图形对象的. 本教程解释了OpenGL ES坐标系统与Android设备屏幕的关系,如果定义基础的形状,比如三角形和四边形. 1. 定义一个三角形 OpenGL ES允许你在三维坐标系统中定义绘制对象,所以在绘制三角形之前,必须定义它的坐标.在OpenGL里面,定义坐标的典型方式是定义一个浮点型的顶点坐标数组,为了最大化效率,将这些坐标

Android OpenGL ES 开发教程 从入门到精通

From:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ES 简明开发教程一:概述 Android OpenGL ES 简明开发教程二:构造OpenGL ES View Android OpenGL ES 简明开发教程三:3D绘图基本概念 Android OpenGL ES 简明开发教程四:3D 坐标变换 Android OpenGL ES 简明开发教程五

[转]Android OpenGL ES 开发教程 从入门到精通

本文转自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ES 简明开发教程一:概述 Android OpenGL ES 简明开发教程二:构造OpenGL ES View Android OpenGL ES 简明开发教程三:3D绘图基本概念 Android OpenGL ES 简明开发教程四:3D 坐标变换 Android OpenGL ES 简明开发教程五

Android OpenGL ES(八)绘制点Point ..

上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐标变换后,再介绍真正的3D图形绘制方法. 在Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 创建了示例应用的程序框架,并提供了一个“Hello World”示例. 为避免一些重复代码,这里定义一个所有示例代码的基类OpenGLESActivity,其定义如下:

Android OpenGL ES(十)绘制三角形Triangle .

三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, -0.4f * 1.732f, 0.0f, 0.0f, -0.4f * 1.732f, 0.0f, -0.4f, 0.4f * 1.732f, 0.0f, 0.0f, -0.0f * 1.732f, 0.0f, 0.8f, -0.0f * 1.732f, 0.0f, 0.4f, 0.4f * 1.73

Android OpenGL ES(九)绘制线段Line Segment .

创建一个DrawLine Activity,定义四个顶点: float vertexArray[] = { -0.8f, -0.4f * 1.732f, 0.0f, -0.4f, 0.4f * 1.732f, 0.0f, 0.0f, -0.4f * 1.732f, 0.0f, 0.4f, 0.4f * 1.732f, 0.0f, }; 分别以三种模式GL_LINES,GL_LINE_STRIP,GL_LINE_LOOP 来绘制直线: public void DrawScene(GL10 gl)

Android OpenGL ES零基础系列(三):OpenGL ES的渲染管道及VertexShader与FragmentShader

前言 在前2篇文章中,我们都说到着色器,且在第二篇中正式说到,这着色器只能用在OpenGL ES2.x等可编程管道里面,而在OpenGL ES1.x是不能用的.但我们一直没有说这是为什么,两者有什么区别.那这篇我们就一起来学习下OpenGL ES中的渲染管道. 正文 管道,英文名叫Pipeline,相信用过FaceBook图片加载库的同学对这个管道并不陌生,因为SimpleImageDrawee里面也是用的管道来对图片进行的一个处理.由于其底层也是C,因此我可以大胆的猜想,FaceBook图片加