Add helpers: RageDisplay::CreateSurfaceFromPixfmt, RageDisplay::FindPixelFormat.

UpdateTexture can now take any image format; it doesn't have to match the
original format, or even be a standard pixel format.  This is because we
can often do the conversion much more efficiently within UpdateTexture
than we can in the caller.  With D3D, we can convert any source format
as we copy, preventing an extra blit. OpenGL can do it on the fly if
it happens to be a known texture format.

We can figure out the pixel format from the image itself, so there's
no need to pass pixfmt to UpdateTexture.

Add BGR8, for movies with OpenGL.
This commit is contained in:
Glenn Maynard
2003-06-29 08:13:18 +00:00
parent 9bcb468aa0
commit 7951b5f3e7
6 changed files with 131 additions and 14 deletions
+41 -3
View File
@@ -95,6 +95,7 @@ static void SetPalette( unsigned TexResource )
// Cards that don't support palettes with alpha will crash unless
// all entires have full alpha.
// XXX: Since we disable FMT_PAL in SupportsTextureFormat, can we remove this? -glenn
if( ! (g_DeviceCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE) )
for(int j=0; j<256; j++)
pal.p[j].peFlags = 255;
@@ -165,6 +166,9 @@ static const PixelFormatDesc PIXEL_FORMAT_DESC[NUM_PIX_FORMATS] = {
0x00FF00,
0x0000FF,
0x000000 }
}, {
/* BGRA (N/A; OpenGL only) */
0, { 0,0,0,0 }
}, {
/* Paletted */
8,
@@ -183,6 +187,7 @@ static D3DFORMAT D3DFORMATS[NUM_PIX_FORMATS] =
#else
D3DFMT_A8R8G8B8,
#endif
D3DFMT_UNKNOWN, /* no BGR */
D3DFMT_P8
};
@@ -555,6 +560,9 @@ bool RageDisplay_D3D::SupportsTextureFormat( PixelFormat pixfmt )
if( pixfmt == FMT_PAL && !(g_DeviceCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE) )
return false;
if( D3DFORMATS[pixfmt] == D3DFMT_UNKNOWN )
return false;
D3DFORMAT d3dfmt = D3DFORMATS[pixfmt];
HRESULT hr = g_pd3d->CheckDeviceFormat(
D3DADAPTER_DEFAULT,
@@ -563,6 +571,8 @@ bool RageDisplay_D3D::SupportsTextureFormat( PixelFormat pixfmt )
0,
D3DRTYPE_TEXTURE,
d3dfmt);
if(FAILED(hr))
LOG->Trace("format %i not supported", pixfmt);
return SUCCEEDED( hr );
}
@@ -910,20 +920,24 @@ unsigned RageDisplay_D3D::CreateTexture(
g_TexResourceToTexturePalette[uTexHandle] = pal;
}
UpdateTexture( uTexHandle, pixfmt, img, 0, 0, img->w, img->h );
UpdateTexture( uTexHandle, img, 0, 0, img->w, img->h );
return uTexHandle;
}
void RageDisplay_D3D::UpdateTexture(
unsigned uTexHandle,
PixelFormat pixfmt,
SDL_Surface*& img,
SDL_Surface* img,
int xoffset, int yoffset, int width, int height )
{
IDirect3DTexture8* pTex = (IDirect3DTexture8*)uTexHandle;
ASSERT( pTex != NULL );
/* Make sure that the pixel format of the image is legit. We don't actually
* care, but the OpenGL renderer does, so make sure people coding in the D3D
* renderer don't accidentally break the OpenGL one. */
FindPixelFormat( img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask );
RECT rect;
rect.left = xoffset;
rect.top = yoffset;
@@ -933,6 +947,29 @@ void RageDisplay_D3D::UpdateTexture(
D3DLOCKED_RECT lr;
pTex->LockRect( 0, &lr, &rect, 0 );
D3DSURFACE_DESC desc;
pTex->GetLevelDesc(0, &desc);
ASSERT( xoffset+width <= int(desc.Width) );
ASSERT( yoffset+height <= int(desc.Height) );
int texpixfmt;
for(texpixfmt = 0; texpixfmt < NUM_PIX_FORMATS; ++texpixfmt)
if(D3DFORMATS[texpixfmt] == desc.Format) break;
ASSERT( texpixfmt != NUM_PIX_FORMATS );
SDL_Surface *Texture = CreateSurfaceFromPixfmt(PixelFormat(texpixfmt), lr.pBits, width, height, lr.Pitch);
SDL_Rect area;
area.x = area.y = 0;
area.w = (Uint16) width;
area.h = (Uint16) height;
SDL_SetAlpha( img, 0, SDL_ALPHA_OPAQUE );
// SDL_SetColorKey( img, 0, 0 );
// SDL_BlitSurface( img, &area, Texture, &area );
mySDL_BlitSurface( img, Texture, width, height, false );
SDL_FreeSurface( Texture );
#if 0
// copy each row
int bytes_per_pixel = img->format->BytesPerPixel;
for( int y=rect.top; y<rect.bottom; y++ )
@@ -941,6 +978,7 @@ void RageDisplay_D3D::UpdateTexture(
char* dst = (char*)lr.pBits + y*lr.Pitch + rect.left*bytes_per_pixel;
memcpy( dst, src, (rect.right-rect.left)*bytes_per_pixel );
}
#endif
pTex->UnlockRect( 0 );
}