Allow any image format when creating a texture.

This commit is contained in:
Glenn Maynard
2003-06-30 02:39:56 +00:00
parent 71d3338ed4
commit ce518b6bb2
2 changed files with 46 additions and 31 deletions
+45 -30
View File
@@ -153,9 +153,6 @@ struct GLPixFmtInfo_t {
GLenum format; /* target format */ GLenum format; /* target format */
GLenum type; /* data format */ GLenum type; /* data format */
} GL_PIXFMT_INFO[NUM_PIX_FORMATS] = { } GL_PIXFMT_INFO[NUM_PIX_FORMATS] = {
/* XXX: GL_UNSIGNED_SHORT_4_4_4_4 is affected by endianness; GL_UNSIGNED_BYTE
* is not, but all SDL masks are affected by endianness, so GL_UNSIGNED_BYTE
* is reversed. This isn't endian-safe. */
{ {
/* R8G8B8A8 */ /* R8G8B8A8 */
GL_RGBA8, GL_RGBA8,
@@ -921,6 +918,39 @@ void RageDisplay_OGL::DeleteTexture( unsigned uTexHandle )
} }
PixelFormat RageDisplay_OGL::GetImgPixelFormat( SDL_Surface* &img, bool &FreeImg, int width, int height )
{
PixelFormat pixfmt = FindPixelFormat( img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask );
if( pixfmt == NUM_PIX_FORMATS )
{
/* The source isn't in a supported, known pixel format. We need to convert
* it ourself. Just convert it to RGBA8, and let OpenGL convert it back
* down to whatever the actual pixel format is. This is a very slow code
* path, which should almost never be used. */
pixfmt = FMT_RGBA8;
const PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
SDL_SetAlpha( img, 0, SDL_ALPHA_OPAQUE );
SDL_Rect area;
area.x = area.y = 0;
area.w = short(width);
area.h = short(height);
SDL_Surface *imgconv = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, width, height,
pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]);
SDL_BlitSurface(img, &area, imgconv, &area);
img = imgconv;
FreeImg = true;
}
else
FreeImg = false;
return pixfmt;
}
unsigned RageDisplay_OGL::CreateTexture( unsigned RageDisplay_OGL::CreateTexture(
PixelFormat pixfmt, PixelFormat pixfmt,
SDL_Surface*& img ) SDL_Surface*& img )
@@ -939,6 +969,10 @@ unsigned RageDisplay_OGL::CreateTexture(
ASSERT( img->w == power_of_two(img->w) ); ASSERT( img->w == power_of_two(img->w) );
ASSERT( img->h == power_of_two(img->h) ); ASSERT( img->h == power_of_two(img->h) );
/* Find the pixel format of the image we've been given. */
bool FreeImg;
PixelFormat imgpixfmt = GetImgPixelFormat( img, FreeImg, img->w, img->h );
if(pixfmt == FMT_PAL) if(pixfmt == FMT_PAL)
{ {
/* The image is paletted. Let's try to set up a paletted texture. */ /* The image is paletted. Let's try to set up a paletted texture. */
@@ -970,8 +1004,8 @@ unsigned RageDisplay_OGL::CreateTexture(
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel); glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
GLenum glTexFormat = GL_PIXFMT_INFO[pixfmt].internalfmt; GLenum glTexFormat = GL_PIXFMT_INFO[pixfmt].internalfmt;
GLenum glImageFormat = GL_PIXFMT_INFO[pixfmt].format; GLenum glImageFormat = GL_PIXFMT_INFO[imgpixfmt].format;
GLenum glImageType = GL_PIXFMT_INFO[pixfmt].type; GLenum glImageType = GL_PIXFMT_INFO[imgpixfmt].type;
FlushGLErrors(); FlushGLErrors();
@@ -994,6 +1028,8 @@ unsigned RageDisplay_OGL::CreateTexture(
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glFlush(); glFlush();
if( FreeImg )
SDL_FreeSurface( img );
return uTexHandle; return uTexHandle;
} }
@@ -1007,29 +1043,8 @@ void RageDisplay_OGL::UpdateTexture(
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel); glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
PixelFormat pixfmt = FindPixelFormat( img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask ); bool FreeImg;
SDL_Surface *imgconv = NULL; PixelFormat pixfmt = GetImgPixelFormat( img, FreeImg, width, height );
if( pixfmt == NUM_PIX_FORMATS )
{
/* The source isn't in a supported, known pixel format. We need to convert
* it ourself. Just convert it to RGBA8, and let OpenGL convert it back
* down to whatever the actual pixel format is. This is a very slow code
* path, which should almost never be used. */
pixfmt = FMT_RGBA8;
const PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
SDL_SetAlpha( img, 0, SDL_ALPHA_OPAQUE );
SDL_Rect area;
area.x = area.y = 0;
area.w = short(width);
area.h = short(height);
imgconv = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, width, height,
pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]);
SDL_BlitSurface(img, &area, imgconv, &area);
img = imgconv;
}
// GLenum glTexFormat = GL_PIXFMT_INFO[pixfmt].internalfmt; // GLenum glTexFormat = GL_PIXFMT_INFO[pixfmt].internalfmt;
GLenum glImageFormat = GL_PIXFMT_INFO[pixfmt].format; GLenum glImageFormat = GL_PIXFMT_INFO[pixfmt].format;
@@ -1044,8 +1059,8 @@ void RageDisplay_OGL::UpdateTexture(
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glFlush(); glFlush();
if( imgconv ) if( FreeImg )
SDL_FreeSurface( imgconv ); SDL_FreeSurface( img );
} }
CString RageDisplay_OGL::GetTextureDiagnostics( unsigned id ) const CString RageDisplay_OGL::GetTextureDiagnostics( unsigned id ) const
+1 -1
View File
@@ -65,7 +65,7 @@ protected:
bool TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ); bool TryVideoMode( VideoModeParams params, bool &bNewDeviceOut );
void SetViewport(int shift_left, int shift_down); void SetViewport(int shift_left, int shift_down);
RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf );
PixelFormat GetImgPixelFormat( SDL_Surface* &img, bool &FreeImg, int width, int height );
}; };
#endif #endif