PDA

View Full Version : Wrapping a OpenGL Texture from a SDL_Surface does not work



Prophet05
06-06-2007, 03:07 PM
Hi,

i tried to wrap a opengl texture from a SDL_Surface that i loaded from a png-file. First i tried on my own but that didn't work. Now i use a function i found on the web. Here my complete code:

#include <cstdlib>
#include <iostream>
using namespace std;

#include <SDL.h>
#include <SDL_image.h>
#include <GL/gl.h>
#include <GL/glu.h>

uint32_t PowerOfTwo(uint32_t size) {
int value = 1;
while(value < size) {
value <<= 1;
}
return value;
}

GLuint LoadTexture(const char *filename, GLfloat* texture_coords) {
GLuint texture;
int w, h;
SDL_Surface *image;
SDL_Surface* surface = IMG_Load(filename);
SDL_Rect area;
Uint32 saved_flags;
Uint8 saved_alpha;

/* Use the surface width and height expanded to powers of 2 */
w = PowerOfTwo(surface->w);
h = PowerOfTwo(surface->h);
texture_coords[0] = 0.0f; /* Min X */
texture_coords[1] = 0.0f; /* Min Y */
texture_coords[2] = (GLfloat)surface->w / w; /* Max X */
texture_coords[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&amp;(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, &amp;area, image, &amp;area);

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

/* Create an OpenGL texture for the image */
glGenTextures(1, &amp;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);/**/

/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image->w, image->h, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);/**/

SDL_FreeSurface(image); /* No longer needed */

return texture;
}


int main()
{
Uint32 Width = 640;
Uint32 Height = 480;
SDL_Init(SDL_INIT_VIDEO);
SDL_SetVideoMode(Width, Height, 0, SDL_OPENGL);

SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

glShadeModel(GL_SMOOTH);
glClearColor(1, 1, 1, 0);
glClearDepth(1.0f);

glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LEQUAL);


glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluOrtho2D(0, Width, Height, 0);

GLfloat text_png_coords[4];
GLuint text_png = LoadTexture("test.png", text_png_coords);
if(text_png == 0)
{
cout << "Could not load texture!" << endl;
exit(0);
}


bool quit = false;
while (!quit)
{
SDL_Event event;
while(SDL_PollEvent(&amp;event))
{
if(event.type == SDL_QUIT)
quit = true;
if(event.type == SDL_KEYDOWN)
if(event.key.keysym.sym == SDLK_ESCAPE)
quit = true;

}

glMatrixMode(GL_MODELVIEW);

//glLoadIdentity();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2i(0, Height/2);
glVertex2i(Width, Height/2);
glVertex2i(Width/2, 0);
glVertex2i(Width/2, Height);
glEnd();

glBindTexture(GL_TEXTURE_2D, text_png);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);

glTexCoord2f(0.0f, 0.0f);
glVertex2i(100, 100);

glTexCoord2f(text_png_coords[2], 0.0f);
glVertex2i(150, 100);

glTexCoord2f(text_png_coords[2], text_png_coords[3]);
glVertex2i(150, 150);

glTexCoord2f(0.0f, text_png_coords[3]);
glVertex2i(100, 150);
glEnd();

glFinish();

SDL_GL_SwapBuffers();
SDL_Delay(10);
}

glDeleteTextures(1, &amp;text_png);
SDL_Quit();

exit(0);
}It draws a red cross on my screen and then shows the texture i loaded. My problem now is that the texture is shown without issues. But from the point i call glTexImage2D at the lines i paint arent shown anymore they just disappear! And i have no idea why. If i comment the call of glTexImage2D out of source it works the lines are drawn (the texture is missing, logicaly). Can you help me? I allready posted in many other forum but never got any proper help.

Greetings, Prophet05

EDIT: Here the png-file i loaded: http://prophet.underground-irc.net/test.png

memfr0b
06-07-2007, 01:56 AM
You never disable texturing, so after loading the texture, not only is your quad textured, but so are your lines. Commenting out the glTexImage2D call helps because without the call the texture isn't initialized and texturing is disabled automatically.

Add glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D) around your quad draw code to fix the problem.

Prophet05
06-07-2007, 04:36 AM
Thank you! That solved my problem.