第二章 你好三角形:一个OpenGL ES 2.0例子

介绍基本概念的OpenGL ES 2.0,我们首先从一个简单的例子。在这一章里,我们将展示什么是需要创建一个OpenGL ES 2.0一个三角形的项目、。我们要编写的程序是最基本的例子,一个OpenGL ES 2.0应用程序,绘制几何。有数量的概念,我们将介绍在本章:

1.创建一个屏幕渲染表面与EGL。

2.加载片段着色器和定点。

3.创建程序的对象,附着顶点和片段着色器,连接程序对象。

4.设置窗口。

5.清除颜色缓冲。

6.渲染一个简单的例子。

7.使内容的颜色缓冲可见在EGL窗口表面。

事实证明,我们可以开始画一个三角形之前,有相当数量的步骤需要做。这个章节将涵盖的每一个步骤。在您的书中,我们补充了每个步骤的细节和进一步的文档API。我们的目的是让你运行你的第一个简单的例子,让您了解如何创建一个应用程序与OpenGL ES 2.0。

Code Framework    代码框架

在本书中,我们将构建一个图书馆的实用工具函数,形成一个框架有用的功能,以编写OpenGL ES 2.0 程序。为了发展示例程序,我们有几个目标,这段代码框架:

1。它是简单的,小的,容易理解。我们希望把我们的例子在相关的OpenGL ES 2.0调用,而不是在一个大型的我们所方明的代码框架。相反,我们尽力事我们的示例程序易于读和理解。这个框架的目的是为了让你集中精力在每个示例的重要的OpenGL ES 2.0 API概念。

2。它可以移植。尽管我们开发我们的示例程序在使用微软的Windows操作系统,我们想要的样本程序容易地移植到其他操作系统和环境。此外,我们选择使用C语言而不是c++,由于不同的c++的局限在许多手持平台。我们也避免使用全局数据,由于他它不允许在许多手持平台使用。

当我们阅读本书的例子,我们引用一些新的代码框架函数。此外,你可以在附录d找到完整的代码文档。你看到的示例代码中任何函数,任何以es开头的函数是我们写的代码框架的一部分。

Where to Download the Examples    哪里下载例子

您可以下载示例从这本书网站在www.opengles-book.com。

这个例子都是针对运行在微软Windows XP或Vista MicrosoftWindows与桌面图形处理单元(GPU)支持OpenGL 2.0。示例程序以源代码的形式提供、 Visual Studio 2005项目的解决方案。这个例子构建和运行在AMD的OpenGL ES 2.0模拟器。一些高级在这本书的渲染例子是用RenderMonkey实现,一个材质developmenttool从AMD。这本书网站提供链接在何处downloadany所需的工具。OpenGL ES 2.0的模拟器和RenderMonkeyare都免费提供的工具。读者没有自己的Visual Studio,可以免费获得微软Visual Studio 2008 Express Edition,在 www.microsoft.com/express/ for download。


Hello Triangle Example    你好三角形例子

让我们看看我们的完整源代码示例项目-你好三角形,这是2 - 1中列出的例子。对于那些熟悉固定功能的桌面版本OpenGL的读者,你可能会认为这是一个一堆代码只是为了画一个简单的三角形。对于那些不熟悉的桌面OpenGL的人,你可能也会认为这是一个很多代码只是为了画一个三角形!记住,OpenGL ES 2.0是完全基于着色器的,这意味着你在没有适当的着色加载和边框的情况下,你不能画任何图形。这意味着相比较桌面版的openGL使用固定的函数处理,你需要使用更多的需要渲染的代码。

Example 2-1Hello Triangle Example    


#include "esUtil.h"
typedef struct
{
// Handle to a program object GLuint programObject;
} UserData;
///
// Create a shader object, load the shader source, and // compile the shader.
//
GLuint LoadShader(const char *shaderSrc, GLenum type) {
GLuint shader; GLint compiled;
// Create the shader object shader = glCreateShader(type);
   if(shader == 0)
      return 0;
// Load the shader source glShaderSource(shader, 1, &shaderSrc, NULL);
// Compile the shader glCompileShader(shader);
// Check the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

if(!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
      if(infoLen > 1)
      {
char* infoLog = malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog); esLogMessage("Error compiling shader:\n%s\n", infoLog); free(infoLog);
}
glDeleteShader(shader);
return 0; }
return shader; }
///
// Initialize the shader and program object //
int Init(ESContext *esContext)
{
UserData *userData = esContext->userData; GLbyte vShaderStr[] =
"attribute vec4 vPosition; "void main()
"{
" gl_Position = vPosition; "}
\n"
\n"
\n"
\n"
\n";
GLbyte fShaderStr[] =
"precision mediump float;
"void main()
"{
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" "} \n";
GLuint vertexShader; GLuint fragmentShader; GLuint programObject; GLint linked;
// Load the vertex/fragment shaders
vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
// Create the program object programObject = glCreateProgram();
if(programObject == 0) return 0;
glAttachShader(programObject, vertexShader); glAttachShader(programObject, fragmentShader);
// Bind vPosition to attribute 0 glBindAttribLocation(programObject, 0, "vPosition");
// Link the program glLinkProgram(programObject);
// Check the link status
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
   if(!linked)
   {
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
      if(infoLen > 1)
      {
char* infoLog = malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); esLogMessage("Error linking program:\n%s\n", infoLog);
free(infoLog); }
glDeleteProgram(programObject);
      return FALSE;
   }
