Sdl surface -> ogl texture & transparency

Hey SDLers,
I’m way new to OpenGL (just began tonight actually), and using the nehe
demos I can get a SDL surface into OpenGL and rotate it. However, I’d
like to simply not blit pixels of a certain color, or use alpha values.
How would I upload an OGL texture w/ alpha values? Using
SDL_SetColorKey() before upping the texture doesnt really work. I’m
sorry if this is a stupid question or whatnot, but I’m extremely new to
OpenGL. Thanks for any help.–
Chris Thielen <@Christopher_Thielen>

Chris Thielen wrote:

How would I upload an OGL texture w/ alpha values?

Well, I have used following code to convert SDL surface to OpenGL
texture. It takes a filename of texture, it loads it with SDL_Image
and returns the ready-to-use OGL texture ID.

---- code begins ----

GLuint load_texture(char *file, bool alpha) {

GLuint tex;	// this will hold the final OGL texture ID

// Load the file
SDL_Surface *img = IMG_Load(file);
.... check for errors ...

// Build the texture from the surface
// Note that you must have 'alpha' parameter set to true
// if you want to use surface's alpha values.
int dim = img->w * img->h * ((alpha) ? 4 : 3);
GLubyte *data;
data = new GLubyte[dim];
if(!data)
	.... error handling here ...

// Traverse trough surface and grab the pixels
int pos = 0;
for(int y=(img->h-1); y>-1; y--) {
	for(int x=0; x<img->w; x++) {
		Uint8 r,g,b,a;
		// Note about getpixel function. It's a simple function
		// taken from SDL's manuals. It just returns the color
		// of specifig pixel in Uint32 format. Just ask me
		// if you want me to show the function.
		Uint32 color = getpixel(img, x,y);

		if(!alpha)
			SDL_GetRGB(color, img->format, &r,&g,&b);
		else
			SDL_GetRGBA(color, img->format, &r,&g,&b,&a);

		data[pos] = r; pos++;
		data[pos] = g; pos++;
		data[pos] = b; pos++;
		if(alpha) {
			data[pos] = a; pos++;
		}
	}
}

// Now we have the 'data' array filled with our pixel (and alpha) data.

int type = (alpha) ? GL_RGBA : GL_RGB;
glGenTextures(1, &tex);		// Generate texture ID
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, type, img->w, img->h, 0, type, \ 

GL_UNSIGNED_BYTE, data);

// You can now use glTexParameteri for setting up your parameters like
// filtering, mipmapping etc.
....

// Clean up and return the texture ID
delete [] data;
SDL_FreeSurface(img);

return tex;

}

— code ends here —

Example using the function:
GLuint cube_tex;
cube_tex = load_texture(“cube.png”);

glBindTexture(GL_TEXTURE_2D, cube_tex);
// Draw a alpha blended cube

The code has worked for me at least, so hope it helps.
And ask if you don’t understand something.–
Mika Halttunen
@Mika_Halttunen

i’m writing under c, not c++, so i changed lines like:

data = new GLubyte[dim];

to

data = calloc(dim, sizeof(GLubyte));

and

delete [] data

to free(data)

and i’m not sure if that is messing up the function but i believe the
two should do the same thing. anyway, i tried using the function and the
texture’s appear completely white. i attached my source code and i’m
loading a png that just has a hole in it, but none of the texture data
appears.

do you know what could be wrong? why is the texture white?On Fri, 2002-11-29 at 10:42, Mika Halttunen wrote:

Chris Thielen wrote:

How would I upload an OGL texture w/ alpha values?

Well, I have used following code to convert SDL surface to OpenGL
texture. It takes a filename of texture, it loads it with SDL_Image
and returns the ready-to-use OGL texture ID.

---- code begins ----

