diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.cproject b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.cproject
new file mode 100644
index 0000000..bea436c
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.cproject
@@ -0,0 +1,574 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.project b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.project
new file mode 100644
index 0000000..3a61e1d
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/.project
@@ -0,0 +1,77 @@
+
+
+ Ch10_MultiTexture
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch10_MultiTexture/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/bar-descriptor.xml
new file mode 100644
index 0000000..16f212d
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/bar-descriptor.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+ com.example.Ch10_MultiTexture
+
+
+ Ch10_MultiTexture
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch10_MultiTexture application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+ res/textures/basemap.tga
+ res/textures/lightmap.tga
+
+ armle-v7
+ Ch10_MultiTexture
+
+
+ armle-v7
+ Ch10_MultiTexture
+
+
+ armle-v7
+ Ch10_MultiTexture
+
+
+ armle-v7
+ Ch10_MultiTexture
+
+
+ x86
+ Ch10_MultiTexture
+
+
+ x86
+ Ch10_MultiTexture
+
+
+ x86
+ Ch10_MultiTexture
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/icon.png b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/basemap.tga b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/basemap.tga
new file mode 100644
index 0000000..8acafae
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/basemap.tga differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/lightmap.tga b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/lightmap.tga
new file mode 100644
index 0000000..d95b262
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/res/textures/lightmap.tga differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/src/MultiTexture.c b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/src/MultiTexture.c
new file mode 100644
index 0000000..a92f240
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch10_MultiTexture/src/MultiTexture.c
@@ -0,0 +1,212 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// MultiTexture.c
+//
+// This is an example that draws a quad with a basemap and
+// lightmap to demonstrate multitexturing.
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+ GLint texCoordLoc;
+
+ // Sampler locations
+ GLint baseMapLoc;
+ GLint lightMapLoc;
+
+ // Texture handle
+ GLuint baseMapTexId;
+ GLuint lightMapTexId;
+
+} UserData;
+
+
+///
+// Load texture from disk
+//
+GLuint LoadTexture(char *fileName)
+{
+ int width, height;
+ char *buffer = esLoadTGA(fileName, &width, &height);
+
+ GLuint texId;
+
+ if (buffer == NULL)
+ {
+ esLogMessage("Error loading (%s) image.\n", fileName);
+ return 0;
+ }
+
+ glGenTextures(1, &texId);
+ glBindTexture(GL_TEXTURE_2D, texId);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ free(buffer);
+
+ return texId;
+}
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_baseMap; \n"
+ "uniform sampler2D s_lightMap; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 baseColor; \n"
+ " vec4 lightColor; \n"
+ " \n"
+ " baseColor = texture2D( s_baseMap, v_texCoord ); \n"
+ " lightColor = texture2D( s_lightMap, v_texCoord ); \n"
+ " gl_FragColor = baseColor * (lightColor + 0.25); \n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+ userData->texCoordLoc = glGetAttribLocation(userData->programObject, "a_texCoord");
+
+ // Get the sampler location
+ userData->baseMapLoc = glGetUniformLocation(userData->programObject, "s_baseMap");
+ userData->lightMapLoc = glGetUniformLocation(userData->programObject, "s_lightMap");
+
+ // Load the textures
+ userData->baseMapTexId = LoadTexture("res/textures/basemap.tga");
+ userData->lightMapTexId = LoadTexture("res/textures/lightmap.tga");
+
+ if (userData->baseMapTexId == 0 || userData->lightMapTexId == 0)
+ return FALSE;
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLfloat vVertices[] = {
+ -0.5f, 0.5f, 0.0f, // Position 0
+ 0.0f, 0.0f, // TexCoord 0
+ -0.5f, -0.5f, 0.0f, // Position 1
+ 0.0f, 1.0f, // TexCoord 1
+ 0.5f, -0.5f, 0.0f, // Position 2
+ 1.0f, 1.0f, // TexCoord 2
+ 0.5f, 0.5f, 0.0f, // Position 3
+ 1.0f, 0.0f // TexCoord 3
+ };
+ GLushort indices[] =
+ { 0, 1, 2, 0, 2, 3 };
+
+ // 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 position
+ glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
+ // Load the texture coordinate
+ glVertexAttribPointer(userData->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+ glEnableVertexAttribArray(userData->texCoordLoc);
+
+ // Bind the base map
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, userData->baseMapTexId);
+
+ // Set the base map sampler to texture unit to 0
+ glUniform1i(userData->baseMapLoc, 0);
+
+ // Bind the light map
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, userData->lightMapTexId);
+
+ // Set the light map sampler to texture unit 1
+ glUniform1i(userData->lightMapLoc, 1);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures(1, &userData->baseMapTexId);
+ glDeleteTextures(1, &userData->lightMapTexId);
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "MultiTexture", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.cproject b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.cproject
new file mode 100644
index 0000000..4646515
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.project b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.project
new file mode 100644
index 0000000..9910411
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/.project
@@ -0,0 +1,77 @@
+
+
+ Ch11_Stencil_Test
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch11_Stencil_Test/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/bar-descriptor.xml
new file mode 100644
index 0000000..97ee1d6
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch11_Stencil_Test
+
+
+ Ch11_Stencil_Test
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch11_Stencil_Test application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch11_Stencil_Test
+
+
+ armle-v7
+ Ch11_Stencil_Test
+
+
+ armle-v7
+ Ch11_Stencil_Test
+
+
+ armle-v7
+ Ch11_Stencil_Test
+
+
+ x86
+ Ch11_Stencil_Test
+
+
+ x86
+ Ch11_Stencil_Test
+
+
+ x86
+ Ch11_Stencil_Test
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/icon.png b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/src/Stencil_Test.c b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/src/Stencil_Test.c
new file mode 100644
index 0000000..c3cfcaa
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch11_Stencil_Test/src/Stencil_Test.c
@@ -0,0 +1,278 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// Stencil_Test.c
+//
+// This example shows various stencil buffer operations.
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+
+ // Uniform locations
+ GLint colorLoc;
+
+} UserData;
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "attribute vec4 a_position; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "uniform vec4 u_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = u_color; \n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+
+ // Get the sampler location
+ userData->colorLoc = glGetUniformLocation(userData->programObject, "u_color");
+
+ // Set the clear color
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Enable the depth and stencil tests
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_STENCIL_TEST);
+
+ // Set the stencil clear value
+ glClearStencil(0x1);
+
+ // Set the depth clear value
+ glClearDepthf(0.75f);
+
+ return TRUE;
+}
+
+///
+// Initialize the stencil buffer values, and then use those
+// values to control rendering
+//
+void Draw(ESContext *esContext)
+{
+ int i;
+
+ UserData *userData = esContext->userData;
+
+ GLfloat vVertices[] = {
+ -0.75f, 0.25f, 0.50f, // Quad #0
+ -0.25f, 0.25f, 0.50f,
+ -0.25f, 0.75f, 0.50f,
+ -0.75f, 0.75f, 0.50f,
+ 0.25f, 0.25f, 0.90f, // Quad #1
+ 0.75f, 0.25f, 0.90f,
+ 0.75f, 0.75f, 0.90f,
+ 0.25f, 0.75f, 0.90f,
+ -0.75f, -0.75f, 0.50f, // Quad #2
+ -0.25f, -0.75f, 0.50f,
+ -0.25f, -0.25f, 0.50f,
+ -0.75f, -0.25f, 0.50f,
+ 0.25f, -0.75f, 0.50f, // Quad #3
+ 0.75f, -0.75f, 0.50f,
+ 0.75f, -0.25f, 0.50f,
+ 0.25f, -0.25f, 0.50f,
+ -1.00f, -1.00f, 0.00f, // Big Quad
+ 1.00f, -1.00f, 0.00f,
+ 1.00f, 1.00f, 0.00f,
+ -1.00f, 1.00f, 0.00f
+ };
+
+ GLubyte indices[][6] = {
+ { 0, 1, 2, 0, 2, 3 }, // Quad #0
+ { 4, 5, 6, 4, 6, 7 }, // Quad #1
+ { 8, 9, 10, 8, 10, 11 }, // Quad #2
+ { 12, 13, 14, 12, 14, 15 }, // Quad #3
+ { 16, 17, 18, 16, 18, 19 } // Big Quad
+ };
+
+#define NumTests 4
+ GLfloat colors[NumTests][4] = {
+ { 1.0f, 0.0f, 0.0f, 1.0f },
+ { 0.0f, 1.0f, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 0.0f, 0.0f }
+ };
+
+ GLint numStencilBits;
+ GLuint stencilValues[NumTests] = {
+ 0x7, // Result of test 0
+ 0x0, // Result of test 1
+ 0x2, // Result of test 2
+ 0xff // Result of test 3. We need to fill this
+ // value in a run-time
+ };
+
+ // Set the viewport
+ glViewport(0, 0, esContext->width, esContext->height);
+
+ // Clear the color, depth, and stencil buffers. At this
+ // point, the stencil buffer will be 0x1 for all pixels
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ // Use the program object
+ glUseProgram(userData->programObject);
+
+ // Load the vertex position
+ glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+
+ // Test 0:
+ //
+ // Initialize upper-left region. In this case, the
+ // stencil-buffer values will be replaced because the
+ // stencil test for the rendered pixels will fail the
+ // stencil test, which is
+ //
+ // ref mask stencil mask
+ // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 )
+ //
+ // The value in the stencil buffer for these pixels will
+ // be 0x7.
+ //
+ glStencilFunc(GL_LESS, 0x7, 0x3);
+ glStencilOp(GL_REPLACE, GL_DECR, GL_DECR);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0]);
+
+ // Test 1:
+ //
+ // Initialize the upper-right region. Here, we'll decrement
+ // the stencil-buffer values where the stencil test passes
+ // but the depth test fails. The stencil test is
+ //
+ // ref mask stencil mask
+ // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 )
+ //
+ // but where the geometry fails the depth test. The
+ // stencil values for these pixels will be 0x0.
+ //
+ glStencilFunc(GL_GREATER, 0x3, 0x3);
+ glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1]);
+
+ // Test 2:
+ //
+ // Initialize the lower-left region. Here we'll increment
+ // (with saturation) the stencil value where both the
+ // stencil and depth tests pass. The stencil test for
+ // these pixels will be
+ //
+ // ref mask stencil mask
+ // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 )
+ //
+ // The stencil values for these pixels will be 0x2.
+ //
+ glStencilFunc(GL_EQUAL, 0x1, 0x3);
+ glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2]);
+
+ // Test 3:
+ //
+ // Finally, initialize the lower-right region. We'll invert
+ // the stencil value where the stencil tests fails. The
+ // stencil test for these pixels will be
+ //
+ // ref mask stencil mask
+ // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 )
+ //
+ // The stencil value here will be set to ~((2^s-1) & 0x1),
+ // (with the 0x1 being from the stencil clear value),
+ // where 's' is the number of bits in the stencil buffer
+ //
+ glStencilFunc(GL_EQUAL, 0x2, 0x1);
+ glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3]);
+
+ // Since we don't know at compile time how many stencil bits are present,
+ // we'll query, and update the value correct value in the
+ // stencilValues arrays for the fourth tests. We'll use this value
+ // later in rendering.
+ glGetIntegerv(GL_STENCIL_BITS, &numStencilBits);
+
+ stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff;
+
+ // Save stencil mask
+ GLint stencilMask;
+ glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask);
+
+ // Use the stencil buffer for controlling where rendering will
+ // occur. We disable writing to the stencil buffer so we
+ // can test against them without modifying the values we
+ // generated.
+ glStencilMask(0x0);
+
+ for (i = 0; i < NumTests; ++i)
+ {
+ glStencilFunc(GL_EQUAL, stencilValues[i], 0xff);
+ glUniform4fv(userData->colorLoc, 1, colors[i]);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4]);
+ }
+
+ // Restore stencil mask
+ glStencilMask(stencilMask);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "Stencil Test", 1024, 600, ES_WINDOW_RGB | ES_WINDOW_DEPTH | ES_WINDOW_STENCIL);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.cproject b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.cproject
new file mode 100644
index 0000000..ea32387
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.cproject
@@ -0,0 +1,551 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.project b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.project
new file mode 100644
index 0000000..d9ffc34
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/.project
@@ -0,0 +1,77 @@
+
+
+ Ch13_ParticleSystem
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch13_ParticleSystem/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/bar-descriptor.xml
new file mode 100644
index 0000000..049b2e7
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/bar-descriptor.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ com.example.Ch13_ParticleSystem
+
+
+ Ch13_ParticleSystem
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch13_ParticleSystem application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+ res/textures/smoke.tga
+
+ armle-v7
+ Ch13_ParticleSystem
+
+
+ armle-v7
+ Ch13_ParticleSystem
+
+
+ armle-v7
+ Ch13_ParticleSystem
+
+
+ armle-v7
+ Ch13_ParticleSystem
+
+
+ x86
+ Ch13_ParticleSystem
+
+
+ x86
+ Ch13_ParticleSystem
+
+
+ x86
+ Ch13_ParticleSystem
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/icon.png b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/res/textures/smoke.tga b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/res/textures/smoke.tga
new file mode 100644
index 0000000..06a0705
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/res/textures/smoke.tga differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/src/ParticleSystem.c b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/src/ParticleSystem.c
new file mode 100644
index 0000000..dae3fd9
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch13_ParticleSystem/src/ParticleSystem.c
@@ -0,0 +1,295 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// ParticleSystem.c
+//
+// This is an example that demonstrates rendering a particle system
+// using a vertex shader and point sprites.
+//
+#include
+#include
+#include "esUtil.h"
+
+#define NUM_PARTICLES 1000
+#define PARTICLE_SIZE 7
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint lifetimeLoc;
+ GLint startPositionLoc;
+ GLint endPositionLoc;
+
+ // Uniform location
+ GLint timeLoc;
+ GLint colorLoc;
+ GLint centerPositionLoc;
+ GLint samplerLoc;
+
+ // Texture handle
+ GLuint textureId;
+
+ // Particle vertex data
+ float particleData[NUM_PARTICLES * PARTICLE_SIZE];
+
+ // Current time
+ float time;
+
+} UserData;
+
+///
+// Load texture from disk
+//
+GLuint LoadTexture(char *fileName)
+{
+ int width, height;
+ char *buffer = esLoadTGA(fileName, &width, &height);
+ GLuint texId;
+
+ if (buffer == NULL)
+ {
+ esLogMessage("Error loading (%s) image.\n", fileName);
+ return 0;
+ }
+
+ glGenTextures(1, &texId);
+ glBindTexture(GL_TEXTURE_2D, texId);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ free(buffer);
+
+ return texId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ int i;
+
+ GLchar vShaderStr[] =
+ "uniform float u_time; \n"
+ "uniform vec3 u_centerPosition; \n"
+ "attribute float a_lifetime; \n"
+ "attribute vec3 a_startPosition; \n"
+ "attribute vec3 a_endPosition; \n"
+ "varying float v_lifetime; \n"
+ "void main() \n"
+ "{ \n"
+ " if ( u_time <= a_lifetime ) \n"
+ " { \n"
+ " gl_Position.xyz = a_startPosition + \n"
+ " (u_time * a_endPosition); \n"
+ " gl_Position.xyz += u_centerPosition; \n"
+ " gl_Position.w = 1.0; \n"
+ " } \n"
+ " else \n"
+ " gl_Position = vec4( -1000, -1000, 0, 0 ); \n"
+ " v_lifetime = 1.0 - ( u_time / a_lifetime ); \n"
+ " v_lifetime = clamp ( v_lifetime, 0.0, 1.0 ); \n"
+ " gl_PointSize = ( v_lifetime * v_lifetime ) * 40.0; \n"
+ "}";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "uniform vec4 u_color; \n"
+ "varying float v_lifetime; \n"
+ "uniform sampler2D s_texture; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor; \n"
+ " texColor = texture2D( s_texture, gl_PointCoord ); \n"
+ " gl_FragColor = vec4( u_color ) * texColor; \n"
+ " gl_FragColor.a *= v_lifetime; \n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->lifetimeLoc = glGetAttribLocation(userData->programObject, "a_lifetime");
+ userData->startPositionLoc = glGetAttribLocation(userData->programObject, "a_startPosition");
+ userData->endPositionLoc = glGetAttribLocation(userData->programObject, "a_endPosition");
+
+ // Get the uniform locations
+ userData->timeLoc = glGetUniformLocation(userData->programObject, "u_time");
+ userData->centerPositionLoc = glGetUniformLocation(userData->programObject, "u_centerPosition");
+ userData->colorLoc = glGetUniformLocation(userData->programObject, "u_color");
+ userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Fill in particle data array
+ srand(0);
+ for (i = 0; i < NUM_PARTICLES; i++)
+ {
+ float *particleData = &userData->particleData[i * PARTICLE_SIZE];
+
+ // Lifetime of particle
+ (*particleData++) = ((float) (rand() % 10000) / 10000.0f);
+
+ // End position of particle
+ (*particleData++) = ((float) (rand() % 10000) / 5000.0f) - 1.0f;
+ (*particleData++) = ((float) (rand() % 10000) / 5000.0f) - 1.0f;
+ (*particleData++) = ((float) (rand() % 10000) / 5000.0f) - 1.0f;
+
+ // Start position of particle
+ (*particleData++) = ((float) (rand() % 10000) / 40000.0f) - 0.125f;
+ (*particleData++) = ((float) (rand() % 10000) / 40000.0f) - 0.125f;
+ (*particleData++) = ((float) (rand() % 10000) / 40000.0f) - 0.125f;
+
+ }
+
+ // Initialize time to cause reset on first update
+ userData->time = 1.0f;
+
+ userData->textureId = LoadTexture("res/textures/smoke.tga");
+ if (userData->textureId <= 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+///
+// Update time-based variables
+//
+void Update ( ESContext *esContext, float deltaTime )
+{
+ UserData *userData = esContext->userData;
+
+ userData->time += deltaTime;
+
+ if ( userData->time >= 1.0f )
+ {
+ float centerPos[3];
+ float color[4];
+
+ userData->time = 0.0f;
+
+ // Pick a new start location and color
+ centerPos[0] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+ centerPos[1] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+ centerPos[2] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+
+ glUniform3fv ( userData->centerPositionLoc, 1, ¢erPos[0] );
+
+ // Random color
+ color[0] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+ color[1] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+ color[2] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+ color[3] = 0.5;
+
+ glUniform4fv ( userData->colorLoc, 1, &color[0] );
+ }
+
+ // Load uniform time variable
+ glUniform1f ( userData->timeLoc, userData->time );
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+ UserData *userData = esContext->userData;
+
+ // 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 attributes
+ glVertexAttribPointer ( userData->lifetimeLoc, 1, GL_FLOAT,
+ GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
+ userData->particleData );
+
+ glVertexAttribPointer ( userData->endPositionLoc, 3, GL_FLOAT,
+ GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
+ &userData->particleData[1] );
+
+ glVertexAttribPointer ( userData->startPositionLoc, 3, GL_FLOAT,
+ GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
+ &userData->particleData[4] );
+
+
+ glEnableVertexAttribArray ( userData->lifetimeLoc );
+ glEnableVertexAttribArray ( userData->endPositionLoc );
+ glEnableVertexAttribArray ( userData->startPositionLoc );
+ // Blend particles
+ glEnable ( GL_BLEND );
+ glBlendFunc ( GL_SRC_ALPHA, GL_ONE );
+
+ // Bind the texture
+ glActiveTexture ( GL_TEXTURE0 );
+ glBindTexture ( GL_TEXTURE_2D, userData->textureId );
+ glEnable ( GL_TEXTURE_2D );
+
+ // Set the sampler texture unit to 0
+ glUniform1i ( userData->samplerLoc, 0 );
+
+ glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
+
+ eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures ( 1, &userData->textureId );
+
+ // Delete program object
+ glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext ( &esContext );
+ esContext.userData = &userData;
+
+ esCreateWindow ( &esContext, "ParticleSystem", 1024, 600, ES_WINDOW_RGB );
+
+ if ( !Init ( &esContext ) )
+ return 0;
+
+ esRegisterDrawFunc ( &esContext, Draw );
+ esRegisterUpdateFunc ( &esContext, Update );
+
+ esMainLoop ( &esContext );
+
+ ShutDown ( &esContext );
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.cproject b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.cproject
new file mode 100644
index 0000000..03c6538
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.cproject
@@ -0,0 +1,551 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.project b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.project
new file mode 100644
index 0000000..3205877
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/.project
@@ -0,0 +1,77 @@
+
+
+ Ch2_Hello_Triangle
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch2_Hello_Triangle/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/bar-descriptor.xml
new file mode 100644
index 0000000..928c26f
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch2_Hello_Triangle
+
+
+ Ch2_Hello_Triangle
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch2_Hello_Triangle application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch2_Hello_Triangle
+
+
+ armle-v7
+ Ch2_Hello_Triangle
+
+
+ armle-v7
+ Ch2_Hello_Triangle
+
+
+ armle-v7
+ Ch2_Hello_Triangle
+
+
+ x86
+ Ch2_Hello_Triangle
+
+
+ x86
+ Ch2_Hello_Triangle
+
+
+ x86
+ Ch2_Hello_Triangle
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/icon.png b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/src/Hello_Triangle.c b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/src/Hello_Triangle.c
new file mode 100644
index 0000000..5fff789
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch2_Hello_Triangle/src/Hello_Triangle.c
@@ -0,0 +1,194 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// Hello_Triangle.c
+//
+// This is a simple example that draws a single triangle with
+// a minimal vertex/fragment shader. The purpose of this
+// example is to demonstrate the basic concepts of
+// OpenGL ES 2.0 rendering.
+#include
+#include
+#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(GLenum type, const char *shaderSrc)
+{
+ 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;
+ GLchar vShaderStr[] =
+ "attribute vec4 vPosition; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vPosition; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float;\n"
+ "void main() \n"
+ "{ \n"
+ " 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, 0.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;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ if (!esCreateWindow(&esContext, "Hello Triangle", 1024, 600, ES_WINDOW_RGB))
+ return 0;
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.cproject b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.cproject
new file mode 100644
index 0000000..f10fd11
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.project b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.project
new file mode 100644
index 0000000..bfb238a
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/.project
@@ -0,0 +1,77 @@
+
+
+ Ch8_Simple_VertexShader
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch8_Simple_VertexShader/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/bar-descriptor.xml
new file mode 100644
index 0000000..77d0005
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch8_Simple_VertexShader
+
+
+ Ch8_Simple_VertexShader
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch8_Simple_VertexShader application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch8_Simple_VertexShader
+
+
+ armle-v7
+ Ch8_Simple_VertexShader
+
+
+ armle-v7
+ Ch8_Simple_VertexShader
+
+
+ armle-v7
+ Ch8_Simple_VertexShader
+
+
+ x86
+ Ch8_Simple_VertexShader
+
+
+ x86
+ Ch8_Simple_VertexShader
+
+
+ x86
+ Ch8_Simple_VertexShader
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/icon.png b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/src/Simple_VertexShader.c b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/src/Simple_VertexShader.c
new file mode 100644
index 0000000..8e5688a
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch8_Simple_VertexShader/src/Simple_VertexShader.c
@@ -0,0 +1,192 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// Simple_VertexShader.c
+//
+// This is a simple example that draws a rotating cube in perspective
+// using a vertex shader to transform the object
+//
+#include
+#include "esUtil.h"
+
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+
+ // Uniform locations
+ GLint mvpLoc;
+
+ // Vertex data
+ GLfloat *vertices;
+ GLuint *indices;
+ int numIndices;
+
+ // Rotation angle
+ GLfloat angle;
+
+ // MVP matrix
+ ESMatrix mvpMatrix;
+} UserData;
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "uniform mat4 u_mvpMatrix; \n"
+ "attribute vec4 a_position; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = u_mvpMatrix * a_position; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); \n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+
+ // Get the uniform locations
+ userData->mvpLoc = glGetUniformLocation(userData->programObject, "u_mvpMatrix");
+
+ // Generate the vertex data
+ userData->numIndices = esGenCube(1.0, &userData->vertices, NULL, NULL, &userData->indices);
+
+ // Starting rotation angle for the cube
+ userData->angle = 45.0f;
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+
+///
+// Update MVP matrix based on time
+//
+void Update(ESContext *esContext, float deltaTime)
+{
+ UserData *userData = (UserData*) esContext->userData;
+ ESMatrix perspective;
+ ESMatrix modelview;
+ float aspect;
+
+ // Compute a rotation angle based on time to rotate the cube
+ userData->angle += (deltaTime * 40.0f);
+ if (userData->angle >= 360.0f)
+ userData->angle -= 360.0f;
+
+ // Compute the window aspect ratio
+ aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
+
+ // Generate a perspective matrix with a 60 degree FOV
+ esMatrixLoadIdentity(&perspective);
+ esPerspective(&perspective, 60.0f, aspect, 1.0f, 20.0f);
+
+ // Generate a model view matrix to rotate/translate the cube
+ esMatrixLoadIdentity(&modelview);
+
+ // Translate away from the viewer
+ esTranslate(&modelview, 0.0, 0.0, -2.0);
+
+ // Rotate the cube
+ esRotate(&modelview, userData->angle, 1.0, 0.0, 1.0);
+
+ // Compute the final MVP by multiplying the
+ // modevleiw and perspective matrices together
+ esMatrixMultiply(&userData->mvpMatrix, &modelview, &perspective);
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // 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 position
+ glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), userData->vertices);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+
+ // Load the MVP matrix
+ glUniformMatrix4fv(userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0]);
+
+ // Draw the cube
+ glDrawElements(GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_INT, userData->indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ if (userData->vertices != NULL)
+ {
+ free(userData->vertices);
+ }
+
+ if (userData->indices != NULL)
+ {
+ free(userData->indices);
+ }
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "Simple Texture 2D", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+ esRegisterUpdateFunc(&esContext, Update);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.cproject b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.cproject
new file mode 100644
index 0000000..d595c3e
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.project b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.project
new file mode 100644
index 0000000..dc6dede
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/.project
@@ -0,0 +1,77 @@
+
+
+ Ch9_MipMap2D
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch9_MipMap2D/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/bar-descriptor.xml
new file mode 100644
index 0000000..a6599c9
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch9_MipMap2D
+
+
+ Ch9_MipMap2D
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch9_MipMap2D application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch9_MipMap2D
+
+
+ armle-v7
+ Ch9_MipMap2D
+
+
+ armle-v7
+ Ch9_MipMap2D
+
+
+ armle-v7
+ Ch9_MipMap2D
+
+
+ x86
+ Ch9_MipMap2D
+
+
+ x86
+ Ch9_MipMap2D
+
+
+ x86
+ Ch9_MipMap2D
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/icon.png b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/src/MipMap2D.c b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/src/MipMap2D.c
new file mode 100644
index 0000000..1759b4d
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_MipMap2D/src/MipMap2D.c
@@ -0,0 +1,334 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// MipMap2D.c
+//
+// This is a simple example that demonstrates generating a mipmap chain
+// and rendering with it
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+ GLint texCoordLoc;
+
+ // Sampler location
+ GLint samplerLoc;
+
+ // Offset location
+ GLint offsetLoc;
+
+ // Texture handle
+ GLuint textureId;
+
+} UserData;
+
+
+///
+// From an RGB8 source image, generate the next level mipmap
+//
+GLboolean GenMipMap2D(GLubyte *src, GLubyte **dst, int srcWidth, int srcHeight, int *dstWidth, int *dstHeight)
+{
+ int x, y;
+ int texelSize = 3;
+
+ *dstWidth = srcWidth / 2;
+ if (*dstWidth <= 0)
+ *dstWidth = 1;
+
+ *dstHeight = srcHeight / 2;
+ if (*dstHeight <= 0)
+ *dstHeight = 1;
+
+ *dst = malloc(sizeof(GLubyte) * texelSize * (*dstWidth) * (*dstHeight));
+ if (*dst == NULL)
+ return GL_FALSE;
+
+ for (y = 0; y < *dstHeight; y++)
+ {
+ for (x = 0; x < *dstWidth; x++)
+ {
+ int srcIndex[4];
+ float r = 0.0f, g = 0.0f, b = 0.0f;
+ int sample;
+
+ // Compute the offsets for 2x2 grid of pixels in previous
+ // image to perform box filter
+ srcIndex[0] = (((y * 2) * srcWidth) + (x * 2)) * texelSize;
+ srcIndex[1] = (((y * 2) * srcWidth) + (x * 2 + 1)) * texelSize;
+ srcIndex[2] = ((((y * 2) + 1) * srcWidth) + (x * 2)) * texelSize;
+ srcIndex[3] = ((((y * 2) + 1) * srcWidth) + (x * 2 + 1)) * texelSize;
+
+ // Sum all pixels
+ for (sample = 0; sample < 4; sample++)
+ {
+ r += src[srcIndex[sample]];
+ g += src[srcIndex[sample] + 1];
+ b += src[srcIndex[sample] + 2];
+ }
+
+ // Average results
+ r /= 4.0;
+ g /= 4.0;
+ b /= 4.0;
+
+ // Store resulting pixels
+ (*dst)[(y * (*dstWidth) + x) * texelSize] = (GLubyte)(r);
+ (*dst)[(y * (*dstWidth) + x) * texelSize + 1] = (GLubyte)(g);
+ (*dst)[(y * (*dstWidth) + x) * texelSize + 2] = (GLubyte)(b);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+///
+// Generate an RGB8 checkerboard image
+//
+GLubyte* GenCheckImage(int width, int height, int checkSize)
+{
+ int x, y;
+ GLubyte *pixels = malloc(width * height * 3);
+
+ if (pixels == NULL)
+ return NULL;
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ GLubyte rColor = 0;
+ GLubyte bColor = 0;
+
+ if ((x / checkSize) % 2 == 0)
+ {
+ rColor = 255 * ((y / checkSize) % 2);
+ bColor = 255 * (1 - ((y / checkSize) % 2));
+ }
+ else
+ {
+ bColor = 255 * ((y / checkSize) % 2);
+ rColor = 255 * (1 - ((y / checkSize) % 2));
+ }
+
+ pixels[(y * height + x) * 3] = rColor;
+ pixels[(y * height + x) * 3 + 1] = 0;
+ pixels[(y * height + x) * 3 + 2] = bColor;
+ }
+ }
+
+ return pixels;
+}
+
+///
+// Create a mipmapped 2D texture image
+//
+GLuint CreateMipMappedTexture2D()
+{
+ // Texture object handle
+ GLuint textureId;
+ int width = 256, height = 256;
+ int level;
+ GLubyte *pixels;
+ GLubyte *prevImage;
+ GLubyte *newImage;
+
+ pixels = GenCheckImage(width, height, 8);
+ if (pixels == NULL)
+ return 0;
+
+ // Generate a texture object
+ glGenTextures(1, &textureId);
+
+ // Bind the texture object
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ // Load mipmap level 0
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ level = 1;
+ prevImage = &pixels[0];
+
+ while (width > 1 && height > 1)
+ {
+ int newWidth, newHeight;
+
+ // Generate the next mipmap level
+ GenMipMap2D(prevImage, &newImage, width, height, &newWidth, &newHeight);
+
+ // Load the mipmap level
+ glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, newImage);
+
+ // Free the previous image
+ free(prevImage);
+
+ // Set the previous image for the next iteration
+ prevImage = newImage;
+ level++;
+
+ // Half the width and height
+ width = newWidth;
+ height = newHeight;
+ }
+
+ free(newImage);
+
+ // Set the filtering mode
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ return textureId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "uniform float u_offset; \n"
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ " gl_Position.x += u_offset;\n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+ userData->texCoordLoc = glGetAttribLocation(userData->programObject, "a_texCoord");
+
+ // Get the sampler location
+ userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
+
+ // Get the offset location
+ userData->offsetLoc = glGetUniformLocation(userData->programObject, "u_offset");
+
+ // Load the texture
+ userData->textureId = CreateMipMappedTexture2D();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLfloat vVertices[] = { -0.5f, 0.5f, 0.0f, 1.5f, // Position 0
+ 0.0f, 0.0f, // TexCoord 0
+ -0.5f, -0.5f, 0.0f, 0.75f, // Position 1
+ 0.0f, 1.0f, // TexCoord 1
+ 0.5f, -0.5f, 0.0f, 0.75f, // Position 2
+ 1.0f, 1.0f, // TexCoord 2
+ 0.5f, 0.5f, 0.0f, 1.5f, // Position 3
+ 1.0f, 0.0f // TexCoord 3
+ };
+ GLushort indices[] =
+ { 0, 1, 2, 0, 2, 3 };
+
+ // 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 position
+ glVertexAttribPointer(userData->positionLoc, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vVertices);
+ // Load the texture coordinate
+ glVertexAttribPointer(userData->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), &vVertices[4]);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+ glEnableVertexAttribArray(userData->texCoordLoc);
+
+ // Bind the texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, userData->textureId);
+
+ // Set the sampler texture unit to 0
+ glUniform1i(userData->samplerLoc, 0);
+
+ // Draw quad with nearest sampling
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glUniform1f(userData->offsetLoc, -0.6f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ // Draw quad with trilinear filtering
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glUniform1f(userData->offsetLoc, 0.6f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures(1, &userData->textureId);
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "MipMap 2D", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.cproject b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.cproject
new file mode 100644
index 0000000..232a937
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.project b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.project
new file mode 100644
index 0000000..d50e785
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/.project
@@ -0,0 +1,77 @@
+
+
+ Ch9_Simple_Texture2D
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch9_Simple_Texture2D/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/bar-descriptor.xml
new file mode 100644
index 0000000..3e172ce
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch9_Simple_Texture2D
+
+
+ Ch9_Simple_Texture2D
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch9_Simple_Texture2D application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch9_Simple_Texture2D
+
+
+ armle-v7
+ Ch9_Simple_Texture2D
+
+
+ armle-v7
+ Ch9_Simple_Texture2D
+
+
+ armle-v7
+ Ch9_Simple_Texture2D
+
+
+ x86
+ Ch9_Simple_Texture2D
+
+
+ x86
+ Ch9_Simple_Texture2D
+
+
+ x86
+ Ch9_Simple_Texture2D
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/icon.png b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/src/Simple_Texture2D.c b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/src/Simple_Texture2D.c
new file mode 100644
index 0000000..3010ae6
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_Texture2D/src/Simple_Texture2D.c
@@ -0,0 +1,197 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// Simple_Texture2D.c
+//
+// This is a simple example that draws a quad with a 2D
+// texture image. The purpose of this example is to demonstrate
+// the basics of 2D texturing
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+ GLint texCoordLoc;
+
+ // Sampler location
+ GLint samplerLoc;
+
+ // Texture handle
+ GLuint textureId;
+
+} UserData;
+
+///
+// Create a simple 2x2 texture image with four different colors
+//
+GLuint CreateSimpleTexture2D()
+{
+ // Texture object handle
+ GLuint textureId;
+
+ // 2x2 Image, 3 bytes per pixel (R, G, B)
+ GLubyte pixels[4 * 3] = {
+ 255, 0, 0, // Red
+ 0, 255, 0, // Green
+ 0, 0, 255, // Blue
+ 255, 255, 0 // Yellow
+ };
+
+ // Use tightly packed data
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ // Generate a texture object
+ glGenTextures(1, &textureId);
+
+ // Bind the texture object
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ // Load the texture
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ // Set the filtering mode
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ return textureId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+ userData->texCoordLoc = glGetAttribLocation(userData->programObject, "a_texCoord");
+
+ // Get the sampler location
+ userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
+
+ // Load the texture
+ userData->textureId = CreateSimpleTexture2D();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+ UserData *userData = esContext->userData;
+ GLfloat vVertices[] = { -0.5f, 0.5f, 0.0f, // Position 0
+ 0.0f, 0.0f, // TexCoord 0
+ -0.5f, -0.5f, 0.0f, // Position 1
+ 0.0f, 1.0f, // TexCoord 1
+ 0.5f, -0.5f, 0.0f, // Position 2
+ 1.0f, 1.0f, // TexCoord 2
+ 0.5f, 0.5f, 0.0f, // Position 3
+ 1.0f, 0.0f // TexCoord 3
+ };
+ GLushort indices[] =
+ { 0, 1, 2, 0, 2, 3 };
+
+ // 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 position
+ glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
+ // Load the texture coordinate
+ glVertexAttribPointer(userData->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+ glEnableVertexAttribArray(userData->texCoordLoc);
+
+ // Bind the texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, userData->textureId);
+
+ // Set the sampler texture unit to 0
+ glUniform1i(userData->samplerLoc, 0);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures(1, &userData->textureId);
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "Simple Texture 2D", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.cproject b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.cproject
new file mode 100644
index 0000000..3629eb5
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.project b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.project
new file mode 100644
index 0000000..27f788d
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/.project
@@ -0,0 +1,77 @@
+
+
+ Ch9_Simple_TextureCubemap
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch9_Simple_TextureCubemap/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/bar-descriptor.xml
new file mode 100644
index 0000000..2fb4f73
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch9_Simple_TextureCubemap
+
+
+ Ch9_Simple_TextureCubemap
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch9_Simple_TextureCubemap application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch9_Simple_TextureCubemap
+
+
+ armle-v7
+ Ch9_Simple_TextureCubemap
+
+
+ armle-v7
+ Ch9_Simple_TextureCubemap
+
+
+ armle-v7
+ Ch9_Simple_TextureCubemap
+
+
+ x86
+ Ch9_Simple_TextureCubemap
+
+
+ x86
+ Ch9_Simple_TextureCubemap
+
+
+ x86
+ Ch9_Simple_TextureCubemap
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/icon.png b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/src/Simple_TextureCubemap.c b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/src/Simple_TextureCubemap.c
new file mode 100644
index 0000000..28bb333
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_Simple_TextureCubemap/src/Simple_TextureCubemap.c
@@ -0,0 +1,217 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// Simple_TextureCubemap.c
+//
+// This is a simple example that draws a sphere with a cubemap image applied.
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+ GLint normalLoc;
+
+ // Sampler location
+ GLint samplerLoc;
+
+ // Texture handle
+ GLuint textureId;
+
+ // Vertex data
+ int numIndices;
+ GLfloat *vertices;
+ GLfloat *normals;
+ GLuint *indices;
+
+} UserData;
+
+///
+// Create a simple cubemap with a 1x1 face with a different
+// color for each face
+GLuint CreateSimpleTextureCubemap()
+{
+ GLuint textureId;
+ // Six 1x1 RGB faces
+ GLubyte cubePixels[6][3] =
+ {
+ // Face 0 - Red
+ {255, 0, 0},
+ // Face 1 - Green,
+ {0, 255, 0},
+ // Face 3 - Blue
+ {0, 0, 255},
+ // Face 4 - Yellow
+ {255, 255, 0},
+ // Face 5 - Purple
+ {255, 0, 255},
+ // Face 6 - White
+ {255, 255, 255}
+ };
+
+ // Generate a texture object
+ glGenTextures(1, &textureId);
+
+ // Bind the texture object
+ glBindTexture(GL_TEXTURE_CUBE_MAP, textureId);
+
+ // Load the cube face - Positive X
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[0]);
+
+ // Load the cube face - Negative X
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[1]);
+
+ // Load the cube face - Positive Y
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[2]);
+
+ // Load the cube face - Negative Y
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[3]);
+
+ // Load the cube face - Positive Z
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[4]);
+
+ // Load the cube face - Negative Z
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[5]);
+
+ // Set the filtering mode
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ return textureId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec3 a_normal; \n"
+ "varying vec3 v_normal; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ " v_normal = a_normal; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec3 v_normal; \n"
+ "uniform samplerCube s_texture; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = textureCube( s_texture, v_normal );\n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+ userData->normalLoc = glGetAttribLocation(userData->programObject, "a_normal");
+
+ // Get the sampler locations
+ userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
+
+ // Load the texture
+ userData->textureId = CreateSimpleTextureCubemap();
+
+ // Generate the vertex data
+ userData->numIndices = esGenSphere(20, 0.75f, &userData->vertices, &userData->normals, NULL, &userData->indices);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Set the viewport
+ glViewport(0, 0, esContext->width, esContext->height);
+
+ // Clear the color buffer
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+
+ // Use the program object
+ glUseProgram(userData->programObject);
+
+ // Load the vertex position
+ glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 0, userData->vertices);
+ // Load the normal
+ glVertexAttribPointer(userData->normalLoc, 3, GL_FLOAT, GL_FALSE, 0, userData->normals);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+ glEnableVertexAttribArray(userData->normalLoc);
+
+ // Bind the texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, userData->textureId);
+
+ // Set the sampler texture unit to 0
+ glUniform1i(userData->samplerLoc, 0);
+
+ glDrawElements(GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_INT, userData->indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures(1, &userData->textureId);
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+
+ free(userData->vertices);
+ free(userData->normals);
+}
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "Simple Texture Cubemap", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.cproject b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.cproject
new file mode 100644
index 0000000..f026af2
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.cproject
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.project b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.project
new file mode 100644
index 0000000..ae67a52
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/.project
@@ -0,0 +1,77 @@
+
+
+ Ch9_TextureWrap
+
+
+ Common
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Ch9_TextureWrap/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/bar-descriptor.xml b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/bar-descriptor.xml
new file mode 100644
index 0000000..000a32f
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/bar-descriptor.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ com.example.Ch9_TextureWrap
+
+
+ Ch9_TextureWrap
+
+
+ 1.0.0
+
+
+ 1
+
+
+
+
+
+ The Ch9_TextureWrap application
+
+
+
+
+
+ Example Inc.
+
+
+
+
+
+ none
+ false
+
+
+
+ core.games
+ icon.png
+
+ armle-v7
+ Ch9_TextureWrap
+
+
+ armle-v7
+ Ch9_TextureWrap
+
+
+ armle-v7
+ Ch9_TextureWrap
+
+
+ armle-v7
+ Ch9_TextureWrap
+
+
+ x86
+ Ch9_TextureWrap
+
+
+ x86
+ Ch9_TextureWrap
+
+
+ x86
+ Ch9_TextureWrap
+
+
+
+
+ icon.png
+
+
+
+
+
+
+ run_native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/icon.png b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/icon.png
new file mode 100644
index 0000000..bcbc3f9
Binary files /dev/null and b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/icon.png differ
diff --git a/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/src/TextureWrap.c b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/src/TextureWrap.c
new file mode 100644
index 0000000..4af508e
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Ch9_TextureWrap/src/TextureWrap.c
@@ -0,0 +1,252 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// TextureWrap.c
+//
+// This is an example that demonstrates the three texture
+// wrap modes available on 2D textures
+//
+#include
+#include "esUtil.h"
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+ // Attribute locations
+ GLint positionLoc;
+ GLint texCoordLoc;
+
+ // Sampler location
+ GLint samplerLoc;
+
+ // Offset location
+ GLint offsetLoc;
+
+ // Texture handle
+ GLuint textureId;
+
+} UserData;
+
+///
+// Generate an RGB8 checkerboard image
+//
+GLubyte* GenCheckImage(int width, int height, int checkSize)
+{
+ int x, y;
+ GLubyte *pixels = malloc(width * height * 3);
+
+ if (pixels == NULL)
+ return NULL;
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ GLubyte rColor = 0;
+ GLubyte bColor = 0;
+
+ if ((x / checkSize) % 2 == 0)
+ {
+ rColor = 255 * ((y / checkSize) % 2);
+ bColor = 255 * (1 - ((y / checkSize) % 2));
+ }
+ else
+ {
+ bColor = 255 * ((y / checkSize) % 2);
+ rColor = 255 * (1 - ((y / checkSize) % 2));
+ }
+
+ pixels[(y * height + x) * 3] = rColor;
+ pixels[(y * height + x) * 3 + 1] = 0;
+ pixels[(y * height + x) * 3 + 2] = bColor;
+ }
+ }
+
+ return pixels;
+}
+
+///
+// Create a mipmapped 2D texture image
+//
+GLuint CreateTexture2D()
+{
+ // Texture object handle
+ GLuint textureId;
+ int width = 256, height = 256;
+ GLubyte *pixels;
+
+ pixels = GenCheckImage(width, height, 64);
+ if (pixels == NULL)
+ return 0;
+
+ // Generate a texture object
+ glGenTextures(1, &textureId);
+
+ // Bind the texture object
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ // Load mipmap level 0
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ // Set the filtering mode
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ return textureId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLchar vShaderStr[] =
+ "uniform float u_offset; \n"
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = a_position; \n"
+ " gl_Position.x += u_offset;\n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ GLchar fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+ "} \n";
+
+ // Load the shaders and get a linked program object
+ userData->programObject = esLoadProgram(vShaderStr, fShaderStr);
+
+ // Get the attribute locations
+ userData->positionLoc = glGetAttribLocation(userData->programObject, "a_position");
+ userData->texCoordLoc = glGetAttribLocation(userData->programObject, "a_texCoord");
+
+ // Get the sampler location
+ userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
+
+ // Get the offset location
+ userData->offsetLoc = glGetUniformLocation(userData->programObject, "u_offset");
+
+ // Load the texture
+ userData->textureId = CreateTexture2D();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+ GLfloat vVertices[] = { -0.3f, 0.3f, 0.0f, 1.0f, // Position 0
+ -1.0f, -1.0f, // TexCoord 0
+ -0.3f, -0.3f, 0.0f, 1.0f, // Position 1
+ -1.0f, 2.0f, // TexCoord 1
+ 0.3f, -0.3f, 0.0f, 1.0f, // Position 2
+ 2.0f, 2.0f, // TexCoord 2
+ 0.3f, 0.3f, 0.0f, 1.0f, // Position 3
+ 2.0f, -1.0f // TexCoord 3
+ };
+ GLushort indices[] =
+ { 0, 1, 2, 0, 2, 3 };
+
+ // 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 position
+ glVertexAttribPointer(userData->positionLoc, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vVertices);
+ // Load the texture coordinate
+ glVertexAttribPointer(userData->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), &vVertices[4]);
+
+ glEnableVertexAttribArray(userData->positionLoc);
+ glEnableVertexAttribArray(userData->texCoordLoc);
+
+ // Bind the texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, userData->textureId);
+
+ // Set the sampler texture unit to 0
+ glUniform1i(userData->samplerLoc, 0);
+
+ // Draw quad with repeat wrap mode
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glUniform1f(userData->offsetLoc, -0.7f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ // Draw quad with clamp to edge wrap mode
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glUniform1f(userData->offsetLoc, 0.0f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ // Draw quad with mirrored repeat
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+ glUniform1f(userData->offsetLoc, 0.7f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+}
+
+///
+// Cleanup
+//
+void ShutDown(ESContext *esContext)
+{
+ UserData *userData = esContext->userData;
+
+ // Delete texture object
+ glDeleteTextures(1, &userData->textureId);
+
+ // Delete program object
+ glDeleteProgram(userData->programObject);
+}
+
+int main(int argc, char *argv[])
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext(&esContext);
+ esContext.userData = &userData;
+
+ esCreateWindow(&esContext, "MipMap 2D", 1024, 600, ES_WINDOW_RGB);
+
+ if (!Init(&esContext))
+ return 0;
+
+ esRegisterDrawFunc(&esContext, Draw);
+
+ esMainLoop(&esContext);
+
+ ShutDown(&esContext);
+
+ return 0;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/.cproject b/OpenGLES2-ProgrammingGuide/Common/.cproject
new file mode 100644
index 0000000..48bb278
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/.cproject
@@ -0,0 +1,391 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Common/.project b/OpenGLES2-ProgrammingGuide/Common/.project
new file mode 100644
index 0000000..cd3351e
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/.project
@@ -0,0 +1,76 @@
+
+
+ Common
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/Common/Simulator-Debug}
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+ com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.qnx.tools.ide.bbt.core.bbtnature
+
+
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esShader.c b/OpenGLES2-ProgrammingGuide/Common/src/esShader.c
new file mode 100644
index 0000000..2fa90d5
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esShader.c
@@ -0,0 +1,154 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esShader.c
+//
+// Utility functions for loading shaders and creating program objects.
+//
+
+///
+// Includes
+//
+#include "esUtil.h"
+#include
+
+//////////////////////////////////////////////////////////////////
+//
+// Private Functions
+//
+//
+
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+//
+///
+/// \brief Load a shader, check for compile errors, print error messages to output log
+/// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
+/// \param shaderSrc Shader source string
+/// \return A new shader object on success, 0 on failure
+//
+GLuint ESUTIL_API esLoadShader(GLenum type, const char *shaderSrc)
+{
+ 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;
+}
+
+
+//
+///
+/// \brief Load a vertex and fragment shader, create a program object, link program.
+// Errors output to log.
+/// \param vertShaderSrc Vertex shader source code
+/// \param fragShaderSrc Fragment shader source code
+/// \return A new program object linked with the vertex/fragment shader pair, 0 on failure
+//
+GLuint ESUTIL_API esLoadProgram(const char *vertShaderSrc, const char *fragShaderSrc)
+{
+ GLuint vertexShader;
+ GLuint fragmentShader;
+ GLuint programObject;
+ GLint linked;
+
+ // Load the vertex/fragment shaders
+ vertexShader = esLoadShader(GL_VERTEX_SHADER, vertShaderSrc);
+ if (vertexShader == 0)
+ return 0;
+
+ fragmentShader = esLoadShader(GL_FRAGMENT_SHADER, fragShaderSrc);
+ if (fragmentShader == 0)
+ {
+ glDeleteShader(vertexShader);
+ return 0;
+ }
+
+ // Create the program object
+ programObject = glCreateProgram();
+
+ if (programObject == 0)
+ return 0;
+
+ glAttachShader(programObject, vertexShader);
+ glAttachShader(programObject, fragmentShader);
+
+ // 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 0;
+ }
+
+ // Free up no longer needed shader resources
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+
+ return programObject;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esShapes.c b/OpenGLES2-ProgrammingGuide/Common/src/esShapes.c
new file mode 100644
index 0000000..689385a
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esShapes.c
@@ -0,0 +1,282 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esShapes.c
+//
+// Utility functions for generating shapes
+//
+
+///
+// Includes
+//
+
+#include
+#include
+
+#include "esUtil.h"
+
+
+///
+// Defines
+//
+#define ES_PI (3.14159265f)
+
+//////////////////////////////////////////////////////////////////
+//
+// Private Functions
+//
+//
+
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+//
+/// \brief Generates geometry for a sphere. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLE_STRIP
+/// \param numSlices The number of slices in the sphere
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices )
+{
+ int i;
+ int j;
+ int numParallels = numSlices / 2;
+ int numVertices = ( numParallels + 1 ) * ( numSlices + 1 );
+ int numIndices = numParallels * numSlices * 6;
+ float angleStep = (2.0f * ES_PI) / ((float) numSlices);
+
+ // Allocate memory for buffers
+ if ( vertices != NULL )
+ *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
+
+ if ( normals != NULL )
+ *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
+
+ if ( texCoords != NULL )
+ *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
+
+ if ( indices != NULL )
+ *indices = malloc ( sizeof(GLuint) * numIndices );
+
+ for ( i = 0; i < numParallels + 1; i++ )
+ {
+ for ( j = 0; j < numSlices + 1; j++ )
+ {
+ int vertex = ( i * (numSlices + 1) + j ) * 3;
+
+ if ( vertices )
+ {
+ (*vertices)[vertex + 0] = radius * sinf ( angleStep * (float)i ) *
+ sinf ( angleStep * (float)j );
+ (*vertices)[vertex + 1] = radius * cosf ( angleStep * (float)i );
+ (*vertices)[vertex + 2] = radius * sinf ( angleStep * (float)i ) *
+ cosf ( angleStep * (float)j );
+ }
+
+ if ( normals )
+ {
+ (*normals)[vertex + 0] = (*vertices)[vertex + 0] / radius;
+ (*normals)[vertex + 1] = (*vertices)[vertex + 1] / radius;
+ (*normals)[vertex + 2] = (*vertices)[vertex + 2] / radius;
+ }
+
+ if ( texCoords )
+ {
+ int texIndex = ( i * (numSlices + 1) + j ) * 2;
+ (*texCoords)[texIndex + 0] = (float) j / (float) numSlices;
+ (*texCoords)[texIndex + 1] = ( 1.0f - (float) i ) / (float) (numParallels - 1 );
+ }
+ }
+ }
+
+ // Generate the indices
+ if ( indices != NULL )
+ {
+ GLuint *indexBuf = (*indices);
+ for ( i = 0; i < numParallels ; i++ )
+ {
+ for ( j = 0; j < numSlices; j++ )
+ {
+ *indexBuf++ = i * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
+
+ *indexBuf++ = i * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
+ *indexBuf++ = i * ( numSlices + 1 ) + ( j + 1 );
+ }
+ }
+ }
+
+ return numIndices;
+}
+
+//
+/// \brief Generates geometry for a cube. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLES
+/// \param scale The size of the cube, use 1.0 for a unit cube.
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices )
+{
+ int i;
+ int numVertices = 24;
+ int numIndices = 36;
+
+ GLfloat cubeVerts[] =
+ {
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ };
+
+ GLfloat cubeNormals[] =
+ {
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ };
+
+ GLfloat cubeTex[] =
+ {
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ };
+
+ // Allocate memory for buffers
+ if ( vertices != NULL )
+ {
+ *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
+ memcpy( *vertices, cubeVerts, sizeof( cubeVerts ) );
+ for ( i = 0; i < numVertices; i++ )
+ {
+ (*vertices)[i] *= scale;
+ }
+ }
+
+ if ( normals != NULL )
+ {
+ *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
+ memcpy( *normals, cubeNormals, sizeof( cubeNormals ) );
+ }
+
+ if ( texCoords != NULL )
+ {
+ *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
+ memcpy( *texCoords, cubeTex, sizeof( cubeTex ) ) ;
+ }
+
+
+ // Generate the indices
+ if ( indices != NULL )
+ {
+ GLuint cubeIndices[] =
+ {
+ 0, 2, 1,
+ 0, 3, 2,
+ 4, 5, 6,
+ 4, 6, 7,
+ 8, 9, 10,
+ 8, 10, 11,
+ 12, 15, 14,
+ 12, 14, 13,
+ 16, 17, 18,
+ 16, 18, 19,
+ 20, 23, 22,
+ 20, 22, 21
+ };
+
+ *indices = malloc ( sizeof(GLuint) * numIndices );
+ memcpy( *indices, cubeIndices, sizeof( cubeIndices ) );
+ }
+
+ return numIndices;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esTransform.c b/OpenGLES2-ProgrammingGuide/Common/src/esTransform.c
new file mode 100644
index 0000000..d43bbdf
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esTransform.c
@@ -0,0 +1,213 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esTransform.c
+//
+// A utility library for OpenGL ES. This library provides a
+// basic common framework for the example applications in the
+// OpenGL ES 2.0 Programming Guide.
+//
+
+///
+// Includes
+//
+#include "esUtil.h"
+#include
+#include
+
+#define PI 3.1415926535897932384626433832795f
+
+void ESUTIL_API
+esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz)
+{
+ result->m[0][0] *= sx;
+ result->m[0][1] *= sx;
+ result->m[0][2] *= sx;
+ result->m[0][3] *= sx;
+
+ result->m[1][0] *= sy;
+ result->m[1][1] *= sy;
+ result->m[1][2] *= sy;
+ result->m[1][3] *= sy;
+
+ result->m[2][0] *= sz;
+ result->m[2][1] *= sz;
+ result->m[2][2] *= sz;
+ result->m[2][3] *= sz;
+}
+
+void ESUTIL_API
+esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz)
+{
+ result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
+ result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
+ result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz);
+ result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
+}
+
+void ESUTIL_API
+esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat sinAngle, cosAngle;
+ GLfloat mag = sqrtf(x * x + y * y + z * z);
+
+ sinAngle = sinf ( angle * PI / 180.0f );
+ cosAngle = cosf ( angle * PI / 180.0f );
+ if ( mag > 0.0f )
+ {
+ GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
+ GLfloat oneMinusCos;
+ ESMatrix rotMat;
+
+ x /= mag;
+ y /= mag;
+ z /= mag;
+
+ xx = x * x;
+ yy = y * y;
+ zz = z * z;
+ xy = x * y;
+ yz = y * z;
+ zx = z * x;
+ xs = x * sinAngle;
+ ys = y * sinAngle;
+ zs = z * sinAngle;
+ oneMinusCos = 1.0f - cosAngle;
+
+ rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
+ rotMat.m[0][1] = (oneMinusCos * xy) - zs;
+ rotMat.m[0][2] = (oneMinusCos * zx) + ys;
+ rotMat.m[0][3] = 0.0F;
+
+ rotMat.m[1][0] = (oneMinusCos * xy) + zs;
+ rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
+ rotMat.m[1][2] = (oneMinusCos * yz) - xs;
+ rotMat.m[1][3] = 0.0F;
+
+ rotMat.m[2][0] = (oneMinusCos * zx) - ys;
+ rotMat.m[2][1] = (oneMinusCos * yz) + xs;
+ rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
+ rotMat.m[2][3] = 0.0F;
+
+ rotMat.m[3][0] = 0.0F;
+ rotMat.m[3][1] = 0.0F;
+ rotMat.m[3][2] = 0.0F;
+ rotMat.m[3][3] = 1.0F;
+
+ esMatrixMultiply( result, &rotMat, result );
+ }
+}
+
+void ESUTIL_API
+esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
+{
+ float deltaX = right - left;
+ float deltaY = top - bottom;
+ float deltaZ = farZ - nearZ;
+ ESMatrix frust;
+
+ if ( (nearZ <= 0.0f) || (farZ <= 0.0f) ||
+ (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) )
+ return;
+
+ frust.m[0][0] = 2.0f * nearZ / deltaX;
+ frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
+
+ frust.m[1][1] = 2.0f * nearZ / deltaY;
+ frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
+
+ frust.m[2][0] = (right + left) / deltaX;
+ frust.m[2][1] = (top + bottom) / deltaY;
+ frust.m[2][2] = -(nearZ + farZ) / deltaZ;
+ frust.m[2][3] = -1.0f;
+
+ frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
+ frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
+
+ esMatrixMultiply(result, &frust, result);
+}
+
+
+void ESUTIL_API
+esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ)
+{
+ GLfloat frustumW, frustumH;
+
+ frustumH = tanf( fovy / 360.0f * PI ) * nearZ;
+ frustumW = frustumH * aspect;
+
+ esFrustum( result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ );
+}
+
+void ESUTIL_API
+esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
+{
+ float deltaX = right - left;
+ float deltaY = top - bottom;
+ float deltaZ = farZ - nearZ;
+ ESMatrix ortho;
+
+ if ( (deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f) )
+ return;
+
+ esMatrixLoadIdentity(&ortho);
+ ortho.m[0][0] = 2.0f / deltaX;
+ ortho.m[3][0] = -(right + left) / deltaX;
+ ortho.m[1][1] = 2.0f / deltaY;
+ ortho.m[3][1] = -(top + bottom) / deltaY;
+ ortho.m[2][2] = -2.0f / deltaZ;
+ ortho.m[3][2] = -(nearZ + farZ) / deltaZ;
+
+ esMatrixMultiply(result, &ortho, result);
+}
+
+
+void ESUTIL_API
+esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB)
+{
+ ESMatrix tmp;
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+ tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
+ (srcA->m[i][1] * srcB->m[1][0]) +
+ (srcA->m[i][2] * srcB->m[2][0]) +
+ (srcA->m[i][3] * srcB->m[3][0]) ;
+
+ tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
+ (srcA->m[i][1] * srcB->m[1][1]) +
+ (srcA->m[i][2] * srcB->m[2][1]) +
+ (srcA->m[i][3] * srcB->m[3][1]) ;
+
+ tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
+ (srcA->m[i][1] * srcB->m[1][2]) +
+ (srcA->m[i][2] * srcB->m[2][2]) +
+ (srcA->m[i][3] * srcB->m[3][2]) ;
+
+ tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
+ (srcA->m[i][1] * srcB->m[1][3]) +
+ (srcA->m[i][2] * srcB->m[2][3]) +
+ (srcA->m[i][3] * srcB->m[3][3]) ;
+ }
+ memcpy(result, &tmp, sizeof(ESMatrix));
+}
+
+
+void ESUTIL_API
+esMatrixLoadIdentity(ESMatrix *result)
+{
+ memset(result, 0x0, sizeof(ESMatrix));
+ result->m[0][0] = 1.0f;
+ result->m[1][1] = 1.0f;
+ result->m[2][2] = 1.0f;
+ result->m[3][3] = 1.0f;
+}
+
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esUtil.c b/OpenGLES2-ProgrammingGuide/Common/src/esUtil.c
new file mode 100644
index 0000000..f592269
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esUtil.c
@@ -0,0 +1,221 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esUtil.c
+//
+// A utility library for OpenGL ES. This library provides a
+// basic common framework for the example applications in the
+// OpenGL ES 2.0 Programming Guide.
+//
+
+///
+// Includes
+//
+#include
+#include
+#include
+#include
+#include
+#include
+#include "esUtil.h"
+#include "esUtil_qnx.h"
+
+///
+// CreateEGLContext()
+//
+// Creates an EGL rendering context and all associated elements
+//
+EGLBoolean CreateEGLContext(EGLNativeWindowType hWnd, EGLDisplay* eglDisplay, EGLContext* eglContext,
+ EGLSurface* eglSurface, EGLint attribList[])
+{
+ EGLint numConfigs;
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLDisplay display;
+ EGLContext context;
+ EGLSurface surface;
+ EGLConfig config;
+ EGLint contextAttribs[] =
+ { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
+
+ // Get Display
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY)
+ {
+ return EGL_FALSE;
+ }
+
+ // Initialize EGL
+ if (!eglInitialize(display, &majorVersion, &minorVersion))
+ {
+ return EGL_FALSE;
+ }
+
+ // Get configs
+ if (!eglGetConfigs(display, NULL, 0, &numConfigs))
+ {
+ return EGL_FALSE;
+ }
+
+ // Choose config
+ if (!eglChooseConfig(display, attribList, &config, 1, &numConfigs))
+ {
+ return EGL_FALSE;
+ }
+
+ // Create a surface
+ surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) hWnd, NULL);
+ if (surface == EGL_NO_SURFACE)
+ {
+ return EGL_FALSE;
+ }
+
+ // Create a GL context
+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ if (context == EGL_NO_CONTEXT)
+ {
+ return EGL_FALSE;
+ }
+
+ // Make the context current
+ if (!eglMakeCurrent(display, surface, surface, context))
+ {
+ return EGL_FALSE;
+ }
+
+ *eglDisplay = display;
+ *eglSurface = surface;
+ *eglContext = context;
+ return EGL_TRUE;
+}
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+///
+// esInitContext()
+//
+// Initialize ES utility context. This must be called before calling any other
+// functions.
+//
+void ESUTIL_API esInitContext(ESContext *esContext)
+{
+ if (esContext != NULL)
+ {
+ memset(esContext, 0, sizeof(ESContext));
+ }
+}
+
+///
+// esCreateWindow()
+//
+// title - name for title bar of window
+// width - width of window to create
+// height - height of window to create
+// flags - bitwise or of window creation flags
+// ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha
+// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
+// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
+// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
+//
+GLboolean ESUTIL_API esCreateWindow(ESContext *esContext, const char* title, GLint width, GLint height, GLuint flags)
+{
+ if (esContext == NULL)
+ {
+ return GL_FALSE;
+ }
+
+ // hard-coded to fullscreen
+ esContext->width = -1;
+ esContext->height = -1;
+
+ if (!CreateWindow(esContext, title, flags))
+ {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+///
+// esMainLoop()
+//
+// Start the main loop for the OpenGL ES application
+//
+void ESUTIL_API esMainLoop(ESContext *esContext)
+{
+ MainLoop(esContext);
+}
+
+///
+// esRegisterDrawFunc()
+//
+void ESUTIL_API esRegisterDrawFunc(ESContext *esContext, void(ESCALLBACK *drawFunc)(ESContext*))
+{
+ esContext->drawFunc = (void*) drawFunc;
+}
+
+
+///
+// esRegisterUpdateFunc()
+//
+void ESUTIL_API esRegisterUpdateFunc(ESContext *esContext, void(ESCALLBACK *updateFunc)(ESContext*, float))
+{
+ esContext->updateFunc = (void*) updateFunc;
+}
+
+
+///
+// esRegisterKeyFunc()
+//
+void ESUTIL_API esRegisterKeyFunc(ESContext *esContext, void(ESCALLBACK *keyFunc)(ESContext*, unsigned char, int, int))
+{
+ esContext->keyFunc = (void*) keyFunc;
+}
+
+
+///
+// esLogMessage()
+//
+// Log an error message to the debug output for the platform
+//
+void ESUTIL_API esLogMessage(const char *formatStr, ...)
+{
+ va_list params;
+ char buf[BUFSIZ];
+
+ va_start ( params, formatStr );
+ //vsprintf_s ( buf, sizeof(buf), formatStr, params );
+
+ printf("%s", buf);
+
+ va_end ( params );
+}
+
+
+///
+// esLoadTGA()
+//
+// Loads a 24-bit TGA image from a file
+//
+char* ESUTIL_API esLoadTGA(char *fileName, int *width, int *height)
+{
+ char *buffer;
+
+ if (LoadTGA(fileName, &buffer, width, height))
+ {
+ return buffer;
+ }
+
+ return NULL;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esUtil.h b/OpenGLES2-ProgrammingGuide/Common/src/esUtil.h
new file mode 100644
index 0000000..6c5bc4c
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esUtil.h
@@ -0,0 +1,286 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esUtil.h
+//
+// A utility library for OpenGL ES. This library provides a
+// basic common framework for the example applications in the
+// OpenGL ES 2.0 Programming Guide.
+//
+#ifndef ESUTIL_H
+#define ESUTIL_H
+
+///
+// Includes
+//
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+
+extern "C" {
+#endif
+
+
+///
+// Macros
+//
+#define ESUTIL_API //__cdecl
+#define ESCALLBACK //__cdecl
+
+
+/// esCreateWindow flag - RGB color buffer
+#define ES_WINDOW_RGB 0
+/// esCreateWindow flag - ALPHA color buffer
+#define ES_WINDOW_ALPHA 1
+/// esCreateWindow flag - depth buffer
+#define ES_WINDOW_DEPTH 2
+/// esCreateWindow flag - stencil buffer
+#define ES_WINDOW_STENCIL 4
+/// esCreateWindow flat - multi-sample buffer
+#define ES_WINDOW_MULTISAMPLE 8
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+///
+// Types
+//
+
+typedef struct
+{
+ GLfloat m[4][4];
+} ESMatrix;
+
+typedef struct
+{
+ /// Put your user data here...
+ void* userData;
+
+ /// Window width
+ GLint width;
+
+ /// Window height
+ GLint height;
+
+ /// Window handle
+ EGLNativeWindowType screen_win;
+
+ /// Window handle
+ EGLNativeWindowType screen_context;
+
+ /// EGL display
+ EGLDisplay eglDisplay;
+
+ /// EGL context
+ EGLContext eglContext;
+
+ /// EGL surface
+ EGLSurface eglSurface;
+
+ /// Callbacks
+ void (ESCALLBACK *drawFunc) ( void* );
+ void (ESCALLBACK *keyFunc) ( void*, unsigned char, int, int );
+ void (ESCALLBACK *updateFunc) ( void*, float deltaTime );
+} ESContext;
+
+
+///
+// Public Functions
+//
+
+//
+///
+/// \brief Initialize ES framework context. This must be called before calling any other functions.
+/// \param esContext Application context
+//
+void ESUTIL_API esInitContext ( ESContext *esContext );
+
+//
+/// \brief Create a window with the specified parameters
+/// \param esContext Application context
+/// \param title Name for title bar of window
+/// \param width Width in pixels of window to create
+/// \param height Height in pixels of window to create
+/// \param flags Bitfield for the window creation flags
+/// ES_WINDOW_RGB - specifies that the color buffer should have R,G,B channels
+/// ES_WINDOW_ALPHA - specifies that the color buffer should have alpha
+/// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
+/// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
+/// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
+/// \return GL_TRUE if window creation is succesful, GL_FALSE otherwise
+GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, const char *title, GLint width, GLint height, GLuint flags );
+
+//
+/// \brief Start the main loop for the OpenGL ES application
+/// \param esContext Application context
+//
+void ESUTIL_API esMainLoop ( ESContext *esContext );
+
+//
+/// \brief Register a draw callback function to be used to render each frame
+/// \param esContext Application context
+/// \param drawFunc Draw callback function that will be used to render the scene
+//
+void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) ( ESContext* ) );
+
+//
+/// \brief Register an update callback function to be used to update on each time step
+/// \param esContext Application context
+/// \param updateFunc Update callback function that will be used to render the scene
+//
+void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) );
+
+//
+/// \brief Register an keyboard input processing callback function
+/// \param esContext Application context
+/// \param keyFunc Key callback function for application processing of keyboard input
+//
+void ESUTIL_API esRegisterKeyFunc ( ESContext *esContext,
+ void (ESCALLBACK *drawFunc) ( ESContext*, unsigned char, int, int ) );
+//
+/// \brief Log a message to the debug output for the platform
+/// \param formatStr Format string for error log.
+//
+void ESUTIL_API esLogMessage ( const char *formatStr, ... );
+
+//
+///
+/// \brief Load a shader, check for compile errors, print error messages to output log
+/// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
+/// \param shaderSrc Shader source string
+/// \return A new shader object on success, 0 on failure
+//
+GLuint ESUTIL_API esLoadShader ( GLenum type, const char *shaderSrc );
+
+//
+///
+/// \brief Load a vertex and fragment shader, create a program object, link program.
+/// Errors output to log.
+/// \param vertShaderSrc Vertex shader source code
+/// \param fragShaderSrc Fragment shader source code
+/// \return A new program object linked with the vertex/fragment shader pair, 0 on failure
+//
+GLuint ESUTIL_API esLoadProgram ( const char *vertShaderSrc, const char *fragShaderSrc );
+
+
+//
+/// \brief Generates geometry for a sphere. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLE_STRIP
+/// \param numSlices The number of slices in the sphere
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices );
+
+//
+/// \brief Generates geometry for a cube. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLES
+/// \param scale The size of the cube, use 1.0 for a unit cube.
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLES
+//
+int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices );
+
+//
+/// \brief Loads a 24-bit TGA image from a file
+/// \param fileName Name of the file on disk
+/// \param width Width of loaded image in pixels
+/// \param height Height of loaded image in pixels
+/// \return Pointer to loaded image. NULL on failure.
+//
+char* ESUTIL_API esLoadTGA ( char *fileName, int *width, int *height );
+
+
+//
+/// \brief multiply matrix specified by result with a scaling matrix and return new matrix in result
+/// \param result Specifies the input matrix. Scaled matrix is returned in result.
+/// \param sx, sy, sz Scale factors along the x, y and z axes respectively
+//
+void ESUTIL_API esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz);
+
+//
+/// \brief multiply matrix specified by result with a translation matrix and return new matrix in result
+/// \param result Specifies the input matrix. Translated matrix is returned in result.
+/// \param tx, ty, tz Scale factors along the x, y and z axes respectively
+//
+void ESUTIL_API esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz);
+
+//
+/// \brief multiply matrix specified by result with a rotation matrix and return new matrix in result
+/// \param result Specifies the input matrix. Rotated matrix is returned in result.
+/// \param angle Specifies the angle of rotation, in degrees.
+/// \param x, y, z Specify the x, y and z coordinates of a vector, respectively
+//
+void ESUTIL_API esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+
+//
+// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param left, right Coordinates for the left and right vertical clipping planes
+/// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
+/// \param nearZ, farZ Distances to the near and far depth clipping planes. Both distances must be positive.
+//
+void ESUTIL_API esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
+
+//
+/// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param fovy Field of view y angle in degrees
+/// \param aspect Aspect ratio of screen
+/// \param nearZ Near plane distance
+/// \param farZ Far plane distance
+//
+void ESUTIL_API esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ);
+
+//
+/// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param left, right Coordinates for the left and right vertical clipping planes
+/// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
+/// \param nearZ, farZ Distances to the near and far depth clipping planes. These values are negative if plane is behind the viewer
+//
+void ESUTIL_API esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
+
+//
+/// \brief perform the following operation - result matrix = srcA matrix * srcB matrix
+/// \param result Returns multiplied matrix
+/// \param srcA, srcB Input matrices to be multiplied
+//
+void ESUTIL_API esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB);
+
+//
+//// \brief return an indentity matrix
+//// \param result returns identity matrix
+//
+void ESUTIL_API esMatrixLoadIdentity(ESMatrix *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ESUTIL_H
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esUtil_TGA.c b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_TGA.c
new file mode 100644
index 0000000..01d9979
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_TGA.c
@@ -0,0 +1,128 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esUtil_TGA.c
+//
+// This file contains the QNX implementation of a TGA image loader
+
+#include
+#include
+
+#include "esUtil.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+///
+// LoadTGA()
+//
+int LoadTGA(const char *fileName, char **buffer, int *width, int *height)
+{
+ char path[255];
+ strcpy(path, "./app/native/");
+ strcat(path, fileName);
+
+ FILE* file = fopen(path, "rb");
+ if (!file)
+ {
+ return FALSE;
+ }
+
+ // Read the image header
+ unsigned char header[12];
+ fread(header, sizeof(unsigned char), 12, file);
+
+ // Make sure this is a type 2 image
+ if (header[2] != 2)
+ {
+ // Unsupported tga image type in file
+ fclose(file);
+ return FALSE;
+ }
+
+ // Make sure there is no color map in this image
+ if (header[1] != 0)
+ {
+ // Unsupported color map
+ fclose(file);
+ return FALSE;
+ }
+
+ // Read width and height fields for the image
+ short s;
+ fread(&s, sizeof(short), 1, file);
+ *width = s;
+ fread(&s, sizeof(short), 1, file);
+ *height = s;
+
+ // Read in the bits per pixel format for this image (only support 24 and 32)
+ unsigned char bpp;
+ fread(&bpp, sizeof(unsigned char), 1, file);
+ if (bpp != 24 && bpp != 32)
+ {
+ fclose(file);
+ return FALSE;
+ }
+
+ // Calculate the actual number of color components and the texture data size
+ int colorComponents = bpp / 8;
+ int size = (*width) * (*height) * colorComponents;
+
+ // Read past the image descriptor byte
+ fseek(file, 1, SEEK_CUR);
+
+ // Read past the image identification field, in case it exists
+ if (header[0] > 0)
+ {
+ fseek(file, header[0], SEEK_CUR);
+ }
+
+ // Allocate space for the pixels in this image
+ char* data = malloc(size);
+
+ // Read in the texture data
+ fread(data, 1, size, file);
+
+ // Done reading in TGA file
+ fclose(file);
+
+ // Swap the first and third bytes - R (red) and B (blue) - to convert the image to RGB(A) format
+ unsigned char temp;
+ int i;
+ for (i = 0; i < size; i += colorComponents)
+ {
+ temp = data[i];
+ data[i] = data[i+2];
+ data[i+2] = temp;
+ }
+
+ if (colorComponents == 3)
+ {
+ *buffer = data;
+ }
+ else if (colorComponents == 4)
+ {
+ // Convert RGBA to RGB
+ int pixelCount = (*width) * (*height);
+ *buffer = malloc(pixelCount * 3);
+ for (i = 0; i < pixelCount; ++i)
+ {
+ (*buffer)[i * 3] = data[i * 4];
+ (*buffer)[i * 3 + 1] = data[i * 4 + 1];
+ (*buffer)[i * 3 + 2] = data[i * 4 + 2];
+ }
+ free(data);
+ }
+
+ return TRUE;
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.c b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.c
new file mode 100644
index 0000000..0c10cc8
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.c
@@ -0,0 +1,417 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esUtil_qnx.c
+//
+// This file contains the QNX implementation of the windowing functions.
+//
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "esUtil.h"
+#include "esUtil_qnx.h"
+
+#define WINDOW_VSYNC 1
+
+//////////////////////////////////////////////////////////////////
+//
+// Globals
+//
+
+// QNX global data
+struct
+{
+ screen_context_t screenContext;
+ screen_window_t screenWindow;
+ screen_event_t screenEvent;
+ int screenWindowSize[2];
+ const char* glExtensions;
+}__qnx;
+
+// Time global variables
+struct
+{
+ int elapsed;
+ int last;
+ int start;
+ int total;
+}__time;
+
+//////////////////////////////////////////////////////////////////
+//
+// Private Functions
+//
+//
+static EGLenum checkErrorEGL(const char* msg)
+{
+ static const char* errmsg[] =
+ {
+ "EGL function succeeded",
+ "EGL is not initialized, or could not be initialized, for the specified display",
+ "EGL cannot access a requested resource",
+ "EGL failed to allocate resources for the requested operation",
+ "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
+ "EGLConfig argument does not name a valid EGLConfig",
+ "EGLContext argument does not name a valid EGLContext",
+ "EGL current surface of the calling thread is no longer valid",
+ "EGLDisplay argument does not name a valid EGLDisplay",
+ "EGL arguments are inconsistent",
+ "EGLNativePixmapType argument does not refer to a valid native pixmap",
+ "EGLNativeWindowType argument does not refer to a valid native window",
+ "EGL one or more argument values are invalid",
+ "EGLSurface argument does not name a valid surface configured for rendering",
+ "EGL power management event has occurred",
+ };
+ EGLenum error = eglGetError();
+ fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
+ return error;
+}
+
+// Creates QNX window and initializes EGL stuff
+static GLboolean qnxCreate(ESContext *esContext, GLuint flags)
+{
+ int rc = 0;
+ int screenFormat = SCREEN_FORMAT_RGBA8888;
+ int screenUsage = SCREEN_USAGE_OPENGL_ES2;
+ int screenSwapInterval = 1;
+ int screenTransparency = SCREEN_TRANSPARENCY_NONE;
+ EGLConfig __eglConfig = 0;
+
+ // hard-coded to (0,0)
+ int windowPosition[] = { 0, 0 };
+
+ EGLint eglConfigCount;
+
+ // hard-coded to 32-bit/OpenGL ES 2.0
+ const EGLint eglConfigAttrs[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
+ EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 24 : EGL_DONT_CARE,
+ EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
+ EGL_NONE
+ };
+
+ const EGLint eglContextAttrs[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ const EGLint eglSurfaceAttrs[] =
+ {
+ EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
+ EGL_NONE
+ };
+
+ // Create the screen context
+ rc = screen_create_context(&__qnx.screenContext, 0);
+ if (rc)
+ {
+ perror("screen_create_context");
+ return GL_FALSE;
+ }
+
+ // Create the screen window
+ rc = screen_create_window(&__qnx.screenWindow, __qnx.screenContext);
+ if (rc)
+ {
+ perror("screen_create_window");
+ return GL_FALSE;
+ }
+
+ // Set/Get any window prooperties.
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
+ return GL_FALSE;
+ }
+
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_USAGE, &screenUsage);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
+ return GL_FALSE;
+ }
+
+ if (esContext->width > 0 && esContext->height > 0)
+ {
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_SIZE, __qnx.screenWindowSize);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_SIZE)");
+ return GL_FALSE;
+ }
+ }
+ else
+ {
+ rc = screen_get_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_SIZE, __qnx.screenWindowSize);
+ if (rc)
+ {
+ perror("screen_get_window_property_iv(SCREEN_PROPERTY_SIZE)");
+ return GL_FALSE;
+ }
+ }
+
+ if (windowPosition[0] != 0 || windowPosition[1] != 0)
+ {
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_POSITION, windowPosition);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_POSITION)");
+ return GL_FALSE;
+ }
+ }
+
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_TRANSPARENCY, &screenTransparency);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_TRANSPARENCY)");
+ return GL_FALSE;
+ }
+
+ rc = screen_set_window_property_iv(__qnx.screenWindow, SCREEN_PROPERTY_SWAP_INTERVAL, &screenSwapInterval);
+ if (rc)
+ {
+ perror("screen_set_window_property_iv(SCREEN_PROPERTY_SWAP_INTERVAL)");
+ return GL_FALSE;
+ }
+
+ // Double buffered.
+ rc = screen_create_window_buffers(__qnx.screenWindow, 2);
+ if (rc)
+ {
+ perror("screen_create_window_buffers");
+ return GL_FALSE;
+ }
+
+ // Create screen event object
+ rc = screen_create_event(&__qnx.screenEvent);
+ if (rc)
+ {
+ perror("screen_create_event");
+ return GL_FALSE;
+ }
+
+ // Get the EGL display and initialize
+ esContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (esContext->eglDisplay == EGL_NO_DISPLAY)
+ {
+ perror("eglGetDisplay");
+ return GL_FALSE;
+ }
+ if (eglInitialize(esContext->eglDisplay, NULL, NULL) != EGL_TRUE)
+ {
+ perror("eglInitialize");
+ return GL_FALSE;
+ }
+
+ if (eglChooseConfig(esContext->eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0)
+ {
+ checkErrorEGL("eglChooseConfig");
+ return GL_FALSE;
+ }
+
+ esContext->eglContext = eglCreateContext(esContext->eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs);
+ if (esContext->eglContext == EGL_NO_CONTEXT)
+ {
+ checkErrorEGL("eglCreateContext");
+ return GL_FALSE;
+ }
+
+ esContext->eglSurface = eglCreateWindowSurface(esContext->eglDisplay, __eglConfig, __qnx.screenWindow, eglSurfaceAttrs);
+ if (esContext->eglSurface == EGL_NO_SURFACE)
+ {
+ checkErrorEGL("eglCreateWindowSurface");
+ return GL_FALSE;
+ }
+
+ if (eglMakeCurrent(esContext->eglDisplay, esContext->eglSurface, esContext->eglSurface, esContext->eglContext) != EGL_TRUE)
+ {
+ checkErrorEGL("eglMakeCurrent");
+ return GL_FALSE;
+ }
+
+ // Use vsync
+ if (WINDOW_VSYNC)
+ eglSwapInterval(esContext->eglDisplay, 1);
+
+ // Initialize OpenGL ES extensions
+ __qnx.glExtensions = (const char*)glGetString(GL_EXTENSIONS);
+ if (strstr(__qnx.glExtensions, "GL_OES_vertex_array_object") || strstr(__qnx.glExtensions, "GL_ARB_vertex_array_object"))
+ {
+ //glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
+ //glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glBindVertexArrayOES");
+ //glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
+ //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
+ }
+ return GL_TRUE;
+}
+
+static void handleScreenEvent(bps_event_t *event)
+{
+ screen_event_t screen_event = screen_event_get_event(event);
+
+ int screen_val;
+ screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
+
+ switch (screen_val)
+ {
+ case SCREEN_EVENT_MTOUCH_TOUCH:
+ case SCREEN_EVENT_MTOUCH_MOVE:
+ case SCREEN_EVENT_MTOUCH_RELEASE:
+ break;
+ }
+}
+
+static void handleNavigatorEvent(bps_event_t *event)
+{
+ switch (bps_event_get_code(event))
+ {
+ case NAVIGATOR_SWIPE_DOWN:
+ break;
+ case NAVIGATOR_EXIT:
+ break;
+ }
+}
+
+static void handle_events()
+{
+ int screen_domain = screen_get_domain();
+ int navigator_domain = navigator_get_domain();
+
+ int rc;
+
+ //Request and process available BPS events
+ for (;;)
+ {
+ bps_event_t *event = NULL;
+ rc = bps_get_event(&event, 0);
+ assert(rc == BPS_SUCCESS);
+
+ if (event)
+ {
+ int domain = bps_event_get_domain(event);
+
+ if (domain == screen_domain)
+ {
+ handleScreenEvent(event);
+ }
+ else if (domain == navigator_domain)
+ {
+ handleNavigatorEvent(event);
+ }
+ }
+ else
+ {
+ //No more events in the queue
+ break;
+ }
+ }
+}
+
+static void terminateGraphics(ESContext *esContext)
+{
+ //Typical egl cleanup
+ eglMakeCurrent(esContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(esContext->eglDisplay, esContext->eglSurface);
+ screen_destroy_window(esContext->screen_win);
+ eglDestroyContext(esContext->eglDisplay, esContext->eglContext);
+ eglTerminate(esContext->eglDisplay);
+ eglReleaseThread();
+}
+
+static long initTime()
+{
+ struct timespec n;
+ clock_gettime(CLOCK_REALTIME, &n);
+ return __time.start = __time.last = n.tv_sec * 1000 + n.tv_nsec / 1000000;
+}
+
+static long getElapsedTime()
+{
+ struct timespec n;
+ clock_gettime(CLOCK_REALTIME, &n);
+ long nowt = n.tv_sec * 1000 + n.tv_nsec / 1000000;
+
+ __time.elapsed = nowt - __time.last;
+ __time.last = nowt;
+
+ __time.total += __time.elapsed;
+ return __time.elapsed;
+}
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+///
+// CreateWindow()
+//
+// Create the window
+//
+GLboolean CreateWindow(ESContext *esContext, const char *title, GLuint flags)
+{
+ qnxCreate(esContext, flags);
+ bps_initialize();
+ screen_request_events(__qnx.screenContext);
+
+ initTime();
+
+ // Query the width and height
+ eglQuerySurface(esContext->eglDisplay, esContext->eglSurface, EGL_WIDTH, &esContext->width);
+ eglQuerySurface(esContext->eglDisplay, esContext->eglSurface, EGL_HEIGHT, &esContext->height);
+
+ return GL_TRUE;
+}
+
+///
+// MainLoop()
+//
+// Start the main loop
+//
+void MainLoop(ESContext *esContext)
+{
+ for (;;)
+ {
+ handle_events();
+ // Call update function if registered
+ if (esContext->updateFunc != NULL)
+ esContext->updateFunc(esContext, getElapsedTime() / 1000.0f);
+ if (esContext && esContext->drawFunc)
+ esContext->drawFunc(esContext);
+ }
+
+ screen_stop_events((screen_context_t) esContext->screen_context);
+
+ terminateGraphics(esContext);
+
+ bps_shutdown();
+
+ screen_destroy_context((screen_context_t) esContext->screen_context);
+}
diff --git a/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.h b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.h
new file mode 100644
index 0000000..a2b3244
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/Common/src/esUtil_qnx.h
@@ -0,0 +1,56 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+// Additional contributions copyright (c) 2011 Research In Motion Limited
+
+// esUtil_qnx.h
+//
+// API-neutral interface for creating windows. Implementation needs to be provided per-platform.
+
+#ifndef ESUTIL_QNX_H_
+#define ESUTIL_QNX_H_
+
+///
+// Includes
+//
+
+#ifdef __cplusplus
+
+extern "C" {
+#endif
+
+///
+// Public Functions
+//
+
+///
+// WinCreate()
+//
+// Create window
+//
+GLboolean CreateWindow ( ESContext *esContext, const char *title, GLuint flags);
+
+///
+// WinLoop()
+//
+// Start main loop
+//
+void MainLoop ( ESContext *esContext );
+
+///
+// LoadTGA()
+//
+// TGA loader QNX implementation
+//
+int LoadTGA(const char *fileName, char **buffer, int *width, int *height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/OpenGLES2-ProgrammingGuide/README b/OpenGLES2-ProgrammingGuide/README
new file mode 100644
index 0000000..3475da2
--- /dev/null
+++ b/OpenGLES2-ProgrammingGuide/README
@@ -0,0 +1,55 @@
+Installing the BlackBerry Native SDK for Tablet OS
+--------------------------------------------------
+
+In order to run the code samples, you will need to download
+The BlackBerry Native SDK for Tablet OS:
+
+https://bdsc.webapps.blackberry.com/native/download
+
+
+Configuring the Native SDK
+--------------------------
+
+Instructions on how to configure the Native SDK and setup the signing keys can be found here:
+
+https://bdsc.webapps.blackberry.com/native/documentation/getting_started.html
+
+
+Importing the projects into the workspace
+-----------------------------------------
+
+ * Set the workspace to the base BlackBerry directory.
+ * Import the projects into the workspace:
+ * File > Import... > Existing Projects into Workspace
+ * Next
+ * Browse...
+ * Ok (The workspace directory is selected by default)
+ * Finish (All projects should be selected by default)
+ * Build All
+
+
+Running on the PlayBook
+-----------------------
+
+Before attempting to deploy to the device, make sure that you have followed
+the instructions up to "Configure your environment for development and deployment".
+
+https://bdsc.webapps.blackberry.com/native/documentation/getting_started.html
+
+Enable Development Mode on your PlayBook
+ * Go to Options by swiping down from the top of the homescreen
+ * Security > Development Mode
+ * Turn on Development mode
+ * Note the Development Address
+
+In the IDE, Create a BlackBerry Tablet OS Target
+ * Connect your PlayBook via USB to your desktop and make sure that development mode is enabled
+ * New > Other... > BlackBerry Tablet OS Target > Next
+ * Enter your "Development Address" (probably 169.254.0.1)
+ * Enter your PlayBook's password
+ * Finish
+ * A BlackBerry Tablet OS Target will appear under the Project Explorer. The name will be the same as the development address.
+
+Launching an application
+ * Create a launch configuration for each sample.
+ * https://bdsc.webapps.blackberry.com/native/documentation/com.qnx.doc.native_sdk.quickstart/topic/prepare_launch.html