1 // 2 // Book: OpenGL(R) ES 2.0 Programming Guide 3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner 4 // ISBN-10: 0321502795 5 // ISBN-13: 9780321502797 6 // Publisher: Addison-Wesley Professional 7 // URLs: http://safari.informit.com/9780321563835 8 // http://www.opengles-book.com 9 // 10 11 // Simple_Texture2D.c 12 // 13 // This is a simple example that draws a quad with a 2D 14 // texture image. The purpose of this example is to demonstrate 15 // the basics of 2D texturing 16 // 17 #include <stdlib.h> 18 #include "esUtil.h" 19 20 typedef struct 21 { 22 // Handle to a program object 23 GLuint programObject; 24 25 // Attribute locations 26 GLint positionLoc; 27 GLint texCoordLoc; 28 29 // Sampler location 30 GLint samplerLoc; 31 32 // Texture handle 33 GLuint textureId; 34 35 } UserData; 36 37 /// 38 // Create a simple 2x2 texture image with four different colors 39 // 40 GLuint CreateSimpleTexture2D( ) 41 { 42 // Texture object handle 43 GLuint textureId; 44 45 // 2x2 Image, 3 bytes per pixel (R, G, B) 46 GLubyte pixels[4 * 3] = 47 { 48 255, 0, 0, // Red 49 0, 255, 0, // Green 50 0, 0, 255, // Blue 51 255, 255, 0 // Yellow 52 }; 53 54 // Use tightly packed data 55 glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); 56 57 // Generate a texture object 58 glGenTextures ( 1, &textureId ); 59 60 // Bind the texture object 61 glBindTexture ( GL_TEXTURE_2D, textureId ); 62 63 // Load the texture 64 glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); 65 66 // Set the filtering mode 67 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 68 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 69 70 return textureId; 71 72 } 73 74 75 /// 76 // Initialize the shader and program object 77 // 78 int Init ( ESContext *esContext ) 79 { 80 UserData *userData = esContext->userData; 81 GLbyte vShaderStr[] = 82 "attribute vec4 a_position; \n" 83 "attribute vec2 a_texCoord; \n" 84 "varying vec2 v_texCoord; \n" 85 "void main() \n" 86 "{ \n" 87 " gl_Position = a_position; \n" 88 " v_texCoord = a_texCoord; \n" 89 "} \n"; 90 91 GLbyte fShaderStr[] = 92 "precision mediump float; \n" 93 "varying vec2 v_texCoord; \n" 94 "uniform sampler2D s_texture; \n" 95 "void main() \n" 96 "{ \n" 97 " gl_FragColor = texture2D( s_texture, v_texCoord );\n" 98 "} \n"; 99 100 // Load the shaders and get a linked program object 101 userData->programObject = esLoadProgram ( vShaderStr, fShaderStr ); 102 103 // Get the attribute locations 104 userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" ); 105 userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" ); 106 107 // Get the sampler location 108 userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" ); 109 110 // Load the texture 111 userData->textureId = CreateSimpleTexture2D (); 112 113 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); 114 return TRUE; 115 } 116 117 /// 118 // Draw a triangle using the shader pair created in Init() 119 // 120 void Draw ( ESContext *esContext ) 121 { 122 UserData *userData = esContext->userData; 123 GLfloat vVertices[] = { -0.5f, 0.5f, 0.0f, // Position 0 124 0.0f, 0.0f, // TexCoord 0 125 -0.5f, -0.5f, 0.0f, // Position 1 126 0.0f, 1.0f, // TexCoord 1 127 0.5f, -0.5f, 0.0f, // Position 2 128 1.0f, 1.0f, // TexCoord 2 129 0.5f, 0.5f, 0.0f, // Position 3 130 1.0f, 0.0f // TexCoord 3 131 }; 132 GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; 133 134 // Set the viewport 135 glViewport ( 0, 0, esContext->width, esContext->height ); 136 137 // Clear the color buffer 138 glClear ( GL_COLOR_BUFFER_BIT ); 139 140 // Use the program object 141 glUseProgram ( userData->programObject ); 142 143 // Load the vertex position 144 glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 145 GL_FALSE, 5 * sizeof(GLfloat), vVertices ); 146 // Load the texture coordinate 147 glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT, 148 GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] ); 149 150 glEnableVertexAttribArray ( userData->positionLoc ); 151 glEnableVertexAttribArray ( userData->texCoordLoc ); 152 153 // Bind the texture 154 glActiveTexture ( GL_TEXTURE0 ); 155 glBindTexture ( GL_TEXTURE_2D, userData->textureId ); 156 157 // Set the sampler texture unit to 0 158 glUniform1i ( userData->samplerLoc, 0 ); 159 160 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices ); 161 162 eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface ); 163 } 164 165 /// 166 // Cleanup 167 // 168 void ShutDown ( ESContext *esContext ) 169 { 170 UserData *userData = esContext->userData; 171 172 // Delete texture object 173 glDeleteTextures ( 1, &userData->textureId ); 174 175 // Delete program object 176 glDeleteProgram ( userData->programObject ); 177 } 178 179 180 int main ( int argc, char *argv[] ) 181 { 182 ESContext esContext; 183 UserData userData; 184 185 esInitContext ( &esContext ); 186 esContext.userData = &userData; 187 188 esCreateWindow ( &esContext, TEXT("Simple Texture 2D"), 320, 240, ES_WINDOW_RGB ); 189 190 if ( !Init ( &esContext ) ) 191 return 0; 192 193 esRegisterDrawFunc ( &esContext, Draw ); 194 195 esMainLoop ( &esContext ); 196 197 ShutDown ( &esContext ); 198 } 199