GLuint load_texture(char *file, bool alpha) {

GLuint tex; // this will hold the final OGL texture ID

// Load the file
SDL_Surface *img = IMG_Load(file);
… check for errors …

// Build the texture from the surface
// Note that you must have ‘alpha’ parameter set to true
// if you want to use surface’s alpha values.
int dim = img->w * img->h * ((alpha) ? 4 : 3);
GLubyte *data;
data = new GLubyte[dim];
if(!data)
… error handling here …

// Traverse trough surface and grab the pixels
int pos = 0;
for(int y=(img->h-1); y>-1; y–) {
for(int x=0; xw; x++) {
Uint8 r,g,b,a;
// Note about getpixel function. It’s a simple function
// taken from SDL’s manuals. It just returns the color
// of specifig pixel in Uint32 format. Just ask me
// if you want me to show the function.
Uint32 color = getpixel(img, x,y);

  	if(!alpha)
  		SDL_GetRGB(color, img->format, &r,&g,&b);
  	else
  		SDL_GetRGBA(color, img->format, &r,&g,&b,&a);

  	data[pos] = r; pos++;
  	data[pos] = g; pos++;
  	data[pos] = b; pos++;
  	if(alpha) {
  		data[pos] = a; pos++;
  	}
  }

}

// Now we have the ‘data’ array filled with our pixel (and alpha) data.

int type = (alpha) ? GL_RGBA : GL_RGB;
glGenTextures(1, &tex); // Generate texture ID
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, type, img->w, img->h, 0, type, \
GL_UNSIGNED_BYTE, data);

// You can now use glTexParameteri for setting up your parameters like
// filtering, mipmapping etc.

// Clean up and return the texture ID
delete [] data;
SDL_FreeSurface(img);

return tex;
}

— code ends here —

Example using the function:
GLuint cube_tex;
cube_tex = load_texture(“cube.png”);

glBindTexture(GL_TEXTURE_2D, cube_tex);
// Draw a alpha blended cube

The code has worked for me at least, so hope it helps.
And ask if you don’t understand something.

Chris Thielen <@Christopher_Thielen>
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#include “SDL.h”
#include “SDL_image.h”

/* lighting on/off (1 = on, 0 = off) */
int light = 0;

GLfloat xrot; // x rotation
GLfloat yrot; // y rotation
GLfloat xspeed = 0.1; // x rotation speed
GLfloat yspeed = 0.1; // y rotation speed

GLfloat z = -5.0f; // depth into the screen.

/* white ambient light at half intensity (rgba) */
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };

/* super bright, full intensity diffuse light. */
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };

/* position of light (x, y, z, (position of light)) */
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };

GLuint filter = 0; /* Which Filter To Use (nearest/linear/mipmapped) /
GLuint texture; /
Storage for 3 textures. */

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

GLuint load_texture(char *file, unsigned char alpha) {
GLuint tex; // this will hold the final OGL texture ID
SDL_Surface *img;
int dim;
GLubyte *data = NULL;
int pos = 0;
int type;
int x, y;

dim = img->w * img->h * ((alpha) ? 4 : 3);

// Load the file
img = IMG_Load(file);
if (img == NULL) {
	fprintf(stdout, "Could not load \"%s\"\n", file);
	exit(-1);
}

// Build the texture from the surface
// Note that you must have 'alpha' parameter set to true
// if you want to use surface's alpha values.
//new GLubyte[dim];
data = calloc(dim, sizeof(GLubyte));
if (data == NULL) {
	fprintf(stdout, "Could not allocate array in load_texture()\n");
	exit(-1);
}

// Traverse trough surface and grab the pixels
    for(y=(img->h-1); y>-1; y--) {
            for(x=0; x<img->w; x++) {
                    Uint8 r,g,b,a;
                    // Note about getpixel function. It's a simple function
                    // taken from SDL's manuals. It just returns the color
                    // of specifig pixel in Uint32 format. Just ask me
                    // if you want me to show the function.
                    Uint32 color = getpixel(img, x,y);
    
                    if(!alpha)
                            SDL_GetRGB(color, img->format, &r,&g,&b);
                    else
                            SDL_GetRGBA(color, img->format, &r,&g,&b,&a);
    
                    data[pos] = r; pos++;
                    data[pos] = g; pos++;
                    data[pos] = b; pos++;
                    if(alpha) {
                            data[pos] = a; pos++;
                    }
            }
    }
    
    // Now we have the 'data' array filled with our pixel (and alpha) data.
    type = (alpha) ? GL_RGBA : GL_RGB;
    glGenTextures(1, &tex);         // Generate texture ID
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, type, img->w, img->h, 0, type, GL_UNSIGNED_BYTE, data);

    // You can now use glTexParameteri for setting up your parameters like
    // filtering, mipmapping etc.
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); // scale linearly + mipmap when image smalled than texture

    // Clean up and return the texture ID
    free(data);
    SDL_FreeSurface(img);

    return tex;

}

