Hi, thanks for your response -
In answer to your queries.
I’m pretty sure I initialize an RGBA context - it’s possible I’m wrong though - have thus far about three days experience with this. Will chuck all the pertient code down at the end of this…
Yes I do enable blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
It’s actually turning this on that seems to be the source of my problems. With it diabled my sprites render fine (albeit without transparency)
-
Think I render in a good order. Clear the screen then render sprites right?
-
Not sure what you mean be ‘clear the buffer with all rgba good values’ - if you mean are all my textures RGBA when rendered then yes - otherwise not sure what you mean?
Anyway code is as follow (btw am using SDL_Opengl - don’t know if this is a problem?)
All the initialization stuff:
cGraphics::cGraphics(int WindowWidth, int WindowHeight, int WindowBPP, string WindowCaption)
{
//initialize all SDL subsystems
SDL_Init(SDL_INIT_VIDEO);
//Initialize SDL_ttf
TTF_Init();
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
//Set up the screen
screen = SDL_SetVideoMode(WindowWidth, WindowHeight, WindowBPP, SDL_OPENGL );//SDL_FULLSCREEN);
//Set the window caption
SDL_WM_SetCaption(WindowCaption.c_str(), NULL);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Clear the screen to red
glClearColor( 255.0f, 0.0f, 0.0f, 0.0f );
//Set the viewport to the size of the window
glViewport( 0, 0, WindowWidth, WindowHeight);
//glViewport( 0, 0, 640, 480);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0.0f, WindowWidth, WindowHeight, 0.0f, -1.0f, 1.0f);
//glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
reading in the sdl surfaces + converting into textures
SDL_Surface* cGraphics::load_image_SDL(string filename)
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load(filename.c_str());
//If the image loaded
if (loadedImage != NULL)
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat(loadedImage);
//Free the old image
SDL_FreeSurface(loadedImage);
//If the image was optimized just fine
if (optimizedImage != NULL)
{
//Map the color key
//Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF);
//Set all pixels of color [0,0xFF,0xFF] to be transparent
//SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
}
}
//Return the optimzed image
return optimizedImage;
}
spriteStruct cGraphics::load_texture(std::string filename)
{
GLuint texture; // This is a handle to our texture object
SDL_Surface *testSurface; // This surface will tell us the details of the image
SDL_Surface *surface; //The final surface to be converted to gl texture
GLenum texture_format;
GLint nOfColors;
testSurface = load_image_SDL(filename);
unsigned width;
unsigned height;
if (SDL_MUSTLOCK(testSurface))
SDL_LockSurface(testSurface);
for(int i = 0; i < testSurface->w; i++ )
{
for (int j = 0; j < testSurface->h; j++)
{
Uint8 r;
Uint8 g;
Uint8 b;
Uint8 a;
Uint32 onePixel = get_pixel32(testSurface, i, j);
SDL_GetRGBA(onePixel, testSurface->format, &r, &g, &b, &a);
if (r ==0 && g == 255 && b == 255)
{
// if so, then set alpha to transparent
a = 0;
}
else a = 255;
Uint32 newPixel = SDL_MapRGBA(testSurface->format, r, g, b, a);
put_pixel32(testSurface, i, j, newPixel);
onePixel = get_pixel32(testSurface, i, j);
SDL_GetRGBA(onePixel, testSurface->format, &r, &g, &b, &a);
SDL_GetRGBA(onePixel, testSurface->format, &r, &g, &b, &a);
}
}
if (SDL_MUSTLOCK(testSurface))
SDL_UnlockSurface(testSurface);
if ( ( (testSurface->w != 0) && ( (testSurface->w & (testSurface->w - 1) )!=0 ) ) ||
( (testSurface->h != 0) && ( (testSurface->h & (testSurface->h - 1) )!=0 ) ) )
{
printf("Warning: texture width/depth is not a power of two");
width = pow( 2, ceil( log10(static_cast<double>(testSurface->w) ) / log10(static_cast<double>(2) ) ) );
height = pow( 2, ceil( log10(static_cast<double>(testSurface->h) ) / log10(static_cast<double>(2) ) ) );
surface = SDL_CreateRGBSurface(testSurface->flags,
width,
height,
testSurface->format->BitsPerPixel,
testSurface->format->Rmask,
testSurface->format->Gmask,
testSurface->format->Bmask,
testSurface->format->Amask);
SDL_BlitSurface(testSurface, NULL, surface, NULL);
SDL_Flip(surface);
}
else
{
surface = testSurface;
printf("Texture is ok!");
width = surface->w;
height = surface->h;
}
SDL_SetAlpha(surface, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if (nOfColors == 3) // no alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
else
{
printf("warning: the image is not truecolor.. this will probably break
");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );
spriteStruct sprite;
sprite.spriteClip.h = testSurface->h;
sprite.spriteClip.w = testSurface->w;
sprite.spriteClip.x = 0;
sprite.spriteClip.y = 0;
sprite.spriteTexture = texture;
// Free the SDL_Surface only if it was successfully created
if (surface)
SDL_FreeSurface(surface);
if (testSurface)
SDL_FreeSurface(testSurface);
return sprite;
}
- Should point out I am using a custom structure which hold both the texture and the sprite rectangle (just for collision stuff) - could this be the problem? - Again though, without blending all works fine.
Finally textures are rendered as follows
int cGraphics::apply_texture(int x, int y, spriteStruct *sprite, SDL_Rect* clip)
{
glBindTexture( GL_TEXTURE_2D, sprite->spriteTexture );
GLfloat textureWidth; GLfloat textureHeight;
float spriteWidth = sprite->spriteClip.w;
float spriteHeight = sprite->spriteClip.h;
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &textureHeight);
float fractionalWidth = spriteWidth/textureWidth;
float fractionalHeight = spriteHeight/textureHeight;
x = float(x);
y = float(y);
glBegin( GL_QUADS );
//Bottom-left vertex (corner)
glTexCoord2f( 0.f, 0.f );
glVertex3f( x, y, 0.f );
//Bottom-right vertex (corner)
glTexCoord2f( fractionalWidth, 0.f );
glVertex3f( x+spriteWidth, y, 0.f );
//Top-right vertex (corner)
glTexCoord2f( fractionalWidth, fractionalHeight );
glVertex3f( x+spriteWidth, y+spriteHeight, 0.f );
//Top-left vertex (corner)
glTexCoord2f( 0.f, fractionalHeight );
glVertex3f( x, y+spriteHeight, 0.f );
glEnd();
return 0;
}
and the buffers swapped:
int cGraphics::show()
{
SDL_GL_SwapBuffers();
return 0;
}
Apologies for so much messy code - hard to keep it tidy with so much mucking about going on…
Thanks a lot.