第二章 你好三角形:一個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開頭的函數是我們寫的代碼框架的一部分。
您可以下載示例從這本書網站在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.
最後更新:2017-04-02 00:06:48