SDL_Surface *LoadBMP(char *filename)
{
Uint8 *rowhi, *rowlo;
Uint8 *tmpbuf, tmpch;
SDL_Surface *image;
int i, j;

image = SDL_LoadBMP(filename);
if ( image == NULL ) {
    fprintf(stderr, "Unable to load %s: %s\n", filename, SDL_GetError());
    return(NULL);
}

/* GL surfaces are upsidedown and RGB, not BGR :-) */
tmpbuf = (Uint8 *)malloc(image->pitch);
if ( tmpbuf == NULL ) {
    fprintf(stderr, "Out of memory\n");
    return(NULL);
}
rowhi = (Uint8 *)image->pixels;
rowlo = rowhi + (image->h * image->pitch) - image->pitch;
for ( i=0; i<image->h/2; ++i ) {
    for ( j=0; j<image->w; ++j ) {
        tmpch = rowhi[j*3];
        rowhi[j*3] = rowhi[j*3+2];
        rowhi[j*3+2] = tmpch;
        tmpch = rowlo[j*3];
        rowlo[j*3] = rowlo[j*3+2];
        rowlo[j*3+2] = tmpch;
    }
    memcpy(tmpbuf, rowhi, image->pitch);
    memcpy(rowhi, rowlo, image->pitch);
    memcpy(rowlo, tmpbuf, image->pitch);
    rowhi += image->pitch;
    rowlo -= image->pitch;
}
free(tmpbuf);
return(image);

}

// Load Bitmaps And Convert To Textures
GLvoid LoadGLTextures(GLvoid)
{
texture = load_texture(“texture.png”, 1);
};

/* A general OpenGL initialization function. Sets all of the initial parameters. */
GLvoid InitGL(GLsizei Width, GLsizei Height) // We call this right after our OpenGL window is created.
{
glViewport(0, 0, Width, Height);
LoadGLTextures(); // load the textures.
glEnable(GL_TEXTURE_2D); // Enable texture mapping.

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);	// This Will Clear The Background Color To Black
glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS);			// The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST);			// Enables Depth Testing
glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading

glMatrixMode(GL_PROJECTION);
glLoadIdentity();				// Reset The Projection Matrix

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);	// Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW);

// set up light number 1.
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);  // add lighting. (ambient)
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);  // add lighting. (diffuse).
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // set light position.
glEnable(GL_LIGHT1);                             // turn light 1 on.

}

/* The main drawing function. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View

glTranslatef(0.0f,0.0f,z);                  // move z units out from the screen.

glRotatef(xrot,1.0f,0.0f,0.0f);		// Rotate On The X Axis
glRotatef(yrot,0.0f,1.0f,0.0f);		// Rotate On The Y Axis

glBindTexture(GL_TEXTURE_2D, texture);   // choose the texture to use.

glBegin(GL_QUADS);		                // begin drawing a cube

// Front Face (note that the texture's corners have to match the quad's corners)
glNormal3f( 0.0f, 0.0f, 1.0f);                              // front face points out of the screen on z.
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Left Of The Texture and Quad

// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);                              // back face points into the screen on z.
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Left Of The Texture and Quad

// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);                              // top face points up on y.
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right Of The Texture and Quad

// Bottom Face       
glNormal3f( 0.0f, -1.0f, 0.0f);                             // bottom face points down on y. 
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right Of The Texture and Quad

// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);                              // right face points right on x.
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left Of The Texture and Quad

// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);                              // left face points left on x.
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left Of The Texture and Quad

glEnd();                                    // done with the polygon.

xrot+=xspeed;		                // X Axis Rotation	
yrot+=yspeed;		                // Y Axis Rotation

// swap buffers to display, since we're double buffered.
SDL_GL_SwapBuffers();

}

int main(int argc, char **argv)
{
int done;
Uint8 *keys;

/* Initialize SDL for video output */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

