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&(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(image, 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);/**/
/*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(&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, &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