// Store the program object userData->programObject = programObject;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   return TRUE;
}
//
// Draw a triangle using the shader pair created in Init() //
void Draw(ESContext *esContext)
{
UserData *userData = esContext->userData; GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f};
// Set the viewport
glViewport(0, 0, esContext->width, esContext->height);
// Clear the color buffer glClear(GL_COLOR_BUFFER_BIT);
// Use the program object glUseProgram(userData->programObject);
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface); }
int main(int argc, char *argv[]) {
ESContext esContext; UserData userData;
esInitialize(&esContext); esContext.userData = &userData;
esCreateWindow(&esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB);
if(!Init(&esContext)) return 0;
esRegisterDrawFunc(&esContext, Draw);
esMainLoop(&esContext); }

Building and Running the Examples    编译和运行例子

在这本书中所有的示例程序开发全部都在AMD’sOpenGL ES 2.0模拟器的上层运行。这个模拟器提供了一个运行EGL 1.3和OpenGL ES 2.0 api的窗口。标准GL2和EGL的头文件是被Khronos提供的,它曾经被作为模拟器的接口  。模拟器是一个完全可以运行OpenGL ES 2.0,这意味着在模拟器上编写的绘图代码可以无缝地在真机上运行。注意,模拟器要求您拥有一个支持桌面OpenGL 2.0 API的桌面GPU。

我们设计的代码框架,可以移植到多种平台。但是,为了这本书的所有示例都使用微软Visual Studio 2005。OpenGL ES 2.0的例子——都在以下的文件夹里:

Common/—包括 OpenGL ES 2.0框架项目,代码.

Chapter_X/—包括每章的代码。 每一章VisualStudio 2005 的启动项.

为了运行你好三角形的例子。请打开Chapter_2/Hello_Triangle/Hello_Triangle.sln in Visual Studio 2005这个文件。这个程序可以直接用 Visual Studio 2005执行。运行起来你可以看到如表格2-1的这张图片。

请注意下另外提供的简单代码。本书后面提供的很多例子用的是AMD的免费着色开发工具RenderMonkey1.80v.RenderMonkey使用在我们应该仅仅注意着色器代码的例子种。RenderMonkey对于开发着色效果提供了一个非常灵活的继承开发环境。所有后缀是.rfx的例子可以用 RenderMonkey v1.80进行开发。 RenderMonkey v1.80IDE 使用的效果截图在Color Plate 2种可以看见。

Using the OpenGL ES 2.0 Framework     用openGLES 2.0框架

在你好三角形的主函数里面,你可以看见很多的调用ESutility的函数。主函数的第一件事情是声明一个 ESContext并且初始化它

ESContext esContext;UserData userData;

esInitialize(&esContext);esContext.userData = &userData; 

这本书里的每一个例子都在做同样的事情。ESContextis包含了ES框架所需要的所有程序的必要信息,并且ES框架工具函数都会传递给它。因为是一个简单的程序,所以所有的传递都围绕这context,ES框架不需要全局变量。

许多的掌上设备平台不允许程序声明全局静态变量。例如BREW和塞班。正因如此我们避免在例子种或者在框架种在两个函数传递context的时候,代码中声明全局变量。


ESContext有一个空指针类的成员变量userData。每个程序例子将会在user data中存储应用所需要的数据。

The ESContext has a member variable named userData that is a void*.Each of the sample programs will store any of the data that are needed forthe application in userData. The esInitialize function is called by thesample program to initialize the context and the ES code framework. Theother elements in the ESContext structure are described in the header fileand are intended only to be read by the user application. Other data in theESContext structure include information such as the window width andheight, EGL context, and callback function pointers. 



你可能感兴趣的:(第二章 你好三角形:一个OpenGL ES 2.0例子)