atexit(SDL_Quit);

/* Create a 640x480 OpenGL screen */
if ( SDL_SetVideoMode(640, 480, 0, SDL_OPENGL) == NULL ) {
	fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
	return (-1);
}

/* Set the title bar in environments that support it */
SDL_WM_SetCaption("OpenGL", "OpenGL");

SDL_ShowCursor(0);

/* Loop, drawing and checking events */
InitGL(640, 480);
done = 0;
while ( ! done ) {
    DrawGLScene();

    /* This could go in a separate function */
    { SDL_Event event;
      while ( SDL_PollEvent(&event) ) {
          if ( event.type == SDL_QUIT ) {
              done = 1;
          }
          if ( event.type == SDL_KEYDOWN ) {
               switch(event.key.keysym.sym) {
                   case SDLK_ESCAPE:
                       done = 1;
                       break;
                   case SDLK_l:
                   printf("Light was: %d\n", light);
                   light = light ? 0 : 1;              // switch the current value of light, between 0 and 1.
                   printf("Light is now: %d\n", light);
                   if (!light) {
                       glDisable(GL_LIGHTING);
                   } else {
                       glEnable(GL_LIGHTING);
                   }
                   break;
                   case SDLK_f:
                   printf("Filter was: %d\n", filter);
                   filter += 1;
                   if (filter>2)
                           filter = 0;
                   printf("Filter is now: %d\n", filter);
                   break;
               }
           }
       }
     }

     /* Check current key state for special commands */
     keys = SDL_GetKeyState(NULL);
     if ( keys[SDLK_PAGEUP] == SDL_PRESSED ) {
         z-=0.02f;
     }
     if ( keys[SDLK_PAGEDOWN] == SDL_PRESSED ) {
         z+=0.02f;
     }
     if ( keys[SDLK_UP] == SDL_PRESSED ) {
         xspeed-=0.01f;
     }
     if ( keys[SDLK_DOWN] == SDL_PRESSED ) {
         xspeed+=0.01f;
     }
     if ( keys[SDLK_LEFT] == SDL_PRESSED ) {
         yspeed-=0.01f;
     }
     if ( keys[SDLK_RIGHT] == SDL_PRESSED ) {
         yspeed+=0.01f;
     }
}

SDL_ShowCursor(1);

return (0);

}

Chris Thielen wrote:

anyway, i tried using the function and the
texture’s appear completely white. i attached my source code and i’m
loading a png that just has a hole in it, but none of the texture data
appears.

do you know what could be wrong? why is the texture white?

I don’t have time right now to completely review the code you attached,
but it seems that you’re missing the mipmap generation code. I mean,
you set texture properties to have mipmapping (glTexParameteri) but
you don’t call gluBuild2DMipmaps at all…?

Try placing following line after your glTexParameteri’s:

gluBuild2DMipmaps(GL_TEXTURE_2D, type, img->w, img->h, type,\
GL_UNSIGNED_BYTE, data);

And you have to link with GLU libs of course.
That could be the problem.–
Mika Halttunen
@Mika_Halttunen

Chris Thielen wrote:

anyway, i tried using the function and the
texture’s appear completely white. i attached my source code and i’m
loading a png that just has a hole in it, but none of the texture data
appears.

do you know what could be wrong? why is the texture white?

I don’t have time right now to completely review the code you attached,
but it seems that you’re missing the mipmap generation code. I mean,
you set texture properties to have mipmapping (glTexParameteri) but
you don’t call gluBuild2DMipmaps at all…?

Try placing following line after your glTexParameteri’s:

