test/testgl.c
changeset 234 1af4be6a73cd
parent 233 5b42a7f5fab3
child 243 cf4944faad96
     1.1 --- a/test/testgl.c	Tue Nov 06 00:15:24 2001 +0000
     1.2 +++ b/test/testgl.c	Tue Nov 06 01:48:36 2001 +0000
     1.3 @@ -6,12 +6,22 @@
     1.4  #include "SDL.h"
     1.5  
     1.6  #ifdef HAVE_OPENGL
     1.7 +
     1.8  #include "SDL_opengl.h"
     1.9  
    1.10 +/* Undefine this if you want a flat cube instead of a rainbow cube */
    1.11  #define SHADED_CUBE
    1.12  
    1.13 +/* Define this to be the name of the logo image to use with -logo */
    1.14 +#define LOGO_FILE	"icon.bmp"
    1.15 +
    1.16 +/* The SDL_OPENGLBLIT interface is deprecated.
    1.17 +   The code is still available for benchmark purposes though.
    1.18 +*/
    1.19  static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
    1.20  
    1.21 +/**********************************************************************/
    1.22 +
    1.23  void HotKey_ToggleFullScreen(void)
    1.24  {
    1.25  	SDL_Surface *screen;
    1.26 @@ -134,10 +144,174 @@
    1.27  	glPopAttrib();
    1.28  }
    1.29  
    1.30 -void DrawSDLLogo(void)
    1.31 +/* Quick utility function for texture creation */
    1.32 +static int power_of_two(int input)
    1.33 +{
    1.34 +	int value = 1;
    1.35 +
    1.36 +	while ( value < input ) {
    1.37 +		value <<= 1;
    1.38 +	}
    1.39 +	return value;
    1.40 +}
    1.41 +
    1.42 +GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
    1.43 +{
    1.44 +	GLuint texture;
    1.45 +	int w, h;
    1.46 +	SDL_Surface *image;
    1.47 +	SDL_Rect area;
    1.48 +	Uint32 saved_flags;
    1.49 +	Uint8  saved_alpha;
    1.50 +
    1.51 +	/* Use the surface width and height expanded to powers of 2 */
    1.52 +	w = power_of_two(surface->w);
    1.53 +	h = power_of_two(surface->h);
    1.54 +	texcoord[0] = 0.0f;			/* Min X */
    1.55 +	texcoord[1] = 0.0f;			/* Min Y */
    1.56 +	texcoord[2] = (GLfloat)surface->w / w;	/* Max X */
    1.57 +	texcoord[3] = (GLfloat)surface->h / h;	/* Max Y */
    1.58 +
    1.59 +	image = SDL_CreateRGBSurface(
    1.60 +			SDL_SWSURFACE,
    1.61 +			w, h,
    1.62 +			32,
    1.63 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
    1.64 +			0x000000FF, 
    1.65 +			0x0000FF00, 
    1.66 +			0x00FF0000, 
    1.67 +			0xFF000000
    1.68 +#else
    1.69 +			0xFF000000,
    1.70 +			0x00FF0000, 
    1.71 +			0x0000FF00, 
    1.72 +			0x000000FF
    1.73 +#endif
    1.74 +		       );
    1.75 +	if ( image == NULL ) {
    1.76 +		return 0;
    1.77 +	}
    1.78 +
    1.79 +	/* Save the alpha blending attributes */
    1.80 +	saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
    1.81 +	saved_alpha = surface->format->alpha;
    1.82 +	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
    1.83 +		SDL_SetAlpha(surface, 0, 0);
    1.84 +	}
    1.85 +
    1.86 +	/* Copy the surface into the GL texture image */
    1.87 +	area.x = 0;
    1.88 +	area.y = 0;
    1.89 +	area.w = surface->w;
    1.90 +	area.h = surface->h;
    1.91 +	SDL_BlitSurface(surface, &area, image, &area);
    1.92 +
    1.93 +	/* Restore the alpha blending attributes */
    1.94 +	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
    1.95 +		SDL_SetAlpha(surface, saved_flags, saved_alpha);
    1.96 +	}
    1.97 +
    1.98 +	/* Create an OpenGL texture for the image */
    1.99 +	glGenTextures(1, &texture);
   1.100 +	glBindTexture(GL_TEXTURE_2D, texture);
   1.101 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1.102 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1.103 +	glTexImage2D(GL_TEXTURE_2D,
   1.104 +		     0,
   1.105 +		     GL_RGBA,
   1.106 +		     w, h,
   1.107 +		     0,
   1.108 +		     GL_RGBA,
   1.109 +		     GL_UNSIGNED_BYTE,
   1.110 +		     image->pixels);
   1.111 +	SDL_FreeSurface(image); /* No longer needed */
   1.112 +
   1.113 +	return texture;
   1.114 +}
   1.115 +
   1.116 +void DrawLogoTexture(void)
   1.117 +{
   1.118 +	static GLuint texture;
   1.119 +	static GLfloat texMinX, texMinY;
   1.120 +	static GLfloat texMaxX, texMaxY;
   1.121 +	static int x = 0;
   1.122 +	static int y = 0;
   1.123 +	static int w, h;
   1.124 +	static int delta_x = 1;
   1.125 +	static int delta_y = 1;
   1.126 +	static Uint32 last_moved = 0;
   1.127 +
   1.128 +	SDL_Surface *screen = SDL_GetVideoSurface();
   1.129 +
   1.130 +	if ( ! texture ) {
   1.131 +		SDL_Surface *image;
   1.132 +		GLfloat texcoord[4];
   1.133 +
   1.134 +		/* Load the image (could use SDL_image library here) */
   1.135 +		image = SDL_LoadBMP(LOGO_FILE);
   1.136 +		if ( image == NULL ) {
   1.137 +			return;
   1.138 +		}
   1.139 +		w = image->w;
   1.140 +		h = image->h;
   1.141 +
   1.142 +		/* Convert the image into an OpenGL texture */
   1.143 +		texture = SDL_GL_LoadTexture(image, texcoord);
   1.144 +
   1.145 +		/* Make texture coordinates easy to understand */
   1.146 +		texMinX = texcoord[0];
   1.147 +		texMinY = texcoord[1];
   1.148 +		texMaxX = texcoord[2];
   1.149 +		texMaxY = texcoord[3];
   1.150 +
   1.151 +		/* We don't need the original image anymore */
   1.152 +		SDL_FreeSurface(image);
   1.153 +
   1.154 +		/* Make sure that the texture conversion is okay */
   1.155 +		if ( ! texture ) {
   1.156 +			return;
   1.157 +		}
   1.158 +	}
   1.159 +
   1.160 +	/* Move the image around */
   1.161 +	x += delta_x;
   1.162 +	if ( x < 0 ) {
   1.163 +		x = 0;
   1.164 +		delta_x = -delta_x;
   1.165 +	} else
   1.166 +	if ( (x+w) > screen->w ) {
   1.167 +		x = screen->w-w;
   1.168 +		delta_x = -delta_x;
   1.169 +	}
   1.170 +	y += delta_y;
   1.171 +	if ( y < 0 ) {
   1.172 +		y = 0;
   1.173 +		delta_y = -delta_y;
   1.174 +	} else
   1.175 +	if ( (y+h) > screen->h ) {
   1.176 +		y = screen->h-h;
   1.177 +		delta_y = -delta_y;
   1.178 +	}
   1.179 +
   1.180 +	/* Show the image on the screen */
   1.181 +	SDL_GL_Enter2DMode();
   1.182 +	glBindTexture(GL_TEXTURE_2D, texture);
   1.183 +	glBegin(GL_TRIANGLE_STRIP);
   1.184 +	glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
   1.185 +	glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
   1.186 +	glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
   1.187 +	glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
   1.188 +	glEnd();
   1.189 +	SDL_GL_Leave2DMode();
   1.190 +}
   1.191 +
   1.192 +/* This code is deprecated, but available for speed comparisons */
   1.193 +void DrawLogoBlit(void)
   1.194  {
   1.195  	static SDL_Surface *image = NULL;
   1.196  	static GLuint texture;
   1.197 +	static GLfloat texMinX, texMinY;
   1.198 +	static GLfloat texMaxX, texMaxY;
   1.199  	static int x = 0;
   1.200  	static int y = 0;
   1.201  	static int w, h;
   1.202 @@ -146,114 +320,72 @@
   1.203  	static Uint32 last_moved = 0;
   1.204  
   1.205  	SDL_Rect dst;
   1.206 -	SDL_Surface *screen;
   1.207 +	SDL_Surface *screen = SDL_GetVideoSurface();
   1.208  
   1.209  	if ( image == NULL ) {
   1.210  		SDL_Surface *temp;
   1.211  
   1.212 -		temp = SDL_LoadBMP("icon.bmp");
   1.213 +		/* Load the image (could use SDL_image library here) */
   1.214 +		temp = SDL_LoadBMP(LOGO_FILE);
   1.215  		if ( temp == NULL ) {
   1.216  			return;
   1.217  		}
   1.218 +		w = temp->w;
   1.219 +		h = temp->h;
   1.220 +
   1.221 +		/* Convert the image into the screen format */
   1.222  		image = SDL_CreateRGBSurface(
   1.223  				SDL_SWSURFACE,
   1.224 -				temp->w, temp->h,
   1.225 -				32,
   1.226 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
   1.227 -				0x000000FF, 
   1.228 -				0x0000FF00, 
   1.229 -				0x00FF0000, 
   1.230 -				0xFF000000
   1.231 -#else
   1.232 -				0xFF000000,
   1.233 -				0x00FF0000, 
   1.234 -				0x0000FF00, 
   1.235 -				0x000000FF
   1.236 -#endif
   1.237 - 			       );
   1.238 -		if ( image != NULL ) {
   1.239 +				w, h,
   1.240 +				screen->format->BitsPerPixel,
   1.241 +				screen->format->Rmask,
   1.242 +				screen->format->Gmask,
   1.243 +				screen->format->Bmask,
   1.244 +				screen->format->Amask);
   1.245 +		if ( image ) {
   1.246  			SDL_BlitSurface(temp, NULL, image, NULL);
   1.247  		}
   1.248  		SDL_FreeSurface(temp);
   1.249 -		if ( image == NULL ) {
   1.250 +
   1.251 +		/* Make sure that the texture conversion is okay */
   1.252 +		if ( ! image ) {
   1.253  			return;
   1.254  		}
   1.255 -		w = image->w;
   1.256 -		h = image->h;
   1.257 -
   1.258 -		/* Create an OpenGL texture for the image */
   1.259 -		if ( ! USE_DEPRECATED_OPENGLBLIT ) {
   1.260 -			glGenTextures(1, &texture);
   1.261 -			glBindTexture(GL_TEXTURE_2D, texture);
   1.262 -			glTexParameteri(GL_TEXTURE_2D,
   1.263 -			                GL_TEXTURE_MAG_FILTER,
   1.264 -			                GL_NEAREST);
   1.265 -			glTexParameteri(GL_TEXTURE_2D,
   1.266 -			                GL_TEXTURE_MIN_FILTER,
   1.267 -			                GL_NEAREST);
   1.268 -			glTexImage2D(GL_TEXTURE_2D,
   1.269 -			             0,
   1.270 -			             GL_RGBA,
   1.271 -			             w, h,
   1.272 -			             0,
   1.273 -			             GL_RGBA,
   1.274 -			             GL_UNSIGNED_BYTE,
   1.275 -			             image->pixels);
   1.276 -			SDL_FreeSurface(image); /* No longer needed */
   1.277 -		}
   1.278  	}
   1.279  
   1.280 -	screen = SDL_GetVideoSurface();
   1.281 -
   1.282 -	/* Show the image on the screen */
   1.283 -	dst.x = x;
   1.284 -	dst.y = y;
   1.285 -	dst.w = w;
   1.286 -	dst.h = h;
   1.287 -
   1.288 -	/* Move it around
   1.289 +	/* Move the image around
   1.290             Note that we do not clear the old position.  This is because we
   1.291             perform a glClear() which clears the framebuffer and then only
   1.292             update the new area.
   1.293             Note that you can also achieve interesting effects by modifying
   1.294             the screen surface alpha channel.  It's set to 255 by default..
   1.295           */
   1.296 -	if ( (SDL_GetTicks() - last_moved) > 100 ) {
   1.297 -		x += delta_x;
   1.298 -		if ( x < 0 ) {
   1.299 -			x = 0;
   1.300 -			delta_x = -delta_x;
   1.301 -		} else
   1.302 -		if ( (x+w) > screen->w ) {
   1.303 -			x = screen->w-w;
   1.304 -			delta_x = -delta_x;
   1.305 -		}
   1.306 -		y += delta_y;
   1.307 -		if ( y < 0 ) {
   1.308 -			y = 0;
   1.309 -			delta_y = -delta_y;
   1.310 -		} else
   1.311 -		if ( (y+h) > screen->h ) {
   1.312 -			y = screen->h-h;
   1.313 -			delta_y = -delta_y;
   1.314 -		}
   1.315 -		if ( USE_DEPRECATED_OPENGLBLIT ) {
   1.316 -			SDL_BlitSurface(image, NULL, screen, &dst);
   1.317 -		} else {
   1.318 -			SDL_GL_Enter2DMode();
   1.319 -			glBindTexture(GL_TEXTURE_2D, texture);
   1.320 -			glBegin(GL_TRIANGLE_STRIP);
   1.321 -			glTexCoord2f(0.0, 0.0); glVertex2i(x,   y  );
   1.322 -			glTexCoord2f(1.0, 0.0); glVertex2i(x+w, y  );
   1.323 -			glTexCoord2f(0.0, 1.0); glVertex2i(x,   y+h);
   1.324 -			glTexCoord2f(1.0, 1.0); glVertex2i(x+w, y+h);
   1.325 -			glEnd();
   1.326 -			SDL_GL_Leave2DMode();
   1.327 -		}
   1.328 +	x += delta_x;
   1.329 +	if ( x < 0 ) {
   1.330 +		x = 0;
   1.331 +		delta_x = -delta_x;
   1.332 +	} else
   1.333 +	if ( (x+w) > screen->w ) {
   1.334 +		x = screen->w-w;
   1.335 +		delta_x = -delta_x;
   1.336  	}
   1.337 -	if ( USE_DEPRECATED_OPENGLBLIT ) {
   1.338 -		SDL_UpdateRects(screen, 1, &dst);
   1.339 +	y += delta_y;
   1.340 +	if ( y < 0 ) {
   1.341 +		y = 0;
   1.342 +		delta_y = -delta_y;
   1.343 +	} else
   1.344 +	if ( (y+h) > screen->h ) {
   1.345 +		y = screen->h-h;
   1.346 +		delta_y = -delta_y;
   1.347  	}
   1.348 +	dst.x = x;
   1.349 +	dst.y = y;
   1.350 +	dst.w = w;
   1.351 +	dst.h = h;
   1.352 +	SDL_BlitSurface(image, NULL, screen, &dst);
   1.353 +
   1.354 +	/* Show the image on the screen */
   1.355 +	SDL_UpdateRects(screen, 1, &dst);
   1.356  }
   1.357  
   1.358  int RunGLTest( int argc, char* argv[],
   1.359 @@ -496,7 +628,11 @@
   1.360  
   1.361  		/* Draw 2D logo onto the 3D display */
   1.362  		if ( logo ) {
   1.363 -			DrawSDLLogo();
   1.364 +			if ( USE_DEPRECATED_OPENGLBLIT ) {
   1.365 +				DrawLogoBlit();
   1.366 +			} else {
   1.367 +				DrawLogoTexture();
   1.368 +			}
   1.369  		}
   1.370  
   1.371  		SDL_GL_SwapBuffers( );