Skip to content

Commit

Permalink
Modified the logo texture load to accept any width/height image
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Nov 6, 2001
1 parent 9e44afe commit 8f09ff0
Showing 1 changed file with 222 additions and 86 deletions.
308 changes: 222 additions & 86 deletions test/testgl.c
Expand Up @@ -6,12 +6,22 @@
#include "SDL.h"

#ifdef HAVE_OPENGL

#include "SDL_opengl.h"

/* Undefine this if you want a flat cube instead of a rainbow cube */
#define SHADED_CUBE

/* Define this to be the name of the logo image to use with -logo */
#define LOGO_FILE "icon.bmp"

/* The SDL_OPENGLBLIT interface is deprecated.
The code is still available for benchmark purposes though.
*/
static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;

/**********************************************************************/

void HotKey_ToggleFullScreen(void)
{
SDL_Surface *screen;
Expand Down Expand Up @@ -134,10 +144,174 @@ void SDL_GL_Leave2DMode()
glPopAttrib();
}

void DrawSDLLogo(void)
/* Quick utility function for texture creation */
static int power_of_two(int input)
{
int value = 1;

while ( value < input ) {
value <<= 1;
}
return value;
}

GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
{
GLuint texture;
int w, h;
SDL_Surface *image;
SDL_Rect area;
Uint32 saved_flags;
Uint8 saved_alpha;

/* Use the surface width and height expanded to powers of 2 */
w = power_of_two(surface->w);
h = power_of_two(surface->h);
texcoord[0] = 0.0f; /* Min X */
texcoord[1] = 0.0f; /* Min Y */
texcoord[2] = (GLfloat)surface->w / w; /* Max X */
texcoord[3] = (GLfloat)surface->h / h; /* Max Y */

image = SDL_CreateRGBSurface(
SDL_SWSURFACE,
w, h,
32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000
#else
0xFF000000,
0x00FF0000,
0x0000FF00,
0x000000FF
#endif
);
if ( image == NULL ) {
return 0;
}

/* Save the alpha blending attributes */
saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
saved_alpha = surface->format->alpha;
if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
SDL_SetAlpha(surface, 0, 0);
}

/* Copy the surface into the GL texture image */
area.x = 0;
area.y = 0;
area.w = surface->w;
area.h = surface->h;
SDL_BlitSurface(surface, &area, image, &area);

/* Restore the alpha blending attributes */
if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
SDL_SetAlpha(surface, saved_flags, saved_alpha);
}

/* Create an OpenGL texture for the image */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
w, h,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
image->pixels);
SDL_FreeSurface(image); /* No longer needed */

return texture;
}

void DrawLogoTexture(void)
{
static GLuint texture;
static GLfloat texMinX, texMinY;
static GLfloat texMaxX, texMaxY;
static int x = 0;
static int y = 0;
static int w, h;
static int delta_x = 1;
static int delta_y = 1;
static Uint32 last_moved = 0;

SDL_Surface *screen = SDL_GetVideoSurface();

if ( ! texture ) {
SDL_Surface *image;
GLfloat texcoord[4];

/* Load the image (could use SDL_image library here) */
image = SDL_LoadBMP(LOGO_FILE);
if ( image == NULL ) {
return;
}
w = image->w;
h = image->h;

/* Convert the image into an OpenGL texture */
texture = SDL_GL_LoadTexture(image, texcoord);

/* Make texture coordinates easy to understand */
texMinX = texcoord[0];
texMinY = texcoord[1];
texMaxX = texcoord[2];
texMaxY = texcoord[3];

/* We don't need the original image anymore */
SDL_FreeSurface(image);

/* Make sure that the texture conversion is okay */
if ( ! texture ) {
return;
}
}

/* Move the image around */
x += delta_x;
if ( x < 0 ) {
x = 0;
delta_x = -delta_x;
} else
if ( (x+w) > screen->w ) {
x = screen->w-w;
delta_x = -delta_x;
}
y += delta_y;
if ( y < 0 ) {
y = 0;
delta_y = -delta_y;
} else
if ( (y+h) > screen->h ) {
y = screen->h-h;
delta_y = -delta_y;
}

/* Show the image on the screen */
SDL_GL_Enter2DMode();
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(texMinX, texMinY); glVertex2i(x, y );
glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y );
glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h);
glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
glEnd();
SDL_GL_Leave2DMode();
}