gluBuild2DMipmaps(GL_TEXTURE_2D, type, img->w, img->h, type,\
GL_UNSIGNED_BYTE, data);

And you have to link with GLU libs of course.
That could be the problem.

Ah, that certainly does hinder it. But the texture is still incorrect.
I’ll try using your exact code under a C++ compiler to see if the
problem is arising out of the malloc() instead of new changes and such,
but I’m still not quite sure what’s wrong.On Sun, 2002-12-01 at 07:10, Mika Halttunen wrote:


Chris Thielen <@Christopher_Thielen>

Chris Thielen wrote:

Ah, that certainly does hinder it. But the texture is still incorrect.
I’ll try using your exact code under a C++ compiler to see if the
problem is arising out of the malloc() instead of new changes and such,
but I’m still not quite sure what’s wrong.

Still white textures? Hmm… I’m not very familiar with C-style
malloc()/calloc() etc. so it might be wise to check with C++,
as you intended. If the problem still exists with C++, you
could load a normal non-alpha texture, such as BMP to see
if the alpha-stuff fails.

Btw, could you resend me (to @Mika_Halttunen) your code for an another
peek, 'cos I managed to lost that particular mail. And I’ll try my own
code tonight with malloc/free to make sure it works. There is always
a possibility that when I cutted/pasted the code from my .cpp -file,
I messed something up. I’ll check that too.–
Mika Halttunen
@Mika_Halttunen

And I’ll try my own code tonight with malloc/free to make
sure it works.

Ok, I have converted the function to use malloc/free and it works
fine. Here’s the whole function as it is in my .cpp-file.
You could try with that function, without any modifications if
you’re using SDL_Image. Usage:

GLuint texture;
texture = load_texture(“foo.png”, true, false, true);
// … with alpha enabled, no repeating and mipmaps enabled

glBindTexture(GL_TEXTURE_2D, texture);
//… draw something

— cut —

// Load a image file using SDL_Image and
// convert it to OpenGL texture.
// If alpha == true -> RGBA alpha texture
// If repeat == true -> texture can be tiled
// If mipmaps == true -> Mipmaps will be generated
// Return texture ID
GLuint load_texture(char *file, bool alpha, bool repeat, bool mipmaps) {

GLuint tex;

// Load the 'file' to SDL_Surface
SDL_Surface *img = NULL;
img = IMG_Load(file);
if(img == NULL)
	error_msg("Unable to load texture from %s!\n%s", file, IMG_GetError());

// Build the texture from the surface
int dim = img->w * img->h * ((alpha) ? 4 : 3);
GLubyte *data;
//data = new GLubyte[dim];
data = (GLubyte*)malloc(sizeof(GLubyte) * dim);
if(!data)
	error_msg("Unable to create a texture from %s!", file);

// Traverse trough surface and grab the pixels
int pos = 0;
for(int y=(img->h-1); y>-1; y--) {
	for(int x=0; x<img->w; x++) {
		Uint8 r,g,b,a;
		Uint32 color = getpixel(img, x,y);

		if(!alpha)
			SDL_GetRGB(color, img->format, &r,&g,&b);
		else
			SDL_GetRGBA(color, img->format, &r,&g,&b,&a);

		data[pos] = r; pos++;
		data[pos] = g; pos++;
		data[pos] = b; pos++;
		if(alpha) {
			data[pos] = a; pos++;
		}
	}
}

int type = (alpha) ? GL_RGBA : GL_RGB;
glGenTextures(1, &tex);		// Generate texture ID
glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, type, img->w, img->h, 0, type, 

GL_UNSIGNED_BYTE, data);
int filter_min, filter_mag;
if(config.texture_filtering) {
filter_min = (mipmaps) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
filter_mag = GL_LINEAR;
}
else {
filter_min = (mipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
filter_mag = GL_NEAREST;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_min);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_mag);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (repeat) ? GL_REPEAT 

: GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (repeat) ? GL_REPEAT
: GL_CLAMP);
if(mipmaps)
gluBuild2DMipmaps(GL_TEXTURE_2D, type, img->w, img->h, type,
GL_UNSIGNED_BYTE, data);

