2
// Book: OpenGL(R) ES 2.0 Programming Guide
3
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
5
// ISBN-13: 9780321502797
6
// Publisher: Addison-Wesley Professional
7
// URLs: http://safari.informit.com/9780321563835
8
// http://www.opengles-book.com
13
// This is an example that draws a quad with a basemap and
14
// lightmap to demonstrate multitexturing.
21
// Handle to a program object
24
// Attribute locations
36
GLuint vertexObject, indexObject;
42
// Load texture from disk
44
GLuint LoadTexture ( char *fileName )
48
char *buffer = esLoadTGA ( fileName, &width, &height );
53
esLogMessage ( "Error loading (%s) image.\n", fileName );
57
glGenTextures ( 1, &texId );
58
glBindTexture ( GL_TEXTURE_2D, texId );
60
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer );
61
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
62
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
63
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
64
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
74
// Initialize the shader and program object
76
int Init ( ESContext *esContext )
78
UserData *userData = esContext->userData;
80
"attribute vec4 a_position; \n"
81
"attribute vec2 a_texCoord; \n"
82
"varying vec2 v_texCoord; \n"
85
" gl_Position = a_position; \n"
86
" v_texCoord = a_texCoord; \n"
90
"precision mediump float; \n"
91
"varying vec2 v_texCoord; \n"
92
"uniform sampler2D s_baseMap; \n"
93
"uniform sampler2D s_lightMap; \n"
97
" vec4 lightColor; \n"
99
" baseColor = texture2D( s_baseMap, v_texCoord ); \n"
100
" lightColor = texture2D( s_lightMap, v_texCoord ); \n"
101
" gl_FragColor = baseColor * (lightColor + 0.25); \n"
104
// Load the shaders and get a linked program object
105
userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
107
// Get the attribute locations
108
userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
109
userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
111
// Get the sampler location
112
userData->baseMapLoc = glGetUniformLocation ( userData->programObject, "s_baseMap" );
113
userData->lightMapLoc = glGetUniformLocation ( userData->programObject, "s_lightMap" );
116
userData->baseMapTexId = LoadTexture ( "basemap.tga" );
117
userData->lightMapTexId = LoadTexture ( "lightmap.tga" );
119
if ( userData->baseMapTexId == 0 || userData->lightMapTexId == 0 )
122
GLfloat vVertices[] = { -0.5, 0.5, 0.0, // Position 0
123
0.0, 0.0, // TexCoord 0
124
-0.5, -0.5, 0.0, // Position 1
125
0.0, 1.0, // TexCoord 1
126
0.5, -0.5, 0.0, // Position 2
127
1.0, 1.0, // TexCoord 2
128
0.5, 0.5, 0.0, // Position 3
129
1.0, 0.0 // TexCoord 3
131
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
133
glGenBuffers(1, &userData->vertexObject);
134
glBindBuffer ( GL_ARRAY_BUFFER, userData->vertexObject );
135
glBufferData ( GL_ARRAY_BUFFER, 5 * 4 * 4, vVertices, GL_STATIC_DRAW );
137
glGenBuffers(1, &userData->indexObject);
138
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->indexObject );
139
glBufferData ( GL_ELEMENT_ARRAY_BUFFER, 6 * 2, indices, GL_STATIC_DRAW );
141
glClearColor ( 0.0, 0.0, 0.0, 1.0 );
147
// Draw a triangle using the shader pair created in Init()
149
void Draw ( ESContext *esContext )
151
UserData *userData = esContext->userData;
154
glViewport ( 0, 0, esContext->width, esContext->height );
156
// Clear the color buffer
157
glClear ( GL_COLOR_BUFFER_BIT );
159
// Use the program object
160
glUseProgram ( userData->programObject );
162
// Load the vertex position
163
glBindBuffer ( GL_ARRAY_BUFFER, userData->vertexObject );
164
glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
165
GL_FALSE, 5 * sizeof(GLfloat), 0 );
166
// Load the texture coordinate
167
glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
168
GL_FALSE, 5 * sizeof(GLfloat), 3 * sizeof(GLfloat) );
170
glEnableVertexAttribArray ( userData->positionLoc );
171
glEnableVertexAttribArray ( userData->texCoordLoc );
174
glActiveTexture ( GL_TEXTURE0 );
175
glBindTexture ( GL_TEXTURE_2D, userData->baseMapTexId );
177
// Set the base map sampler to texture unit to 0
178
glUniform1i ( userData->baseMapLoc, 0 );
180
// Bind the light map
181
glActiveTexture ( GL_TEXTURE1 );
182
glBindTexture ( GL_TEXTURE_2D, userData->lightMapTexId );
184
// Set the light map sampler to texture unit 1
185
glUniform1i ( userData->lightMapLoc, 1 );
187
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->indexObject );
188
glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 );
190
eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
196
void ShutDown ( ESContext *esContext )
198
UserData *userData = esContext->userData;
200
// Delete texture object
201
glDeleteTextures ( 1, &userData->baseMapTexId );
202
glDeleteTextures ( 1, &userData->lightMapTexId );
204
// Delete program object
205
glDeleteProgram ( userData->programObject );
209
int main ( int argc, char *argv[] )
214
esInitContext ( &esContext );
215
esContext.userData = &userData;
217
esCreateWindow ( &esContext, "MultiTexture", 320, 240, ES_WINDOW_RGB );
219
if ( !Init ( &esContext ) )
222
esRegisterDrawFunc ( &esContext, Draw );
224
esMainLoop ( &esContext );
226
ShutDown ( &esContext );