Mercurial > sdl-ios-xcode
comparison test/testgl.c @ 234:1af4be6a73cd
Modified the logo texture load to accept any width/height image
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 06 Nov 2001 01:48:36 +0000 |
parents | 5b42a7f5fab3 |
children | cf4944faad96 |
comparison
equal
deleted
inserted
replaced
233:5b42a7f5fab3 | 234:1af4be6a73cd |
---|---|
4 #include <math.h> | 4 #include <math.h> |
5 | 5 |
6 #include "SDL.h" | 6 #include "SDL.h" |
7 | 7 |
8 #ifdef HAVE_OPENGL | 8 #ifdef HAVE_OPENGL |
9 | |
9 #include "SDL_opengl.h" | 10 #include "SDL_opengl.h" |
10 | 11 |
12 /* Undefine this if you want a flat cube instead of a rainbow cube */ | |
11 #define SHADED_CUBE | 13 #define SHADED_CUBE |
12 | 14 |
15 /* Define this to be the name of the logo image to use with -logo */ | |
16 #define LOGO_FILE "icon.bmp" | |
17 | |
18 /* The SDL_OPENGLBLIT interface is deprecated. | |
19 The code is still available for benchmark purposes though. | |
20 */ | |
13 static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE; | 21 static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE; |
22 | |
23 /**********************************************************************/ | |
14 | 24 |
15 void HotKey_ToggleFullScreen(void) | 25 void HotKey_ToggleFullScreen(void) |
16 { | 26 { |
17 SDL_Surface *screen; | 27 SDL_Surface *screen; |
18 | 28 |
132 glPopMatrix(); | 142 glPopMatrix(); |
133 | 143 |
134 glPopAttrib(); | 144 glPopAttrib(); |
135 } | 145 } |
136 | 146 |
137 void DrawSDLLogo(void) | 147 /* Quick utility function for texture creation */ |
138 { | 148 static int power_of_two(int input) |
139 static SDL_Surface *image = NULL; | 149 { |
150 int value = 1; | |
151 | |
152 while ( value < input ) { | |
153 value <<= 1; | |
154 } | |
155 return value; | |
156 } | |
157 | |
158 GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord) | |
159 { | |
160 GLuint texture; | |
161 int w, h; | |
162 SDL_Surface *image; | |
163 SDL_Rect area; | |
164 Uint32 saved_flags; | |
165 Uint8 saved_alpha; | |
166 | |
167 /* Use the surface width and height expanded to powers of 2 */ | |
168 w = power_of_two(surface->w); | |
169 h = power_of_two(surface->h); | |
170 texcoord[0] = 0.0f; /* Min X */ | |
171 texcoord[1] = 0.0f; /* Min Y */ | |
172 texcoord[2] = (GLfloat)surface->w / w; /* Max X */ | |
173 texcoord[3] = (GLfloat)surface->h / h; /* Max Y */ | |
174 | |
175 image = SDL_CreateRGBSurface( | |
176 SDL_SWSURFACE, | |
177 w, h, | |
178 32, | |
179 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ | |
180 0x000000FF, | |
181 0x0000FF00, | |
182 0x00FF0000, | |
183 0xFF000000 | |
184 #else | |
185 0xFF000000, | |
186 0x00FF0000, | |
187 0x0000FF00, | |
188 0x000000FF | |
189 #endif | |
190 ); | |
191 if ( image == NULL ) { | |
192 return 0; | |
193 } | |
194 | |
195 /* Save the alpha blending attributes */ | |
196 saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); | |
197 saved_alpha = surface->format->alpha; | |
198 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { | |
199 SDL_SetAlpha(surface, 0, 0); | |
200 } | |
201 | |
202 /* Copy the surface into the GL texture image */ | |
203 area.x = 0; | |
204 area.y = 0; | |
205 area.w = surface->w; | |
206 area.h = surface->h; | |
207 SDL_BlitSurface(surface, &area, image, &area); | |
208 | |
209 /* Restore the alpha blending attributes */ | |
210 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { | |
211 SDL_SetAlpha(surface, saved_flags, saved_alpha); | |
212 } | |
213 | |
214 /* Create an OpenGL texture for the image */ | |
215 glGenTextures(1, &texture); | |
216 glBindTexture(GL_TEXTURE_2D, texture); | |
217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
219 glTexImage2D(GL_TEXTURE_2D, | |
220 0, | |
221 GL_RGBA, | |
222 w, h, | |
223 0, | |
224 GL_RGBA, | |
225 GL_UNSIGNED_BYTE, | |
226 image->pixels); | |
227 SDL_FreeSurface(image); /* No longer needed */ | |
228 | |
229 return texture; | |
230 } | |
231 | |
232 void DrawLogoTexture(void) | |
233 { | |
140 static GLuint texture; | 234 static GLuint texture; |
235 static GLfloat texMinX, texMinY; | |
236 static GLfloat texMaxX, texMaxY; | |
141 static int x = 0; | 237 static int x = 0; |
142 static int y = 0; | 238 static int y = 0; |
143 static int w, h; | 239 static int w, h; |
144 static int delta_x = 1; | 240 static int delta_x = 1; |
145 static int delta_y = 1; | 241 static int delta_y = 1; |
146 static Uint32 last_moved = 0; | 242 static Uint32 last_moved = 0; |
147 | 243 |
244 SDL_Surface *screen = SDL_GetVideoSurface(); | |
245 | |
246 if ( ! texture ) { | |
247 SDL_Surface *image; | |
248 GLfloat texcoord[4]; | |
249 | |
250 /* Load the image (could use SDL_image library here) */ | |
251 image = SDL_LoadBMP(LOGO_FILE); | |
252 if ( image == NULL ) { | |
253 return; | |
254 } | |
255 w = image->w; | |
256 h = image->h; | |
257 | |
258 /* Convert the image into an OpenGL texture */ | |
259 texture = SDL_GL_LoadTexture(image, texcoord); | |
260 | |
261 /* Make texture coordinates easy to understand */ | |
262 texMinX = texcoord[0]; | |
263 texMinY = texcoord[1]; | |
264 texMaxX = texcoord[2]; | |
265 texMaxY = texcoord[3]; | |
266 | |
267 /* We don't need the original image anymore */ | |
268 SDL_FreeSurface(image); | |
269 | |
270 /* Make sure that the texture conversion is okay */ | |
271 if ( ! texture ) { | |
272 return; | |
273 } | |
274 } | |
275 | |
276 /* Move the image around */ | |
277 x += delta_x; | |
278 if ( x < 0 ) { | |
279 x = 0; | |
280 delta_x = -delta_x; | |
281 } else | |
282 if ( (x+w) > screen->w ) { | |
283 x = screen->w-w; | |
284 delta_x = -delta_x; | |
285 } | |
286 y += delta_y; | |
287 if ( y < 0 ) { | |
288 y = 0; | |
289 delta_y = -delta_y; | |
290 } else | |
291 if ( (y+h) > screen->h ) { | |
292 y = screen->h-h; | |
293 delta_y = -delta_y; | |
294 } | |
295 | |
296 /* Show the image on the screen */ | |
297 SDL_GL_Enter2DMode(); | |
298 glBindTexture(GL_TEXTURE_2D, texture); | |
299 glBegin(GL_TRIANGLE_STRIP); | |
300 glTexCoord2f(texMinX, texMinY); glVertex2i(x, y ); | |
301 glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y ); | |
302 glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h); | |
303 glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h); | |
304 glEnd(); | |
305 SDL_GL_Leave2DMode(); | |
306 } | |
307 | |
308 /* This code is deprecated, but available for speed comparisons */ | |
309 void DrawLogoBlit(void) | |
310 { | |
311 static SDL_Surface *image = NULL; | |
312 static GLuint texture; | |
313 static GLfloat texMinX, texMinY; | |
314 static GLfloat texMaxX, texMaxY; | |
315 static int x = 0; | |
316 static int y = 0; | |
317 static int w, h; | |
318 static int delta_x = 1; | |
319 static int delta_y = 1; | |
320 static Uint32 last_moved = 0; | |
321 | |
148 SDL_Rect dst; | 322 SDL_Rect dst; |
149 SDL_Surface *screen; | 323 SDL_Surface *screen = SDL_GetVideoSurface(); |
150 | 324 |
151 if ( image == NULL ) { | 325 if ( image == NULL ) { |
152 SDL_Surface *temp; | 326 SDL_Surface *temp; |
153 | 327 |
154 temp = SDL_LoadBMP("icon.bmp"); | 328 /* Load the image (could use SDL_image library here) */ |
329 temp = SDL_LoadBMP(LOGO_FILE); | |
155 if ( temp == NULL ) { | 330 if ( temp == NULL ) { |
156 return; | 331 return; |
157 } | 332 } |
333 w = temp->w; | |
334 h = temp->h; | |
335 | |
336 /* Convert the image into the screen format */ | |
158 image = SDL_CreateRGBSurface( | 337 image = SDL_CreateRGBSurface( |
159 SDL_SWSURFACE, | 338 SDL_SWSURFACE, |
160 temp->w, temp->h, | 339 w, h, |
161 32, | 340 screen->format->BitsPerPixel, |
162 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ | 341 screen->format->Rmask, |
163 0x000000FF, | 342 screen->format->Gmask, |
164 0x0000FF00, | 343 screen->format->Bmask, |
165 0x00FF0000, | 344 screen->format->Amask); |
166 0xFF000000 | 345 if ( image ) { |
167 #else | |
168 0xFF000000, | |
169 0x00FF0000, | |
170 0x0000FF00, | |
171 0x000000FF | |
172 #endif | |
173 ); | |
174 if ( image != NULL ) { | |
175 SDL_BlitSurface(temp, NULL, image, NULL); | 346 SDL_BlitSurface(temp, NULL, image, NULL); |
176 } | 347 } |
177 SDL_FreeSurface(temp); | 348 SDL_FreeSurface(temp); |
178 if ( image == NULL ) { | 349 |
350 /* Make sure that the texture conversion is okay */ | |
351 if ( ! image ) { | |
179 return; | 352 return; |
180 } | 353 } |
181 w = image->w; | 354 } |
182 h = image->h; | 355 |
183 | 356 /* Move the image around |
184 /* Create an OpenGL texture for the image */ | |
185 if ( ! USE_DEPRECATED_OPENGLBLIT ) { | |
186 glGenTextures(1, &texture); | |
187 glBindTexture(GL_TEXTURE_2D, texture); | |
188 glTexParameteri(GL_TEXTURE_2D, | |
189 GL_TEXTURE_MAG_FILTER, | |
190 GL_NEAREST); | |
191 glTexParameteri(GL_TEXTURE_2D, | |
192 GL_TEXTURE_MIN_FILTER, | |
193 GL_NEAREST); | |
194 glTexImage2D(GL_TEXTURE_2D, | |
195 0, | |
196 GL_RGBA, | |
197 w, h, | |
198 0, | |
199 GL_RGBA, | |
200 GL_UNSIGNED_BYTE, | |
201 image->pixels); | |
202 SDL_FreeSurface(image); /* No longer needed */ | |
203 } | |
204 } | |
205 | |
206 screen = SDL_GetVideoSurface(); | |
207 | |
208 /* Show the image on the screen */ | |
209 dst.x = x; | |
210 dst.y = y; | |
211 dst.w = w; | |
212 dst.h = h; | |
213 | |
214 /* Move it around | |
215 Note that we do not clear the old position. This is because we | 357 Note that we do not clear the old position. This is because we |
216 perform a glClear() which clears the framebuffer and then only | 358 perform a glClear() which clears the framebuffer and then only |
217 update the new area. | 359 update the new area. |
218 Note that you can also achieve interesting effects by modifying | 360 Note that you can also achieve interesting effects by modifying |
219 the screen surface alpha channel. It's set to 255 by default.. | 361 the screen surface alpha channel. It's set to 255 by default.. |
220 */ | 362 */ |
221 if ( (SDL_GetTicks() - last_moved) > 100 ) { | 363 x += delta_x; |
222 x += delta_x; | 364 if ( x < 0 ) { |
223 if ( x < 0 ) { | 365 x = 0; |
224 x = 0; | 366 delta_x = -delta_x; |
225 delta_x = -delta_x; | 367 } else |
226 } else | 368 if ( (x+w) > screen->w ) { |
227 if ( (x+w) > screen->w ) { | 369 x = screen->w-w; |
228 x = screen->w-w; | 370 delta_x = -delta_x; |
229 delta_x = -delta_x; | 371 } |
230 } | 372 y += delta_y; |
231 y += delta_y; | 373 if ( y < 0 ) { |
232 if ( y < 0 ) { | 374 y = 0; |
233 y = 0; | 375 delta_y = -delta_y; |
234 delta_y = -delta_y; | 376 } else |
235 } else | 377 if ( (y+h) > screen->h ) { |
236 if ( (y+h) > screen->h ) { | 378 y = screen->h-h; |
237 y = screen->h-h; | 379 delta_y = -delta_y; |
238 delta_y = -delta_y; | 380 } |
239 } | 381 dst.x = x; |
240 if ( USE_DEPRECATED_OPENGLBLIT ) { | 382 dst.y = y; |
241 SDL_BlitSurface(image, NULL, screen, &dst); | 383 dst.w = w; |
242 } else { | 384 dst.h = h; |
243 SDL_GL_Enter2DMode(); | 385 SDL_BlitSurface(image, NULL, screen, &dst); |
244 glBindTexture(GL_TEXTURE_2D, texture); | 386 |
245 glBegin(GL_TRIANGLE_STRIP); | 387 /* Show the image on the screen */ |
246 glTexCoord2f(0.0, 0.0); glVertex2i(x, y ); | 388 SDL_UpdateRects(screen, 1, &dst); |
247 glTexCoord2f(1.0, 0.0); glVertex2i(x+w, y ); | |
248 glTexCoord2f(0.0, 1.0); glVertex2i(x, y+h); | |
249 glTexCoord2f(1.0, 1.0); glVertex2i(x+w, y+h); | |
250 glEnd(); | |
251 SDL_GL_Leave2DMode(); | |
252 } | |
253 } | |
254 if ( USE_DEPRECATED_OPENGLBLIT ) { | |
255 SDL_UpdateRects(screen, 1, &dst); | |
256 } | |
257 } | 389 } |
258 | 390 |
259 int RunGLTest( int argc, char* argv[], | 391 int RunGLTest( int argc, char* argv[], |
260 int logo, int slowly, int bpp, float gamma ) | 392 int logo, int slowly, int bpp, float gamma ) |
261 { | 393 { |
494 glMatrixMode(GL_MODELVIEW); | 626 glMatrixMode(GL_MODELVIEW); |
495 glRotatef(5.0, 1.0, 1.0, 1.0); | 627 glRotatef(5.0, 1.0, 1.0, 1.0); |
496 | 628 |
497 /* Draw 2D logo onto the 3D display */ | 629 /* Draw 2D logo onto the 3D display */ |
498 if ( logo ) { | 630 if ( logo ) { |
499 DrawSDLLogo(); | 631 if ( USE_DEPRECATED_OPENGLBLIT ) { |
632 DrawLogoBlit(); | |
633 } else { | |
634 DrawLogoTexture(); | |
635 } | |
500 } | 636 } |
501 | 637 |
502 SDL_GL_SwapBuffers( ); | 638 SDL_GL_SwapBuffers( ); |
503 | 639 |
504 /* Check for error conditions. */ | 640 /* Check for error conditions. */ |