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