Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: third_party/gles_book_examples/Chapter_9/MipMap2D/MipMap2D.c

Issue 543002: Renamed gles_book_examples to gles2_book to make it shorter and more correct.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 // MipMap2D.c
12 //
13 // This is a simple example that demonstrates generating a mipmap chain
14 // and rendering with it
15 //
16 #include <stdlib.h>
17 #include "esUtil.h"
18
19 typedef struct
20 {
21 // Handle to a program object
22 GLuint programObject;
23
24 // Attribute locations
25 GLint positionLoc;
26 GLint texCoordLoc;
27
28 // Sampler location
29 GLint samplerLoc;
30
31 // Offset location
32 GLint offsetLoc;
33
34 // Texture handle
35 GLuint textureId;
36
37 } UserData;
38
39
40 ///
41 // From an RGB8 source image, generate the next level mipmap
42 //
43 GLboolean GenMipMap2D( GLubyte *src, GLubyte **dst, int srcWidth, int srcHeight, int *dstWidth, int *dstHeight )
44 {
45 int x,
46 y;
47 int texelSize = 3;
48
49 *dstWidth = srcWidth / 2;
50 if ( *dstWidth <= 0 )
51 *dstWidth = 1;
52
53 *dstHeight = srcHeight / 2;
54 if ( *dstHeight <= 0 )
55 *dstHeight = 1;
56
57 *dst = malloc ( sizeof(GLubyte) * texelSize * (*dstWidth) * (*dstHeight) );
58 if ( *dst == NULL )
59 return GL_FALSE;
60
61 for ( y = 0; y < *dstHeight; y++ )
62 {
63 for( x = 0; x < *dstWidth; x++ )
64 {
65 int srcIndex[4];
66 float r = 0.0f,
67 g = 0.0f,
68 b = 0.0f;
69 int sample;
70
71 // Compute the offsets for 2x2 grid of pixels in previous
72 // image to perform box filter
73 srcIndex[0] =
74 (((y * 2) * srcWidth) + (x * 2)) * texelSize;
75 srcIndex[1] =
76 (((y * 2) * srcWidth) + (x * 2 + 1)) * texelSize;
77 srcIndex[2] =
78 ((((y * 2) + 1) * srcWidth) + (x * 2)) * texelSize;
79 srcIndex[3] =
80 ((((y * 2) + 1) * srcWidth) + (x * 2 + 1)) * texelSize;
81
82 // Sum all pixels
83 for ( sample = 0; sample < 4; sample++ )
84 {
85 r += src[srcIndex[sample]];
86 g += src[srcIndex[sample] + 1];
87 b += src[srcIndex[sample] + 2];
88 }
89
90 // Average results
91 r /= 4.0;
92 g /= 4.0;
93 b /= 4.0;
94
95 // Store resulting pixels
96 (*dst)[ ( y * (*dstWidth) + x ) * texelSize ] = (GLubyte)( r );
97 (*dst)[ ( y * (*dstWidth) + x ) * texelSize + 1] = (GLubyte)( g );
98 (*dst)[ ( y * (*dstWidth) + x ) * texelSize + 2] = (GLubyte)( b );
99 }
100 }
101
102 return GL_TRUE;
103 }
104
105 ///
106 // Generate an RGB8 checkerboard image
107 //
108 GLubyte* GenCheckImage( int width, int height, int checkSize )
109 {
110 int x,
111 y;
112 GLubyte *pixels = malloc( width * height * 3 );
113
114 if ( pixels == NULL )
115 return NULL;
116
117 for ( y = 0; y < height; y++ )
118 for ( x = 0; x < width; x++ )
119 {
120 GLubyte rColor = 0;
121 GLubyte bColor = 0;
122
123 if ( ( x / checkSize ) % 2 == 0 )
124 {
125 rColor = 255 * ( ( y / checkSize ) % 2 );
126 bColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
127 }
128 else
129 {
130 bColor = 255 * ( ( y / checkSize ) % 2 );
131 rColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
132 }
133
134 pixels[(y * height + x) * 3] = rColor;
135 pixels[(y * height + x) * 3 + 1] = 0;
136 pixels[(y * height + x) * 3 + 2] = bColor;
137 }
138
139 return pixels;
140 }
141
142 ///
143 // Create a mipmapped 2D texture image
144 //
145 GLuint CreateMipMappedTexture2D( )
146 {
147 // Texture object handle
148 GLuint textureId;
149 int width = 256,
150 height = 256;
151 int level;
152 GLubyte *pixels;
153 GLubyte *prevImage;
154 GLubyte *newImage;
155
156 pixels = GenCheckImage( width, height, 8 );
157 if ( pixels == NULL )
158 return 0;
159
160 // Generate a texture object
161 glGenTextures ( 1, &textureId );
162
163 // Bind the texture object
164 glBindTexture ( GL_TEXTURE_2D, textureId );
165
166 // Load mipmap level 0
167 glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height,
168 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
169
170 level = 1;
171 prevImage = &pixels[0];
172
173 while ( width > 1 && height > 1 )
174 {
175 int newWidth,
176 newHeight;
177
178 // Generate the next mipmap level
179 GenMipMap2D( prevImage, &newImage, width, height,
180 &newWidth, &newHeight );
181
182 // Load the mipmap level
183 glTexImage2D( GL_TEXTURE_2D, level, GL_RGB,
184 newWidth, newHeight, 0, GL_RGB,
185 GL_UNSIGNED_BYTE, newImage );
186
187 // Free the previous image
188 free ( prevImage );
189
190 // Set the previous image for the next iteration
191 prevImage = newImage;
192 level++;
193
194 // Half the width and height
195 width = newWidth;
196 height = newHeight;
197 }
198
199 free ( newImage );
200
201 // Set the filtering mode
202 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEA REST );
203 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
204
205 return textureId;
206
207 }
208
209
210 ///
211 // Initialize the shader and program object
212 //
213 int Init ( ESContext *esContext )
214 {
215 UserData *userData = esContext->userData;
216 GLbyte vShaderStr[] =
217 "uniform float u_offset; \n"
218 "attribute vec4 a_position; \n"
219 "attribute vec2 a_texCoord; \n"
220 "varying vec2 v_texCoord; \n"
221 "void main() \n"
222 "{ \n"
223 " gl_Position = a_position; \n"
224 " gl_Position.x += u_offset;\n"
225 " v_texCoord = a_texCoord; \n"
226 "} \n";
227
228 GLbyte fShaderStr[] =
229 "precision mediump float; \n"
230 "varying vec2 v_texCoord; \n"
231 "uniform sampler2D s_texture; \n"
232 "void main() \n"
233 "{ \n"
234 " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
235 "} \n";
236
237 // Load the shaders and get a linked program object
238 userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
239
240 // Get the attribute locations
241 userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_pos ition" );
242 userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_tex Coord" );
243
244 // Get the sampler location
245 userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_tex ture" );
246
247 // Get the offset location
248 userData->offsetLoc = glGetUniformLocation( userData->programObject, "u_offse t" );
249
250 // Load the texture
251 userData->textureId = CreateMipMappedTexture2D ();
252
253 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
254 return TRUE;
255 }
256
257 ///
258 // Draw a triangle using the shader pair created in Init()
259 //
260 void Draw ( ESContext *esContext )
261 {
262 UserData *userData = esContext->userData;
263 GLfloat vVertices[] = { -0.5f, 0.5f, 0.0f, 1.5f, // Position 0
264 0.0f, 0.0f, // TexCoord 0
265 -0.5f, -0.5f, 0.0f, 0.75f, // Position 1
266 0.0f, 1.0f, // TexCoord 1
267 0.5f, -0.5f, 0.0f, 0.75f, // Position 2
268 1.0f, 1.0f, // TexCoord 2
269 0.5f, 0.5f, 0.0f, 1.5f, // Position 3
270 1.0f, 0.0f // TexCoord 3
271 };
272 GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
273
274 // Set the viewport
275 glViewport ( 0, 0, esContext->width, esContext->height );
276
277 // Clear the color buffer
278 glClear ( GL_COLOR_BUFFER_BIT );
279
280 // Use the program object
281 glUseProgram ( userData->programObject );
282
283 // Load the vertex position
284 glVertexAttribPointer ( userData->positionLoc, 4, GL_FLOAT,
285 GL_FALSE, 6 * sizeof(GLfloat), vVertices );
286 // Load the texture coordinate
287 glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
288 GL_FALSE, 6 * sizeof(GLfloat), &vVertices[4] );
289
290 glEnableVertexAttribArray ( userData->positionLoc );
291 glEnableVertexAttribArray ( userData->texCoordLoc );
292
293 // Bind the texture
294 glActiveTexture ( GL_TEXTURE0 );
295 glBindTexture ( GL_TEXTURE_2D, userData->textureId );
296
297 // Set the sampler texture unit to 0
298 glUniform1i ( userData->samplerLoc, 0 );
299
300 // Draw quad with nearest sampling
301 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
302 glUniform1f ( userData->offsetLoc, -0.6f );
303 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
304
305 // Draw quad with trilinear filtering
306 glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINE AR );
307 glUniform1f ( userData->offsetLoc, 0.6f );
308 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
309
310 eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
311 }
312
313 ///
314 // Cleanup
315 //
316 void ShutDown ( ESContext *esContext )
317 {
318 UserData *userData = esContext->userData;
319
320 // Delete texture object
321 glDeleteTextures ( 1, &userData->textureId );
322
323 // Delete program object
324 glDeleteProgram ( userData->programObject );
325 }
326
327
328 int main ( int argc, char *argv[] )
329 {
330 ESContext esContext;
331 UserData userData;
332
333 esInitContext ( &esContext );
334 esContext.userData = &userData;
335
336 esCreateWindow ( &esContext, "MipMap 2D", 320, 240, ES_WINDOW_RGB );
337
338 if ( !Init ( &esContext ) )
339 return 0;
340
341 esRegisterDrawFunc ( &esContext, Draw );
342
343 esMainLoop ( &esContext );
344
345 ShutDown ( &esContext );
346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698