/* This code is deprecated, but available for speed comparisons */
void DrawLogoBlit(void)
{
static SDL_Surface *image = NULL;
static GLuint texture;
static GLfloat texMinX, texMinY;
static GLfloat texMaxX, texMaxY;
static int x = 0;
static int y = 0;
static int w, h;
Expand All @@ -146,114 +320,72 @@ void DrawSDLLogo(void)
static Uint32 last_moved = 0;

SDL_Rect dst;
SDL_Surface *screen;
SDL_Surface *screen = SDL_GetVideoSurface();

if ( image == NULL ) {
SDL_Surface *temp;

temp = SDL_LoadBMP("icon.bmp");
/* Load the image (could use SDL_image library here) */
temp = SDL_LoadBMP(LOGO_FILE);
if ( temp == NULL ) {
return;
}
w = temp->w;
h = temp->h;

/* Convert the image into the screen format */
image = SDL_CreateRGBSurface(
SDL_SWSURFACE,
temp->w, temp->h,
32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000
#else
0xFF000000,
0x00FF0000,
0x0000FF00,
0x000000FF
#endif
);
if ( image != NULL ) {
w, h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
if ( image ) {
SDL_BlitSurface(temp, NULL, image, NULL);
}
SDL_FreeSurface(temp);
if ( image == NULL ) {
return;
}
w = image->w;
h = image->h;

/* Create an OpenGL texture for the image */
if ( ! USE_DEPRECATED_OPENGLBLIT ) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
w, h,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
image->pixels);
SDL_FreeSurface(image); /* No longer needed */
/* Make sure that the texture conversion is okay */
if ( ! image ) {
return;
}
}

screen = SDL_GetVideoSurface();

/* Show the image on the screen */
dst.x = x;
dst.y = y;
dst.w = w;
dst.h = h;

/* Move it around
/* Move the image around
Note that we do not clear the old position. This is because we
perform a glClear() which clears the framebuffer and then only
update the new area.
Note that you can also achieve interesting effects by modifying
the screen surface alpha channel. It's set to 255 by default..
*/
if ( (SDL_GetTicks() - last_moved) > 100 ) {
x += delta_x;
if ( x < 0 ) {
x = 0;
delta_x = -delta_x;
} else
if ( (x+w) > screen->w ) {
x = screen->w-w;
delta_x = -delta_x;
}
y += delta_y;
if ( y < 0 ) {
y = 0;
delta_y = -delta_y;
} else
if ( (y+h) > screen->h ) {
y = screen->h-h;
delta_y = -delta_y;
}
if ( USE_DEPRECATED_OPENGLBLIT ) {
SDL_BlitSurface(image, NULL, screen, &dst);
} else {
SDL_GL_Enter2DMode();
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0, 0.0); glVertex2i(x, y );
glTexCoord2f(1.0, 0.0); glVertex2i(x+w, y );
glTexCoord2f(0.0, 1.0); glVertex2i(x, y+h);
glTexCoord2f(1.0, 1.0); glVertex2i(x+w, y+h);
glEnd();
SDL_GL_Leave2DMode();
}
x += delta_x;
if ( x < 0 ) {
x = 0;
delta_x = -delta_x;
} else
if ( (x+w) > screen->w ) {
x = screen->w-w;
delta_x = -delta_x;
}
if ( USE_DEPRECATED_OPENGLBLIT ) {
SDL_UpdateRects(screen, 1, &dst);
y += delta_y;
if ( y < 0 ) {
y = 0;
delta_y = -delta_y;
} else
if ( (y+h) > screen->h ) {
y = screen->h-h;
delta_y = -delta_y;
}
dst.x = x;
dst.y = y;
dst.w = w;
dst.h = h;
SDL_BlitSurface(image, NULL, screen, &dst);

/* Show the image on the screen */
SDL_UpdateRects(screen, 1, &dst);
}

int RunGLTest( int argc, char* argv[],
Expand Down Expand Up @@ -496,7 +628,11 @@ int RunGLTest( int argc, char* argv[],

/* Draw 2D logo onto the 3D display */
if ( logo ) {
DrawSDLLogo();
if ( USE_DEPRECATED_OPENGLBLIT ) {
DrawLogoBlit();
} else {
DrawLogoTexture();
}
}

SDL_GL_SwapBuffers( );
Expand Down

0 comments on commit 8f09ff0

Please sign in to comment.