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