OpenGL Textures from SDL_Surfaces (Solved! with code)

Micah Brening <micah.brening gmail.com> writes:

So my request:
Please, anyone who knows how to accomplish what I’m attempting, please post
code to initialize OpenGL, convert an SDL_Surface to an OpenGL Texture, or
even
the drawing functions used. Or what ever might be involved in getting rid of
the boxes around the textures. I’m assuming I’m just forgetting to enable
some
option, or set some value. But I cannot find anywhere on the Internet that
just comes out and tells it all plain and simple. I guess I need something
from start to finish so that I’m not missing something so brain numbingly
obvious.

Well I finally figured it out. After comparing all the code from what I had,
and what I was shown. The difference was that I was setting up opengl for 2d
in a function, for each frame (not in the code I submitted earlier) Which had
things ALMOST correct. I had the texture env set to GL_DECAL, rather than
GL_REPLACE. That said, after changing that, the code worked perfectly.

I figured I’d share the code in case someone should have the same problem and
wish to see what worked for me:

#include “main.h”
#include “SDL_opengl.h”
#include “SDL_image.h”

typedef struct sprite{
GLuint img;
GLfloat texcoord[4];
} sprite;

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,colorkey;
Uint8 saved_alpha;

w = power_of_two(surface->w);
h = power_of_two(surface->h);
texcoord[0] = 0.0f;
texcoord[1] = 0.0f;
texcoord[2] = (GLfloat)surface->w / w;
texcoord[3] = (GLfloat)surface->h / h;

image = SDL_CreateRGBSurface(
		SDL_SWSURFACE,
		w, h,
		32,

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000
#else
0xFF000000,
0x00FF0000,
0x0000FF00,
0x000000FF
#endif
);
if ( image == NULL ) {
return 0;
}
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);
}

area.x = 0;
area.y = 0;
area.w = surface->w;
area.h = surface->h;
SDL_BlitSurface(surface, &area, image, &area);
if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
	SDL_SetAlpha(surface, saved_flags, saved_alpha);
}
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); 

return texture;

}

void SDL_GL_Enter2DMode()
{
SDL_Surface *screen = SDL_GetVideoSurface();

/* Note, there may be other things you need to change,
   depending on how you have your OpenGL state set up.
*/
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);

/* This allows alpha blending of 2D textures with the scene */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER,0);
glEnable(GL_ALPHA_TEST);
glViewport(0, 0, screen->w, screen->h);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);

}

int GFX_initgfx(kelset *rage)
{ rage->printd(rage,“Setting Video Mode”);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
rage->screen = SDL_SetVideoMode(rage->width,rage->height,rage->bpp,rage-

flags);
if (!rage->screen)
{
rage->printd(rage,“Unable to initalize SDL”);
return -1;
}
else
{
rage->printd(rage,“Setting Window Title”);
SDL_WM_SetCaption(rage->wmtitle,NULL);
glViewport( 0, 0,rage->screen->w,rage->screen->h);
glClearColor(0,0,0,1);
glClearDepth(0.0f);
//glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_Enter2DMode();
rage->printd(rage,“Returning Successful”);
return 1;
}

}

void* GFX_loadsprite(char * filename,SDL_Rect *def)
{
SDL_Surface *img;
sprite *glimg = (sprite *)malloc(sizeof(sprite));
img = IMG_Load(filename);
def->w = img->w;
def->h = img->h;
SDL_SetColorKey(img,SDL_SRCCOLORKEY,SDL_MapRGB(img->format,0,0,0));
glimg->img = SDL_GL_LoadTexture(img,glimg->texcoord);
SDL_FreeSurface(img);
return glimg;
}

void GFX_drawsprite(void *vimg,int x,int y,int w,int h)
{
sprite *glimg = (sprite *)vimg;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,glimg->img);
glBegin(GL_TRIANGLE_STRIP);
// glColor4ub(255, 255, 255,255);
glTexCoord2f(glimg->texcoord[0],glimg->texcoord[1]); glVertex2i
(x,y);
glTexCoord2f(glimg->texcoord[2],glimg->texcoord[1]); glVertex2i
(x+w,y);
glTexCoord2f(glimg->texcoord[0],glimg->texcoord[3]); glVertex2i
(x,y+h);
glTexCoord2f(glimg->texcoord[2],glimg->texcoord[3]); glVertex2i
(x+w,y+h);
glEnd();

}

void GFX_killsprite(void *vimg)
{
sprite *glimg = (sprite *)vimg;
glDeleteTextures(1,&glimg->img);
free(glimg);
}

void GFX_clearscreen(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void GFX_flip(kelset *rage)
{
glFlush();
SDL_GL_SwapBuffers();
}

void GFX_killgfx(void)
{
SDL_Quit();
}

void GFX_drawline(int sx,int sy,int dx,int dy,SDL_Color color)
{
glDisable(GL_TEXTURE_2D);
glBegin(GL_LINE_STRIP);
glColor4ub(color.r, color.g, color.b,255);
glVertex2i(sx,sy);
glVertex2i(dx,dy);
glEnd();
glEnable(GL_TEXTURE_2D);
}

void GFX_drawgrline(int sx,int sy,SDL_Color scolor,int dx,int dy,SDL_Color
dcolor)
{
glDisable(GL_TEXTURE_2D);
glBegin(GL_LINE_STRIP);
glColor4ub(scolor.r, scolor.g, scolor.b,255);
glVertex2i(sx,sy);
glColor4ub(dcolor.r, dcolor.g, dcolor.b,255);
glVertex2i(dx,dy);
glEnd();
glEnable(GL_TEXTURE_2D);
}

void *GFX_totexture(SDL_Surface *img)
{
sprite *glimg = (sprite *)malloc(sizeof(sprite));
glimg->img = SDL_GL_LoadTexture(img,glimg->texcoord);
SDL_FreeSurface(img);
return glimg;
}