// Clean up and return the texture ID
//delete [] data;
free(data);
SDL_FreeSurface(img);

return tex;

}

— cut —

If it still doesn’t work, I’d suspect it’s your image loading code
which fails with alpha …? Are you using SDL_Image?–
Mika Halttunen
@Mika_Halttunen

Yes, this code works! :slight_smile:

I was wondering if the alpha areas on the png, when textured to a
GL_POLYGON, do they appear as black or simply not drawn at all? I put it
on a spinning cube and they appear black. Is there a way to simply have
that area of the texture not blit at all? Like full transparency there?

(OFF-TOPIC/non-sdl, might wanna reply personally or not at all):
when i load this image, or other images, my glColor3f() commands seem
ignored. For example, my suppose-to-be-white stars appear very very dark
grey. Any idea why I can’t set the color of a polygon correctly? Do I
need to clear something?On Tue, 2002-12-03 at 07:37, Mika Halttunen wrote:

And I’ll try my own code tonight with malloc/free to make
sure it works.

Ok, I have converted the function to use malloc/free and it works
fine. Here’s the whole function as it is in my .cpp-file.
You could try with that function, without any modifications if
you’re using SDL_Image. Usage:

GLuint texture;
texture = load_texture(“foo.png”, true, false, true);
// … with alpha enabled, no repeating and mipmaps enabled

glBindTexture(GL_TEXTURE_2D, texture);
//… draw something

— cut —

// Load a image file using SDL_Image and
// convert it to OpenGL texture.
// If alpha == true -> RGBA alpha texture
// If repeat == true -> texture can be tiled
// If mipmaps == true -> Mipmaps will be generated
// Return texture ID
GLuint load_texture(char *file, bool alpha, bool repeat, bool mipmaps) {

GLuint tex;

// Load the ‘file’ to SDL_Surface
SDL_Surface *img = NULL;
img = IMG_Load(file);
if(img == NULL)
error_msg(“Unable to load texture from %s!\n%s”, file, IMG_GetError());

// Build the texture from the surface
int dim = img->w * img->h * ((alpha) ? 4 : 3);
GLubyte data;
//data = new GLubyte[dim];
data = (GLubyte
)malloc(sizeof(GLubyte) * dim);
if(!data)
error_msg(“Unable to create a texture from %s!”, file);

// Traverse trough surface and grab the pixels
int pos = 0;
for(int y=(img->h-1); y>-1; y–) {
for(int x=0; xw; x++) {
Uint8 r,g,b,a;
Uint32 color = getpixel(img, x,y);

  	if(!alpha)
  		SDL_GetRGB(color, img->format, &r,&g,&b);
  	else
  		SDL_GetRGBA(color, img->format, &r,&g,&b,&a);

  	data[pos] = r; pos++;
  	data[pos] = g; pos++;
  	data[pos] = b; pos++;
  	if(alpha) {
  		data[pos] = a; pos++;
  	}
  }

}

int type = (alpha) ? GL_RGBA : GL_RGB;
glGenTextures(1, &tex); // Generate texture ID
glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, type, img->w, img->h, 0, type,
GL_UNSIGNED_BYTE, data);
int filter_min, filter_mag;
if(config.texture_filtering) {
filter_min = (mipmaps) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
filter_mag = GL_LINEAR;
}
else {
filter_min = (mipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
filter_mag = GL_NEAREST;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_min);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_mag);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (repeat) ? GL_REPEAT
: GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (repeat) ? GL_REPEAT
: GL_CLAMP);
if(mipmaps)
gluBuild2DMipmaps(GL_TEXTURE_2D, type, img->w, img->h, type,
GL_UNSIGNED_BYTE, data);

// Clean up and return the texture ID
//delete [] data;
free(data);
SDL_FreeSurface(img);

return tex;
}

— cut —

If it still doesn’t work, I’d suspect it’s your image loading code
which fails with alpha …? Are you using SDL_Image?


Mika Halttunen
lsoft at mbnet.fi


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Chris Thielen <@Christopher_Thielen>