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_TextureCubemap.c
12 //
13 // This is a simple example that draws a sphere with a cubemap image applied.
14 //
15 #include <stdlib.h>
16 #include "esUtil.h"
17
18 typedef struct
19 {
20 // Handle to a program object
21 GLuint programObject;
22
23 // Attribute locations
24 GLint positionLoc;
25 GLint normalLoc;
26
27 // Sampler location
28 GLint samplerLoc;
29
30 // Texture handle
31 GLuint textureId;
32
33 // Vertex data
34 int numIndices;
35 GLfloat *vertices;
36 GLfloat *normals;
37 GLuint *indices;
38
39 } UserData;
40
41 ///
42 // Create a simple cubemap with a 1x1 face with a different
43 // color for each face
CreateSimpleTextureCubemap()44 GLuint CreateSimpleTextureCubemap( )
45 {
46 GLuint textureId;
47 // Six 1x1 RGB faces
48 GLubyte cubePixels[6][3] =
49 {
50 // Face 0 - Red
51 255, 0, 0,
52 // Face 1 - Green,
53 0, 255, 0,
54 // Face 3 - Blue
55 0, 0, 255,
56 // Face 4 - Yellow
57 255, 255, 0,
58 // Face 5 - Purple
59 255, 0, 255,
60 // Face 6 - White
61 255, 255, 255
62 };
63
64 // Generate a texture object
65 glGenTextures ( 1, &textureId );
66
67 // Bind the texture object
68 glBindTexture ( GL_TEXTURE_CUBE_MAP, textureId );
69
70 // Load the cube face - Positive X
71 glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, 1, 1, 0,
72 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[0] );
73
74 // Load the cube face - Negative X
75 glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, 1, 1, 0,
76 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[1] );
77
78 // Load the cube face - Positive Y
79 glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, 1, 1, 0,
80 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[2] );
81
82 // Load the cube face - Negative Y
83 glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, 1, 1, 0,
84 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[3] );
85
86 // Load the cube face - Positive Z
87 glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, 1, 1, 0,
88 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[4] );
89
90 // Load the cube face - Negative Z
91 glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, 1, 1, 0,
92 GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[5] );
93
94 // Set the filtering mode
95 glTexParameteri ( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
96 glTexParameteri ( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
97
98 return textureId;
99
100 }
101
102 #include <stdio.h>
103 ///
104 // Initialize the shader and program object
105 //
Init(ESContext * esContext)106 int Init ( ESContext *esContext )
107 {
108 //esContext->userData = malloc(sizeof(UserData));
109 UserData *userData = esContext->userData;
110 GLbyte vShaderStr[] =
111 "attribute vec4 a_position; \n"
112 "attribute vec3 a_normal; \n"
113 "varying vec3 v_normal; \n"
114 "void main() \n"
115 "{ \n"
116 " gl_Position = a_position; \n"
117 " v_normal = a_normal; \n"
118 "} \n";
119
120 GLbyte fShaderStr[] =
121 "precision mediump float; \n"
122 "varying vec3 v_normal; \n"
123 "uniform samplerCube s_texture; \n"
124 "void main() \n"
125 "{ \n"
126 " gl_FragColor = textureCube( s_texture, v_normal );\n"
127 "} \n";
128
129 // Load the shaders and get a linked program object
130 userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
131
132 // Get the attribute locations
133 userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
134 userData->normalLoc = glGetAttribLocation ( userData->programObject, "a_normal" );
135
136 // Get the sampler locations
137 userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
138
139 // Load the texture
140 userData->textureId = CreateSimpleTextureCubemap ();
141
142 // Generate the vertex data
143 userData->numIndices = esGenSphere ( 20, 0.75f, &userData->vertices, &userData->normals,
144 NULL, &userData->indices );
145
146 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
147 return GL_TRUE;
148 }
149
150 ///
151 // Draw a triangle using the shader pair created in Init()
152 //
Draw(ESContext * esContext)153 void Draw ( ESContext *esContext )
154 {
155 UserData *userData = esContext->userData;
156
157 // Set the viewport
158 glViewport ( 0, 0, esContext->width, esContext->height );
159
160 // Clear the color buffer
161 glClear ( GL_COLOR_BUFFER_BIT );
162
163 glCullFace ( GL_BACK );
164 glEnable ( GL_CULL_FACE );
165
166 // Use the program object
167 glUseProgram ( userData->programObject );
168
169 // Load the vertex position
170 glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
171 GL_FALSE, 0, userData->vertices );
172 // Load the normal
173 glVertexAttribPointer ( userData->normalLoc, 3, GL_FLOAT,
174 GL_FALSE, 0, userData->normals );
175
176 glEnableVertexAttribArray ( userData->positionLoc );
177 glEnableVertexAttribArray ( userData->normalLoc );
178
179 // Bind the texture
180 glActiveTexture ( GL_TEXTURE0 );
181 glBindTexture ( GL_TEXTURE_CUBE_MAP, userData->textureId );
182
183 // Set the sampler texture unit to 0
184 glUniform1i ( userData->samplerLoc, 0 );
185
186 glDrawElements ( GL_TRIANGLES, userData->numIndices,
187 GL_UNSIGNED_INT, userData->indices );
188 }
189
190 ///
191 // Cleanup
192 //
ShutDown(ESContext * esContext)193 void ShutDown ( ESContext *esContext )
194 {
195 UserData *userData = esContext->userData;
196
197 // Delete texture object
198 glDeleteTextures ( 1, &userData->textureId );
199
200 // Delete program object
201 glDeleteProgram ( userData->programObject );
202
203 free ( userData->vertices );
204 free ( userData->normals );
205
206 //free ( esContext->userData);
207 }
208
main(int argc,char * argv[])209 int main ( int argc, char *argv[] )
210 {
211 ESContext esContext;
212 UserData userData;
213
214 esInitContext ( &esContext );
215 esContext.userData = &userData;
216
217 esCreateWindow ( &esContext, "Simple Texture Cubemap", 320, 240, ES_WINDOW_RGB );
218
219 if ( !Init ( &esContext ) )
220 return 0;
221
222 esRegisterDrawFunc ( &esContext, Draw );
223
224 esMainLoop ( &esContext );
225
226 ShutDown ( &esContext );
227 }
228