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    GLuint vertexObject, indexObject;
36 
37 } UserData;
38 
39 ///
40 // Create a simple 2x2 texture image with four different colors
41 //
CreateSimpleTexture2D()42 GLuint CreateSimpleTexture2D( )
43 {
44    // Texture object handle
45    GLuint textureId;
46 
47    // 2x2 Image, 3 bytes per pixel (R, G, B)
48    GLubyte pixels[4 * 3] =
49    {
50       255,   0,   0, // Red
51         0, 255,   0, // Green
52         0,   0, 255, // Blue
53       255, 255,   0  // Yellow
54    };
55 
56    // Use tightly packed data
57    glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
58 
59    // Generate a texture object
60    glGenTextures ( 1, &textureId );
61 
62    // Bind the texture object
63    glBindTexture ( GL_TEXTURE_2D, textureId );
64 
65    // Load the texture
66    glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
67 
68    // Set the filtering mode
69    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
70    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
71 
72    return textureId;
73 
74 }
75 
76 
77 ///
78 // Initialize the shader and program object
79 //
Init(ESContext * esContext)80 int Init ( ESContext *esContext )
81 {
82    esContext->userData = malloc(sizeof(UserData));
83    UserData *userData = esContext->userData;
84    GLbyte vShaderStr[] =
85       "attribute vec4 a_position;   \n"
86       "attribute vec2 a_texCoord;   \n"
87       "varying vec2 v_texCoord;     \n"
88       "void main()                  \n"
89       "{                            \n"
90       "   gl_Position = a_position; \n"
91       "   v_texCoord = a_texCoord;  \n"
92       "}                            \n";
93 
94    GLbyte fShaderStr[] =
95       "precision mediump float;                            \n"
96       "varying vec2 v_texCoord;                            \n"
97       "uniform sampler2D s_texture;                        \n"
98       "void main()                                         \n"
99       "{                                                   \n"
100       "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
101       "}                                                   \n";
102 
103    // Load the shaders and get a linked program object
104    userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
105 
106    // Get the attribute locations
107    userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
108    userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
109 
110    // Get the sampler location
111    userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
112 
113    // Load the texture
114    userData->textureId = CreateSimpleTexture2D ();
115 
116    // Setup the vertex data
117    GLfloat vVertices[] = { -0.5,  0.5, 0.0,  // Position 0
118                             0.0,  0.0,       // TexCoord 0
119                            -0.5, -0.5, 0.0,  // Position 1
120                             0.0,  1.0,       // TexCoord 1
121                             0.5, -0.5, 0.0,  // Position 2
122                             1.0,  1.0,       // TexCoord 2
123                             0.5,  0.5, 0.0,  // Position 3
124                             1.0,  0.0        // TexCoord 3
125                          };
126    GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
127 
128    glGenBuffers(1, &userData->vertexObject);
129    glBindBuffer(GL_ARRAY_BUFFER, userData->vertexObject );
130    glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW );
131 
132    glGenBuffers(1, &userData->indexObject);
133    glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->indexObject );
134    glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW );
135 
136    glClearColor ( 0.0f, 0.0f, 0.0f, 1.0f );
137    return GL_TRUE;
138 }
139 
140 ///
141 // Draw a triangle using the shader pair created in Init()
142 //
Draw(ESContext * esContext)143 void Draw ( ESContext *esContext )
144 {
145    // Set the viewport
146    glViewport ( 0, 0, esContext->width, esContext->height );
147 
148    // Clear the color buffer
149    glClear ( GL_COLOR_BUFFER_BIT );
150 
151    UserData *userData = esContext->userData;
152 
153    // Use the program object
154    glUseProgram ( userData->programObject );
155 
156    // Load the vertex position
157    glBindBuffer (GL_ARRAY_BUFFER, userData->vertexObject );
158    glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
159                            GL_FALSE, 5 * 4, 0 );
160    // Load the texture coordinate
161    glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
162                            GL_FALSE, 5 * 4,
163                            3 * 4 );
164 
165    glEnableVertexAttribArray ( userData->positionLoc );
166    glEnableVertexAttribArray ( userData->texCoordLoc );
167 
168    // Bind the texture
169    glActiveTexture ( GL_TEXTURE0 );
170    glBindTexture ( GL_TEXTURE_2D, userData->textureId );
171 
172    // Set the sampler texture unit to 0
173    glUniform1i ( userData->samplerLoc, 0 );
174 
175    glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->indexObject );
176    glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 );
177 }
178 
179 ///
180 // Cleanup
181 //
ShutDown(ESContext * esContext)182 void ShutDown ( ESContext *esContext )
183 {
184    UserData *userData = esContext->userData;
185 
186    // Delete texture object
187    glDeleteTextures ( 1, &userData->textureId );
188 
189    // Delete program object
190    glDeleteProgram ( userData->programObject );
191 
192    free(esContext->userData);
193 }
194 
main(int argc,char * argv[])195 int main ( int argc, char *argv[] )
196 {
197    ESContext esContext;
198    UserData  userData;
199 
200    esInitContext ( &esContext );
201    esContext.userData = &userData;
202 
203    esCreateWindow ( &esContext, "Simple Texture 2D", 320, 240, ES_WINDOW_RGB );
204 
205    if ( !Init ( &esContext ) )
206       return 0;
207 
208    esRegisterDrawFunc ( &esContext, Draw );
209 
210    esMainLoop ( &esContext );
211 
212    ShutDown ( &esContext );
213 }
214