# Sdl surface -\> ogl texture & transparency

**URL:** <https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842>\
**Category:** SDL Development\
**Created:** [November 28, 2002, 7:40pm UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842 "2002-11-28T19:40:03Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christopher\_Thielen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/c/ce73a5/32.png) [@Christopher\_Thielen](https://discourse.libsdl.org/u/Christopher_Thielen)\
**Post date:** [November 28, 2002, 7:40pm UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/1 "2002-11-28T19:40:03Z")

</div>

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\>

---

<div class="post-metadata">

**Author:** ![Mika\_Halttunen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/6a8cbe/32.png) [@Mika\_Halttunen](https://discourse.libsdl.org/u/Mika_Halttunen)\
**Post date:** [November 29, 2002, 10:45am UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/2 "2002-11-29T10:45:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Christopher\_Thielen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/c/ce73a5/32.png) [@Christopher\_Thielen](https://discourse.libsdl.org/u/Christopher_Thielen)\
**Post date:** [November 30, 2002, 12:56pm UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/3 "2002-11-30T12:56:01Z")

</div>

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;

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);

```

}

---

<div class="post-metadata">

**Author:** ![Mika\_Halttunen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/6a8cbe/32.png) [@Mika\_Halttunen](https://discourse.libsdl.org/u/Mika_Halttunen)\
**Post date:** [December 1, 2002, 7:13am UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/4 "2002-12-01T07:13:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Christopher\_Thielen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/c/ce73a5/32.png) [@Christopher\_Thielen](https://discourse.libsdl.org/u/Christopher_Thielen)\
**Post date:** [December 1, 2002, 7:09pm UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/5 "2002-12-01T19:09:01Z")

</div>

> 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\>

---

<div class="post-metadata">

**Author:** ![Mika\_Halttunen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/6a8cbe/32.png) [@Mika\_Halttunen](https://discourse.libsdl.org/u/Mika_Halttunen)\
**Post date:** [December 2, 2002, 9:13am UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/6 "2002-12-02T09:13:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Mika\_Halttunen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/6a8cbe/32.png) [@Mika\_Halttunen](https://discourse.libsdl.org/u/Mika_Halttunen)\
**Post date:** [December 3, 2002, 7:41am UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/7 "2002-12-03T07:41:01Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![Christopher\_Thielen](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/c/ce73a5/32.png) [@Christopher\_Thielen](https://discourse.libsdl.org/u/Christopher_Thielen)\
**Post date:** [December 3, 2002, 6:08pm UTC](https://discourse.libsdl.org/t/sdl-surface-ogl-texture-transparency/7842/8 "2002-12-03T18:08:02Z")

</div>

Yes, this code works! 🙂

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](http://mbnet.fi)
> 
> * * *
> 
> SDL mailing list  
> SDL at [libsdl.org](http://libsdl.org)  
> [http://www.libsdl.org/mailman/listinfo/sdl](http://www.libsdl.org/mailman/listinfo/sdl)  
> –  
> Chris Thielen \<@Christopher\_Thielen\>
