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