Reorganize RageDisplay

Add Direct3D renderer (separate project configuration)
Add Xbox project config (doesn't yet compile)
This commit is contained in:
Chris Danford
2003-05-22 05:28:37 +00:00
parent 8f87e27031
commit 02016ae442
35 changed files with 6051 additions and 1498 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
+2 -1
View File
@@ -292,6 +292,7 @@ void BitmapText::DrawPrimitives()
if( m_szTextLines.empty() )
return;
Actor::SetRenderStates(); // set Actor-specified render states
DISPLAY->SetTextureModeModulate();
/* Draw if we're not fully transparent or the zbuffer is enabled */
@@ -303,7 +304,7 @@ void BitmapText::DrawPrimitives()
if( m_bShadow )
{
DISPLAY->PushMatrix();
DISPLAY->TranslateLocal( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
RageColor dim(0,0,0,0.5f*m_temp.diffuse[0].a); // semi-transparent black
+1 -1
View File
@@ -50,7 +50,7 @@ void GhostArrow::Step( TapNoteScore score )
// HACK: set the length of each frame so the animation plays in exactly 1 pop up time.
// We can't do this in the constructor because the image hasn't been loaded yet
for( int i=0; i<Sprite::GetNumStates(); i++ )
Sprite::m_fDelay[i] = GA_SHOW_SECONDS / Sprite::GetNumStates();
Sprite::m_States[i].fDelay = GA_SHOW_SECONDS / Sprite::GetNumStates();
RageColor colorStart;
switch( score )
+1 -1
View File
@@ -50,7 +50,7 @@ void GhostArrowBright::Step( TapNoteScore score )
// HACK: set the length of each frame so the animation plays in exactly 1 pop up time.
// We can't do this in the constructor because the image hasn't been loaded yet
for( int i=0; i<Sprite::GetNumStates(); i++ )
Sprite::m_fDelay[i] = GAB_SHOW_SECONDS / Sprite::GetNumStates();
Sprite::m_States[i].fDelay = GAB_SHOW_SECONDS / Sprite::GetNumStates();
RageColor colorStart;
switch( score )
+13 -10
View File
@@ -120,25 +120,28 @@ void GrooveGraph::Mountain::DrawPrimitives()
{
DISPLAY->SetTexture( NULL );
DISPLAY->SetTextureModeModulate();
RageVertex v[3];
RageVertex v[4];
for( int i=NUM_DIFFICULTIES-1; i>=0; i-- )
{
float fValue = SCALE(m_fPercentTowardNew, 0.f, 1.f, m_fValuesOld[i], m_fValuesNew[i] );
float fHeight = MOUNTAIN_HEIGHT*fValue;
v[0].p = RageVector3( -MOUNTAIN_WIDTH/2, 0, 0 );
v[0].p = v[3].p = RageVector3( -MOUNTAIN_WIDTH/2, 0, 0 );
v[1].p = RageVector3( MOUNTAIN_WIDTH/2, 0, 0 );
v[2].p = RageVector3( 0, -fHeight, 0 );
v[0].c = v[1].c = v[2].c = g_DifficultyColorsCache[i];
v[0].c = v[1].c = v[2].c = v[3].c = g_DifficultyColorsCache[i];
DISPLAY->DrawFan( v, 3 );
}
switch( PREFSMAN->m_iPolygonRadar )
{
case 0: DISPLAY->DrawLoop_LinesAndPoints( v, 3, 2 ); break;
case 1: DISPLAY->DrawLoop_Polys( v, 3, 2 ); break;
default:
case -1: DISPLAY->DrawLoop( v, 3, 2 ); break;
}
// TODO: Add this back in
// switch( PREFSMAN->m_iPolygonRadar )
// {
// case 0: DISPLAY->DrawLoop_LinesAndPoints( v, 3, 2 ); break;
// case 1: DISPLAY->DrawLoop_Polys( v, 3, 2 ); break;
// default:
// case -1:
DISPLAY->DrawLineStrip( v, 4, 2 );
// break;
// }
}
+11 -8
View File
@@ -186,7 +186,7 @@ void GrooveRadar::GrooveRadarValueMap::DrawPrimitives()
//
// use a line loop to draw the thick line
//
for( i=0; i<NUM_RADAR_CATEGORIES; i++ )
for( i=0; i<=NUM_RADAR_CATEGORIES; i++ )
{
const int c = i%NUM_RADAR_CATEGORIES;
const float fDistFromCenter =
@@ -199,13 +199,16 @@ void GrooveRadar::GrooveRadarValueMap::DrawPrimitives()
v[i].c = PlayerToColor( (PlayerNumber)p );
}
switch( PREFSMAN->m_iPolygonRadar )
{
case 0: DISPLAY->DrawLoop_LinesAndPoints( v, NUM_RADAR_CATEGORIES, RADAR_EDGE_WIDTH ); break;
case 1: DISPLAY->DrawLoop_Polys( v, NUM_RADAR_CATEGORIES, RADAR_EDGE_WIDTH ); break;
default:
case -1: DISPLAY->DrawLoop( v, NUM_RADAR_CATEGORIES, RADAR_EDGE_WIDTH ); break;
}
// TODO: Add this back in. -Chris
// switch( PREFSMAN->m_iPolygonRadar )
// {
// case 0: DISPLAY->DrawLoop_LinesAndPoints( v, NUM_RADAR_CATEGORIES, RADAR_EDGE_WIDTH ); break;
// case 1: DISPLAY->DrawLoop_Polys( v, NUM_RADAR_CATEGORIES, RADAR_EDGE_WIDTH ); break;
// default:
// case -1:
DISPLAY->DrawLineStrip( v, NUM_RADAR_CATEGORIES+1, RADAR_EDGE_WIDTH );
// break;
// }
}
}
+1 -1
View File
@@ -181,7 +181,7 @@ void Inventory::UseItem( int iSlot )
if( asInventory[iSlot].IsBlank() )
return;
PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber];
// PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber];
GameState::Attack a = asInventory[iSlot];
// GAMESTATE->LaunchAttack( pnToAttack, a );
+1 -2
View File
@@ -725,11 +725,10 @@ bool Model::LoadMilkshapeAsciiBones( CString sPath )
void Model::DrawPrimitives()
{
if (!m_pModel)
return;
Actor::DrawPrimitives(); // set Actor-specified render states
Actor::SetRenderStates(); // set Actor-specified render states
DISPLAY->Scale( 1, -1, 1 ); // flip Y so positive is up
+6 -1
View File
@@ -125,6 +125,12 @@ void NoteMetricCache_t::Load(PlayerNumber pn, const CString &name)
NoteDisplay::NoteDisplay()
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_pTapNote[i] = NULL;
m_pHoldHeadActive[i] = NULL;
m_pHoldHeadInactive[i] = NULL;
}
cache = new NoteMetricCache_t;
}
@@ -136,7 +142,6 @@ NoteDisplay::~NoteDisplay()
delete m_pHoldHeadActive[i];
delete m_pHoldHeadInactive[i];
}
delete cache;
}
+132 -337
View File
@@ -16,7 +16,7 @@
#include "RageLog.h"
#include "RageException.h"
#include "RageDisplay.h"
#include "RageDisplayInternal.h"
#include "RageTypes.h"
#include "SDL.h"
#include "SDL_image.h"
@@ -27,84 +27,6 @@
#include "RageTimer.h"
enum pixfmts {
FMT_RGBA8,
FMT_RGBA4,
FMT_RGB5A1,
FMT_PAL,
NUM_PIX_FORMATS
};
/* Return true for pixfmts that need to be converted to FMT_RGBA8 for GLDirect
* (those with packed pixel data types). */
static bool IsPackedPixelFormat(GLenum pixfmt)
{
return pixfmt == FMT_RGBA4 || pixfmt == FMT_RGB5A1;
}
/* Definitions for various texture formats. We'll probably want RGBA
* in OpenGL, not ARGB ... All of these are in local (little) endian;
* this may or may not need adjustment for OpenGL. */
struct PixFmt_t {
int bpp;
GLenum internalfmt; /* target format */
GLenum format; /* target format */
GLenum type; /* data format */
unsigned int masks[4];
} PixFmtMasks[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. */
{
/* B8G8R8A8 */
32,
GL_RGBA8,
GL_RGBA,
GL_UNSIGNED_BYTE,
{ 0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000 }
}, {
/* B4G4R4A4 */
16,
GL_RGBA4,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
{ 0xF000,
0x0F00,
0x00F0,
0x000F },
}, {
/* B5G5R5A1 */
16,
GL_RGB5_A1,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
{ 0xF800,
0x07C0,
0x003E,
0x0001 },
}, {
/* Paletted */
8,
GL_COLOR_INDEX8_EXT,
GL_COLOR_INDEX,
GL_UNSIGNED_BYTE,
{ 0,0,0,0 } /* N/A */
}
};
int PixFmtMaskNo(GLenum fmt)
{
switch(fmt) {
case GL_RGBA8: return FMT_RGBA8;
case GL_RGBA4: return FMT_RGBA4;
case GL_RGB5_A1: return FMT_RGB5A1;
default: ASSERT(0); return FMT_RGBA8;
}
}
static void GetResolutionFromFileName( CString sPath, int &Width, int &Height )
{
/* Match:
@@ -130,42 +52,33 @@ RageBitmapTexture::RageBitmapTexture( RageTextureID name ) :
RageTexture( name )
{
// LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
m_uGLTextureID = 0;
Create(); // sFilePath and prefs are saved by RageTexture()
Create();
}
RageBitmapTexture::~RageBitmapTexture()
{
if(m_uGLTextureID)
glDeleteTextures(1,reinterpret_cast<GLuint*>(&m_uGLTextureID));
Destroy();
}
void RageBitmapTexture::Reload()
{
RageTexture::Reload();
DISPLAY->SetTexture(0);
if(m_uGLTextureID)
{
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_uGLTextureID));
m_uGLTextureID = 0;
}
Destroy();
Create();
}
/* 1. Create (and return) a surface ready to be loaded to OpenGL,
* 2. Set up m_ActualID, and
* 3. Set these texture parameters:
* m_iSourceWidth, m_iSourceHeight
* m_iTextureWidth, m_iTextureHeight
* m_iImageWidth, m_iImageHeight
* m_iFramesWide, m_iFramesHigh
/*
* Each dwMaxSize, dwTextureColorDepth and iAlphaBits are maximums; we may
* use less. iAlphaBits must be 0, 1 or 4.
*
* XXX: change iAlphaBits == 4 to iAlphaBits == 8 to indicate "as much alpha
* as needed", since that's what it really is; still only use 4 in 16-bit textures.
*
* Dither forces dithering when loading 16-bit textures.
* Stretch forces the loaded image to fill the texture completely.
*/
SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
void RageBitmapTexture::Create()
{
/* Create (and return) a surface ready to be loaded to OpenGL */
/* Load the image into an SDL surface. */
SDL_Surface *img = IMG_Load(GetFilePath());
@@ -174,7 +87,7 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
if(img == NULL)
RageException::Throw( "RageBitmapTexture: Couldn't load %s: %s", GetFilePath().c_str(), SDL_GetError() );
if(m_ActualID.bHotPinkColorKey)
if(m_ID.bHotPinkColorKey)
{
/* Annoying: SDL will do a nearest-match on paletted images if
* they don't have the color we ask for, so images without HOT PINK
@@ -199,79 +112,46 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
* TRAIT_NO_TRANSPARENCY if the color key is never used. */
int traits = FindSurfaceTraits(img);
if(traits & TRAIT_NO_TRANSPARENCY)
m_ActualID.iAlphaBits = 0;
m_ID.iAlphaBits = 0;
else if(traits & TRAIT_BOOL_TRANSPARENCY)
m_ActualID.iAlphaBits = 1;
m_ID.iAlphaBits = 1;
if(traits & TRAIT_WHITE_ONLY)
m_ActualID.iTransparencyOnly = 8;
m_ID.iTransparencyOnly = 8;
}
// look in the file name for a format hints
CString HintString = GetFilePath();
HintString.MakeLower();
if( HintString.Find("4alphaonly") != -1 ) m_ActualID.iTransparencyOnly = 4;
else if( HintString.Find("8alphaonly") != -1 ) m_ActualID.iTransparencyOnly = 8;
if( HintString.Find("dither") != -1 ) m_ActualID.bDither = true;
if( HintString.Find("4alphaonly") != -1 ) m_ID.iTransparencyOnly = 4;
else if( HintString.Find("8alphaonly") != -1 ) m_ID.iTransparencyOnly = 8;
if( HintString.Find("dither") != -1 ) m_ID.bDither = true;
if( m_ActualID.iTransparencyOnly )
{
/* Treat the image as 32-bit, so we don't lose any alpha precision. */
m_ActualID.iColorDepth = 32;
}
GLenum fmtTexture;
/* Figure out which texture format to use. */
if( m_ActualID.iColorDepth == 16 )
{
/* Bits of alpha in the source: */
int src_alpha_bits = 8 - img->format->Aloss;
/* No real alpha in paletted input. */
if( img->format->BytesPerPixel == 1 )
src_alpha_bits = 0;
/* Colorkeyed input effectively has at least one bit of alpha: */
if( img->flags & SDL_SRCCOLORKEY )
src_alpha_bits = max( 1, src_alpha_bits );
/* Don't use more than we were hinted to. */
src_alpha_bits = min( m_ActualID.iAlphaBits, src_alpha_bits );
switch( src_alpha_bits ) {
case 0:
case 1:
fmtTexture = GL_RGB5_A1;
break;
default:
fmtTexture = GL_RGBA4;
break;
}
}
else if( m_ActualID.iColorDepth == 32)
fmtTexture = GL_RGBA8;
else
RageException::Throw( "Invalid color depth: %d bits", m_ActualID.iColorDepth );
if( m_ID.iTransparencyOnly )
m_ID.iColorDepth = 32; /* Treat the image as 32-bit, so we don't lose any alpha precision. */
/* Cap the max texture size to the hardware max. */
m_ActualID.iMaxSize = min( m_ActualID.iMaxSize, DISPLAY->GetMaxTextureSize() );
m_ID.iMaxSize = min( m_ID.iMaxSize, DISPLAY->GetMaxTextureSize() );
/* Save information about the source. */
m_iSourceWidth = img->w;
m_iSourceHeight = img->h;
/* See if the apparent "size" is being overridden. */
GetResolutionFromFileName(m_ID.filename, m_iSourceWidth, m_iSourceHeight);
/* image size cannot exceed max size */
m_iImageWidth = min( m_iSourceWidth, m_ActualID.iMaxSize );
m_iImageHeight = min( m_iSourceHeight, m_ActualID.iMaxSize );
m_iImageWidth = min( m_iSourceWidth, m_ID.iMaxSize );
m_iImageHeight = min( m_iSourceHeight, m_ID.iMaxSize );
/* Texture dimensions need to be a power of two; jump to the next. */
m_iTextureWidth = power_of_two(m_iImageWidth);
m_iTextureHeight = power_of_two(m_iImageHeight);
ASSERT( m_iTextureWidth <= m_ActualID.iMaxSize );
ASSERT( m_iTextureHeight <= m_ActualID.iMaxSize );
ASSERT( m_iTextureWidth <= m_ID.iMaxSize );
ASSERT( m_iTextureHeight <= m_ID.iMaxSize );
if(m_ActualID.bStretch)
if(m_ID.bStretch)
{
/* The hints asked for the image to be stretched to the texture size,
* probably for tiling. */
@@ -279,225 +159,140 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
m_iImageHeight = m_iTextureHeight;
}
/* If the source is larger than the texture, we have to scale it to fit. */
if(m_iSourceWidth > m_iImageWidth || m_iSourceHeight > m_iImageHeight)
m_ActualID.bStretch = true;
pixfmt = PixFmtMaskNo(fmtTexture);
if( m_ActualID.bStretch )
if( img->w != m_iImageWidth || img->h != m_iImageHeight )
{
/* resize currently only does RGBA8888 */
int mask = 0;
ConvertSDLSurface(img, img->w, img->h, PixFmtMasks[mask].bpp,
PixFmtMasks[mask].masks[0], PixFmtMasks[mask].masks[1],
PixFmtMasks[mask].masks[2], PixFmtMasks[mask].masks[3]);
ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
zoomSurface(img, m_iImageWidth, m_iImageHeight );
}
/* See if the apparent "size" is being overridden. */
GetResolutionFromFileName(m_ActualID.filename, m_iSourceWidth, m_iSourceHeight);
return img;
}
// Format of the image that we will pass to OpenGL and that we want OpenGL to use
PixelFormat pixfmt;
/*
* Each dwMaxSize, dwTextureColorDepth and iAlphaBits are maximums; we may
* use less. iAlphaBits must be 0, 1 or 4.
*
* XXX: change iAlphaBits == 4 to iAlphaBits == 8 to indicate "as much alpha
* as needed", since that's what it really is; still only use 4 in 16-bit textures.
*
* Dither forces dithering when loading 16-bit textures.
* Stretch forces the loaded image to fill the texture completely.
*/
void RageBitmapTexture::Create()
{
/* This will be set to the pixfmt we should use if we use an RGBA texture. */
int desired_rgba_pixfmt;
SDL_SaveBMP( img, "testing.bmp" );
SDL_Surface *img = CreateImg(desired_rgba_pixfmt);
if(!m_uGLTextureID)
glGenTextures(1, reinterpret_cast<GLuint*>(&m_uGLTextureID));
ASSERT(m_uGLTextureID);
DISPLAY->SetTexture(this);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
/* This is an experiment: some people are seeing skips when the danger
* background comes in. One hypothesis: we're loading the danger background,
* keeping it in memory without displaying it for several games, it gets
* swapped out of texture memory, and then we skip swapping it in.
*
* It's rather small, so I'm not entirely convinced this is what's happening.
* Let's try boosting the texture priority for the danger background and
* see if it goes away. If it does, I'll make texture pris a texture hint
* (or find another way to do this; perhaps we should do a dummy render of
* a texture when it's reused from our texture cache if it hasn't been used
* in a long time). */
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5f);
if(GetFilePath().Find("danger") != -1)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0f);
int pixfmt = desired_rgba_pixfmt;
retry:
if(img->format->BitsPerPixel == 8 && DISPLAY->GetSpecs().EXT_paletted_texture)
pixfmt = FMT_PAL;
if(pixfmt != FMT_PAL)
/* Figure out which texture format to use. */
// if the source is palleted, load palleted no matter what the prefs
if(img->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(FMT_PAL))
{
pixfmt = FMT_PAL;
}
else
{
// not paletted
switch( m_ID.iColorDepth )
{
case 16:
{
/* Bits of alpha in the source: */
int src_alpha_bits = 8 - img->format->Aloss;
/* No real alpha in paletted input. */
if( img->format->BytesPerPixel == 1 )
src_alpha_bits = 0;
/* Colorkeyed input effectively has at least one bit of alpha: */
if( img->flags & SDL_SRCCOLORKEY )
src_alpha_bits = max( 1, src_alpha_bits );
/* Don't use more than we were hinted to. */
src_alpha_bits = min( m_ID.iAlphaBits, src_alpha_bits );
switch( src_alpha_bits ) {
case 0:
case 1:
pixfmt = FMT_RGB5A1;
break;
default:
pixfmt = FMT_RGBA4;
break;
}
}
break;
case 32:
pixfmt = FMT_RGBA8;
break;
default:
RageException::Throw( "Invalid color depth: %d bits", m_ID.iColorDepth );
}
/* Override the internalformat with an alpha format if it was requested.
* Don't use iTransparencyOnly with paletted images; there's no point--paletted
* images are as small or smaller (and the load will fail). */
/* SDL surfaces don't allow for 8 bpp surfaces that aren't paletted. Arg!
* fix this later. -Chris */
// if(m_ID.iTransparencyOnly > 0)
// {
// imagePixfmt = FMT_ALPHA8;
// texturePixfmt = FMT_ALPHA8;
// }
/* It's either not a paletted image, or we can't handle paletted textures.
* Convert to the desired RGBA format, dithering if appropriate. */
/* Never dither when the target is 32bpp; there's no point. */
if( PixFmtMasks[pixfmt].bpp == 32)
m_ActualID.bDither = false;
if( m_ActualID.bDither )
if( m_ID.bDither &&
(pixfmt==FMT_RGBA4 || pixfmt==FMT_RGB5A1) ) /* Don't dither if format is 32bpp; there's no point. */
{
/* Dither down to the destination format. */
SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, PixFmtMasks[pixfmt].bpp,
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, PIXEL_FORMAT_DESC[pixfmt].bpp,
PIXEL_FORMAT_DESC[pixfmt].masks[0], PIXEL_FORMAT_DESC[pixfmt].masks[1],
PIXEL_FORMAT_DESC[pixfmt].masks[2], PIXEL_FORMAT_DESC[pixfmt].masks[3]);
//SM_SDL_OrderedDither(img, dst);
SM_SDL_ErrorDiffusionDither(img, dst);
SDL_FreeSurface(img);
img = dst;
}
}
/* Convert the data to the destination format if it's not in it already. */
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PixFmtMasks[pixfmt].bpp,
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
SDL_SaveBMP( img, "testing.bmp" );
/* This needs to be done *after* the final resize, since that resize
* may introduce new alpha bits that need to be set. It needs to be
* done *before* we set up the palette, since it might change it. */
FixHiddenAlpha(img);
if(pixfmt == FMT_PAL)
{
/* The image is currently paletted. Let's try to set up a paletted texture. */
GLubyte palette[256*4];
memset(palette, 0, sizeof(palette));
int p = 0;
/* Copy the palette to the simple, unpacked data OGL expects. If
* we're color keyed, change it over as we go. */
for(int i = 0; i < img->format->palette->ncolors; ++i)
{
palette[p++] = img->format->palette->colors[i].r;
palette[p++] = img->format->palette->colors[i].g;
palette[p++] = img->format->palette->colors[i].b;
SDL_SaveBMP( img, "testing.bmp" );
if(img->flags & SDL_SRCCOLORKEY && i == int(img->format->colorkey))
palette[p++] = 0;
else
palette[p++] = 0xFF; /* opaque */
}
/* Convert the data to the destination format and dimensions
* required by OpenGL if it's not in it already. */
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PIXEL_FORMAT_DESC[pixfmt].bpp,
PIXEL_FORMAT_DESC[pixfmt].masks[0], PIXEL_FORMAT_DESC[pixfmt].masks[1],
PIXEL_FORMAT_DESC[pixfmt].masks[2], PIXEL_FORMAT_DESC[pixfmt].masks[3]);
SDL_SaveBMP( img, "testing.bmp" );
/* Set the palette. */
GLExt::glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette);
m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img );
GLint RealFormat = 0;
GLExt::glGetColorTableParameterivEXT(GL_TEXTURE_2D, GL_COLOR_TABLE_FORMAT, &RealFormat);
if(RealFormat != GL_RGBA8)
{
/* This is a case I don't expect to happen; if it does, log,
* turn off PT's permanently and continue as an RGBA texture. */
LOG->Info("Expected an RGBA8 palette, got %i instead; disabling paletted textures", RealFormat);
DISPLAY->DisablePalettedTexture();
pixfmt = desired_rgba_pixfmt;
goto retry;
}
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
GLenum internalfmt = PixFmtMasks[pixfmt].internalfmt;
if(DISPLAY->GetSpecs().bPackedPixelsCauseProblems &&
IsPackedPixelFormat(pixfmt))
{
/* GLDirect crashes if we give it packed pixel format. We need
* to convert to a non-packed format (FMT_RGBA8). However, we
* can still get 16-bit textures by passing it the appropriate
* internalformat; it'll simply truncate the extra bits. This
* means that it'll still use the dithering we gave it; we just
* have to do a bit of redundant conversion work. */
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PixFmtMasks[FMT_RGBA8].bpp,
PixFmtMasks[FMT_RGBA8].masks[0], PixFmtMasks[FMT_RGBA8].masks[1],
PixFmtMasks[FMT_RGBA8].masks[2], PixFmtMasks[FMT_RGBA8].masks[3]);
pixfmt = FMT_RGBA8;
/* (don't change internalfmt) */
}
if(internalfmt != GL_COLOR_INDEX8_EXT)
{
/* Override the internalformat with an alpha format if it was requested.
* Don't use iTransparencyOnly with paletted images; there's no point--paletted
* images are as small or smaller (and the load will fail). */
if(m_ActualID.iTransparencyOnly == 4)
internalfmt = GL_ALPHA4;
else if(m_ActualID.iTransparencyOnly == 8)
internalfmt = GL_ALPHA8;
else ASSERT(m_ActualID.iTransparencyOnly == 0);
}
glTexImage2D(GL_TEXTURE_2D, 0, internalfmt,
m_iTextureWidth, m_iTextureHeight, 0,
PixFmtMasks[pixfmt].format, PixFmtMasks[pixfmt].type, img->pixels);
/* If we're paletted, and didn't get the 8-bit palette we asked for ...*/
if(img->format->BitsPerPixel == 8)
{
GLint size = 0;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GLenum(GL_TEXTURE_INDEX_SIZE_EXT), &size);
if(size != 8)
{
/* I don't know any reason this should actually fail (paletted textures
* but no support for 8-bit palettes?), so let's just disable paletted
* textures the first time this happens. */
LOG->Info("Expected an 8-bit palette, got a %i-bit one instead; disabling paletted textures", size);
DISPLAY->DisablePalettedTexture();
pixfmt = desired_rgba_pixfmt;
goto retry;
}
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glFlush();
SDL_FreeSurface(img);
SDL_FreeSurface( img );
CreateFrameRects();
CString props = " ";
switch( internalfmt )
{
case GL_RGBA4: props += "GL_RGBA4 "; break;
case GL_RGBA8: props += "GL_RGBA8 "; break;
case GL_RGB5_A1: props += "GL_RGB5_A1 "; break;
case GL_ALPHA8: props += "GL_ALPHA8 "; break;
case GL_COLOR_INDEX8_EXT: props += "GL_COLOR_INDEX8_EXT "; break;
default: props += ssprintf("unknown-format-%d ",internalfmt); break;
}
if(m_ActualID.iAlphaBits == 0) props += "opaque ";
if(m_ActualID.iAlphaBits == 1) props += "matte ";
if(m_ActualID.iTransparencyOnly) props += "mask ";
if(m_ActualID.bStretch) props += "stretch ";
if(m_ActualID.bDither) props += "dither ";
/*
CString props = " ";
switch( pixfmt )
{
case FMT_RGBA4: props += "FMT_RGBA4 "; break;
case FMT_RGBA8: props += "FMT_RGBA8 "; break;
case FMT_RGB5A1: props += "FMT_RGB5A1 "; break;
case FMT_ALPHA8: props += "FMT_ALPHA8 "; break;
case FMT_PAL: props += "FMT_PAL "; break;
default: ASSERT(0); break;
}
if(m_ID.iAlphaBits == 0) props += "opaque ";
if(m_ID.iAlphaBits == 1) props += "matte ";
if(m_ID.iTransparencyOnly) props += "mask ";
if(m_ID.bStretch) props += "stretch ";
if(m_ID.bDither) props += "dither ";
if(IsPackedPixelFormat(pixfmt)) props += "paletted ";
props.erase(props.size()-1);
LOG->Trace( "RageBitmapTexture: Loaded '%s' (%ux%u); %s, source %d,%d; image %d,%d.",
m_ActualID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
m_ID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
props.c_str(), m_iSourceWidth, m_iSourceHeight,
m_iImageWidth, m_iImageHeight);
*/
}
void RageBitmapTexture::Destroy()
{
DISPLAY->DeleteTexture( m_uTexHandle );
}
+5 -5
View File
@@ -13,22 +13,22 @@
*/
#include "RageTexture.h"
#include "RageDisplayInternal.h"
struct SDL_Surface;
class RageBitmapTexture : public RageTexture
{
public:
RageBitmapTexture( RageTextureID name );
virtual ~RageBitmapTexture();
/* only called by RageTextureManager::InvalidateTextures */
virtual void Invalidate() { m_uGLTextureID = 0; }
virtual void Invalidate() { m_uTexHandle = 0; /* don't Destroy() */}
virtual void Reload();
virtual unsigned GetTexHandle() { return m_uTexHandle; }; // accessed by RageDisplay
private:
void Create(); // called by constructor and Reload
unsigned int GetGLTextureID() { return m_uGLTextureID; }
unsigned int m_uGLTextureID;
void Destroy();
unsigned m_uTexHandle; // treat as unsigned in OpenGL, ID3D8Texture* for D3D
SDL_Surface *CreateImg(int &pixfmt);
};
File diff suppressed because it is too large Load Diff
+87 -45
View File
@@ -4,24 +4,53 @@
-----------------------------------------------------------------------------
Class: RageDisplay
Desc: Wrapper around a D3D device. Also holds global vertex and index
buffers that dynamic geometry can use to render.
Desc: Wrapper around a graphics device.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
class RageTexture;
struct RageMatrix;
struct RageVertex;
#include "SDL_types.h"
#include "RageTypes.h"
const int REFRESH_DEFAULT = 0;
struct oglspecs_t;
struct SDL_Surface;
// VertexArray holds vertex data in a format that is most efficient for
// the graphics API.
/*struct VertexArray
{
VertexArray();
~VertexArray();
unsigned size();
void resize( unsigned new_size );
RageVector2& TexCoord( int index );
RageColor& Color( int index );
RageVector3& Normal( int index );
RageVector3& Position( int index );
// convenience. Remove this later!
void Set( int index, const RageVertex& v );
struct Impl;
Impl* pImpl;
};
*/
enum PixelFormat {
FMT_RGBA8,
FMT_RGBA4,
FMT_RGB5A1,
FMT_RGB5,
FMT_RGB8,
FMT_PAL,
NUM_PIX_FORMATS
};
struct PixelFormatDesc {
int bpp;
unsigned int masks[4];
};
extern const PixelFormatDesc PIXEL_FORMAT_DESC[NUM_PIX_FORMATS];
class RageDisplay
{
@@ -41,30 +70,33 @@ public:
void Clear();
void Flip();
float PredictedSecondsUntilNextFlip() const;
bool IsWindowed() const;
int GetWidth() const;
int GetHeight() const;
int GetBPP() const;
void PushMatrix();
void PopMatrix();
void Translate( float x, float y, float z );
void TranslateLocal( float x, float y, float z );
void Scale( float x, float y, float z );
void RotateX( float r );
void RotateY( float r );
void RotateZ( float r );
void MultMatrix( const RageMatrix &f ) { PostMultMatrix(f); } /* alias */
void PostMultMatrix( const RageMatrix &f );
void PreMultMatrix( const RageMatrix &f );
void SetBlendMode( BlendMode mode );
bool SupportsTextureFormat( PixelFormat pixfmt );
/* return 0 if failed or internal texture resource handle
* (unsigned in OpenGL, texture pointer in D3D) */
unsigned CreateTexture(
PixelFormat pixfmt, // format of img and of texture in video mem
SDL_Surface*& img // must be in pixfmt
);
void UpdateTexture(
unsigned uTexHandle,
PixelFormat pixfmt, // this must be the same as what was passed to CreateTexture
SDL_Surface*& img,
int xoffset, int yoffset, int width, int height
);
void DeleteTexture( unsigned uTexHandle );
void SetTexture( RageTexture* pTexture );
void SetTextureModeModulate();
void SetTextureModeGlow( GlowMode m = GLOW_WHITEN );
void SetTextureModeGlow( GlowMode m=GLOW_WHITEN );
void SetTextureWrapping( bool b );
int GetMaxTextureSize() const;
void SetTextureFiltering( bool b);
bool IsZBufferEnabled() const;
void SetZBuffer( bool b );
@@ -72,6 +104,8 @@ public:
void SetBackfaceCull( bool b );
void SetAlphaTest( bool b );
void SetMaterial(
float emissive[4],
float ambient[4],
@@ -89,48 +123,56 @@ public:
RageColor specular,
RageVector3 dir );
void DrawQuad( const RageVertex v[4] ); // upper-left, upper-right, lower-left, lower-right
void DrawQuad( const RageVertex v[] ) { DrawQuads(v,4); } /* alias. upper-left, upper-right, lower-left, lower-right */
void DrawQuads( const RageVertex v[], int iNumVerts );
void DrawFan( const RageVertex v[], int iNumVerts );
void DrawStrip( const RageVertex v[], int iNumVerts );
void DrawTriangles( const RageVertex v[], int iNumVerts );
void DrawIndexedTriangles( const RageVertex v[], const Uint16* pIndices, int iNumIndices );
void DrawLoop( const RageVertex v[], int iNumVerts, float LineWidth );
void DrawLoop_LinesAndPoints( const RageVertex v[], int iNumVerts, float LineWidth );
void DrawLoop_Polys( const RageVertex v[], int iNumVerts, float LineWidth );
void FlushQueue();
void DrawLineStrip( const RageVertex v[], int iNumVerts, float LineWidth );
int GetMaxTextureSize() const;
// This far clipping this might cause Z-fighting if we ever turn the z-buffer on
void LoadMenuPerspective(float fovDegrees);
void EnterPerspective(float fov, bool preserve_loc = true, float near = 1, float far = 1000);
void ExitPerspective();
void LookAt(const RageVector3 &Eye, const RageVector3 &At, const RageVector3 &Up);
void SaveScreenshot( CString sPath );
protected:
void SetViewport(int shift_left, int shift_down);
// Stuff in RageDisplay.cpp
void SetDefaultRenderStates();
public:
/* Statistics */
int GetFPS() const;
int GetVPF() const;
int GetCumFPS() const; /* average FPS since last reset */
void ResetStats();
void ProcessStatsOnFlip();
void StatsAddVerts( int iNumVertsRendered );
const oglspecs_t &GetSpecs() const { return *m_oglspecs; }
void DisablePalettedTexture();
/* Statistics */
void SaveScreenshot( CString sPath );
/* Statistics */
void PushMatrix();
void PopMatrix();
void Translate( float x, float y, float z );
void TranslateWorld( float x, float y, float z );
void Scale( float x, float y, float z );
void RotateX( float deg );
void RotateY( float deg );
void RotateZ( float deg );
void MultMatrix( const RageMatrix &f ) { this->PostMultMatrix(f); } /* alias */
void PostMultMatrix( const RageMatrix &f );
void PreMultMatrix( const RageMatrix &f );
void LoadIdentity();
void LoadMenuPerspective(float fovDegrees);
void EnterPerspective(float fov, bool preserve_loc = true, float znear = 1, float zfar = 1000);
void ExitPerspective();
void LookAt(const RageVector3 &Eye, const RageVector3 &At, const RageVector3 &Up);
protected:
void AddVerts( const RageVertex v[], int iNumVerts );
void SetupOpenGL();
void SetupExtensions();
void SetViewport(int shift_left, int shift_down);
oglspecs_t *m_oglspecs;
/* Don't use this to check extensions; use GetSpecs. */
bool HasExtension(CString ext) const;
void RageDisplay::DumpOpenGLDebugInfo();
const RageMatrix* GetProjection();
const RageMatrix* GetModelViewTop();
void DrawPolyLine(const RageVertex &p1, const RageVertex &p2, float LineWidth );
};
+802
View File
@@ -0,0 +1,802 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: RageDisplay
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
Glenn Maynard
-----------------------------------------------------------------------------
*/
#include "RageDisplay.h"
#include "D3D8.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "RageTimer.h"
#include "RageException.h"
#include "RageTexture.h"
#include "RageTextureManager.h"
#include "RageMath.h"
#include "RageTypes.h"
#include "GameConstantsAndTypes.h"
#include "StepMania.h"
#include "RageUtil.h"
#include "D3dx8math.h"
#include "SDL_video.h" // for SDL_Surface
#include "SDL_utils.h"
#include "arch/arch.h"
#pragma comment(lib, "D3d8.lib")
#pragma comment(lib, "D3dx8.lib")
#include <math.h>
RageDisplay* DISPLAY = NULL;
//
// Globals
//
LPDIRECT3D8 g_pd3d = NULL;
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
D3DCAPS8 g_DeviceCaps;
D3DDISPLAYMODE g_DesktopMode;
D3DPRESENT_PARAMETERS g_d3dpp;
int g_ModelMatrixCnt=0;
bool g_Windowed;
int g_CurrentHeight, g_CurrentWidth, g_CurrentBPP;
/* Direct3D doesn't associate a palette with textures.
* Instead, we load a palette into a slot. We need to keep track
* of which texture's palette is stored in what slot. */
map<unsigned,int> g_TexResourceToPaletteIndex;
int GetUnusedPaletteIndex()
{
for( int i=0; i<256; i++ )
{
bool bFreeToUse = true;
for( map<unsigned,int>::const_iterator iter=g_TexResourceToPaletteIndex.begin();
iter!=g_TexResourceToPaletteIndex.end();
iter++ )
{
if( iter->second == i )
{
bFreeToUse = false;
break;
}
}
if( bFreeToUse )
return i;
}
ASSERT( 0 ); // couldn't find a free palette index. Resource leak?
return 0;
}
#define D3DFVF_RAGEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1) // D3D FVF flags which describe our vertex structure
const PixelFormatDesc PIXEL_FORMAT_DESC[NUM_PIX_FORMATS] = {
{
/* A8B8G8R8 */
32,
{ 0x00FF0000,
0x0000FF00,
0x000000FF,
0xFF000000 }
}, {
/* A4R4G4B4 */
16,
{ 0x0F00,
0x00F0,
0x000F,
0xF000 },
}, {
/* A1B5G5R5 */
16,
{ 0x7C00,
0x03E0,
0x001F,
0x8000 },
}, {
/* X1R5G5R5 */
16,
{ 0x7C00,
0x03E0,
0x001F,
0x0000 },
}, {
/* B8G8R8 */
24,
{ 0xFF0000,
0x00FF00,
0x0000FF,
0x000000 }
}, {
/* Paletted */
8,
{ 0,0,0,0 } /* N/A */
}
};
RageDisplay::RageDisplay( bool windowed, int width, int height, int bpp, int rate, bool vsync )
{
LOG->Trace( "RageDisplay::RageDisplay()" );
if(!SDL_WasInit(SDL_INIT_VIDEO))
SDL_InitSubSystem(SDL_INIT_VIDEO);
/* By default, ignore all SDL events. We'll enable them as we need them.
* We must not enable any events we don't actually want, since we won't
* query for them and they'll fill up the event queue.
*
* This needs to be done after we initialize video, since it's really part
* of the SDL video system--it'll be reinitialized on us if we do this first. */
SDL_EventState(0xFF /*SDL_ALLEVENTS*/, SDL_IGNORE);
SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE);
g_Windowed = false;
g_pd3d = Direct3DCreate8( D3D_SDK_VERSION );
if( FAILED( g_pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &g_DeviceCaps) ) )
throw RageException(
"There was an error while initializing your video card.\n\n"
"Your system is reporting that Direct3D8 hardware acceleration\n"
"is not available. In most cases, you can download an updated\n"
"driver from your card's manufacturer."
);
D3DADAPTER_IDENTIFIER8 identifier;
g_pd3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &identifier );
LOG->Trace(
"Driver: %s\n"
"Description: %s\n"
"Max texture size: %d\n",
identifier.Driver,
identifier.Description,
g_DeviceCaps.MaxTextureWidth
);
LOG->Trace( "This display adaptor supports the following modes:" );
D3DDISPLAYMODE mode;
for( UINT u=0; u<g_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT); u++ )
if( SUCCEEDED( g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, u, &mode ) ) )
LOG->Trace( " %ux%u %uHz, format %d", mode.Width, mode.Height, mode.RefreshRate, mode.Format );
// Save the original desktop format.
g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_DesktopMode );
SetVideoMode( windowed, width, height, bpp, rate, vsync );
}
void RageDisplay::Update(float fDeltaTime)
{
SDL_Event event;
while(SDL_GetEvent(event, SDL_VIDEORESIZEMASK))
{
switch(event.type)
{
case SDL_VIDEORESIZE:
g_CurrentWidth = event.resize.w;
g_CurrentHeight = event.resize.h;
/* Let DISPLAY know that our resolution has changed. */
ResolutionChanged();
break;
}
}
}
bool RageDisplay::IsSoftwareRenderer()
{
return false;
}
RageDisplay::~RageDisplay()
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE);
g_pd3dDevice->Release();
g_pd3d->Release();
}
D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP)
{
HRESULT hr;
// If windowed, then bpp is ignored. Use whatever works.
vector<D3DFORMAT> vBackBufferFormats; // throw all possibilities in here
/* When windowed, add all formats; otherwise add only formats that match dwBPP. */
if( iBPP == 16 || bWindowed )
{
vBackBufferFormats.push_back( D3DFMT_R5G6B5 );
vBackBufferFormats.push_back( D3DFMT_X1R5G5B5 );
vBackBufferFormats.push_back( D3DFMT_A1R5G5B5 );
}
if( iBPP == 32 || bWindowed )
{
#ifndef _XBOX
vBackBufferFormats.push_back( D3DFMT_R8G8B8 );
#endif
vBackBufferFormats.push_back( D3DFMT_X8R8G8B8 );
vBackBufferFormats.push_back( D3DFMT_A8R8G8B8 );
}
if( !bWindowed && iBPP != 16 && iBPP != 32 )
throw RageException( ssprintf("Invalid BPP '%u' specified", iBPP) );
// Test each back buffer format until we find something that works.
for( unsigned i=0; i < vBackBufferFormats.size(); i++ )
{
D3DFORMAT fmtBackBuffer = vBackBufferFormats[i];
D3DFORMAT fmtDisplay;
if( bWindowed )
fmtDisplay = g_DesktopMode.Format;
else // Fullscreen
fmtDisplay = vBackBufferFormats[i];
LOG->Trace( "Testing format: display %d, back buffer %d, windowed %d...",
fmtDisplay, fmtBackBuffer, bWindowed );
hr = g_pd3d->CheckDeviceType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
fmtDisplay, fmtBackBuffer, bWindowed );
if( FAILED(hr) )
continue; // skip
// done searching
LOG->Trace( "This will work." );
return fmtBackBuffer;
}
RageException::Throw( "Couldn't find an appropriate back buffer format." );
return D3DFMT_UNKNOWN;
}
#ifndef _XBOX
HWND GetHwnd()
{
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if( SDL_GetWMInfo(&info) < 0 )
RageException::Throw( "SDL_GetWMInfo failed" );
return info.window;
}
#endif
/* Set the video mode. */
bool RageDisplay::SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync )
{
int flags = SDL_RESIZABLE;
if( !windowed )
flags |= SDL_FULLSCREEN;
g_Windowed = windowed;
SDL_ShowCursor( g_Windowed );
SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
if(!screen)
RageException::Throw("SDL_SetVideoMode failed: %s", SDL_GetError());
g_CurrentWidth = screen->w;
g_CurrentHeight = screen->h;
g_CurrentBPP = bpp;
ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
g_d3dpp.BackBufferWidth = width;
g_d3dpp.BackBufferHeight = height;
g_d3dpp.BackBufferFormat = FindBackBufferType( windowed, bpp );
g_d3dpp.BackBufferCount = 1;
g_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
#ifndef _XBOX
g_d3dpp.hDeviceWindow = GetHwnd();
#endif
g_d3dpp.Windowed = windowed;
g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
g_d3dpp.Flags = 0;
g_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
/* Windowed must always use D3DPRESENT_INTERVAL_DEFAULT. */
g_d3dpp.FullScreen_PresentationInterval =
(windowed || vsync) ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
if( g_pd3dDevice == NULL ) // device is not yet created. We need to create it
{
g_pd3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
#ifndef _XBOX
GetHwnd(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
#else
NULL,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
#endif
&g_d3dpp,
&g_pd3dDevice );
ASSERT( g_pd3dDevice );
}
else
{
g_pd3dDevice->Reset( &g_d3dpp );
}
ResolutionChanged();
this->SetDefaultRenderStates();
g_pd3dDevice->BeginScene();
return false; // we can always reuse the D3D device
}
void RageDisplay::ResolutionChanged()
{
// no need to clear because D3D uses an overlay
// SetViewport(0,0);
//
// /* Clear any junk that's in the framebuffer. */
// Clear();
// Flip();
}
void RageDisplay::SetViewport(int shift_left, int shift_down)
{
/* left and down are on a 0..SCREEN_WIDTH, 0..SCREEN_HEIGHT scale.
* Scale them to the actual viewport range. */
shift_left = int( shift_left * float(g_CurrentWidth) / SCREEN_WIDTH );
shift_down = int( shift_down * float(g_CurrentWidth) / SCREEN_WIDTH );
D3DVIEWPORT8 viewData = { shift_left, -shift_down, g_CurrentWidth, g_CurrentHeight, 0.f, 1.f };
g_pd3dDevice->SetViewport( &viewData );
}
int RageDisplay::GetMaxTextureSize() const
{
return g_DeviceCaps.MaxTextureWidth;
}
void RageDisplay::Clear()
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
}
void RageDisplay::Flip()
{
g_pd3dDevice->EndScene();
g_pd3dDevice->Present( 0, 0, 0, 0 );
g_pd3dDevice->BeginScene();
ProcessStatsOnFlip();
}
D3DFORMAT D3DFORMATS[NUM_PIX_FORMATS] =
{
D3DFMT_A8R8G8B8,
D3DFMT_A4R4G4B4,
D3DFMT_A1R5G5B5,
D3DFMT_X1R5G5B5,
#ifndef _XBOX
D3DFMT_R8G8B8,
#else
D3DFMT_A8R8G8B8,
#endif
D3DFMT_P8
};
bool RageDisplay::SupportsTextureFormat( PixelFormat pixfmt )
{
D3DFORMAT d3dfmt = D3DFORMATS[pixfmt];
HRESULT hr = g_pd3d->CheckDeviceFormat(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
g_d3dpp.BackBufferFormat,
0,
D3DRTYPE_TEXTURE,
d3dfmt);
return SUCCEEDED( hr );
}
void RageDisplay::SaveScreenshot( CString sPath )
{
#ifndef _XBOX
IDirect3DSurface8* pSurface;
g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface );
D3DXSaveSurfaceToFile( sPath, D3DXIFF_BMP, pSurface, 0, NULL );
pSurface->Release();
#endif
}
bool RageDisplay::IsWindowed() const { return g_Windowed; }
int RageDisplay::GetWidth() const { return g_CurrentWidth; }
int RageDisplay::GetHeight() const { return g_CurrentHeight; }
int RageDisplay::GetBPP() const { return g_CurrentBPP; }
#define SEND_CURRENT_MATRICES \
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)GetProjection() ); \
RageMatrix m; \
/* Convert to OpenGL-style "pixel-centered" coords */ \
RageMatrixTranslation( &m, -0.5f, -0.5f, 0 ); \
RageMatrixMultiply( &m, &m, GetModelViewTop() ); \
g_pd3dDevice->SetTransform( D3DTS_WORLD, (D3DMATRIX*)&m );
void RageDisplay::DrawQuads( const RageVertex v[], int iNumVerts )
{
ASSERT( (iNumVerts%4) == 0 );
if(iNumVerts == 0)
return;
// there isn't a quad primitive in D3D, so we have to fake it with indexed triangles
int iNumQuads = iNumVerts/4;
int iNumTriangles = iNumQuads*2;
int iNumIndices = iNumTriangles*3;
// make a temporary index buffer
static vector<Uint16> vIndices;
unsigned uOldSize = vIndices.size();
unsigned uNewSize = max(uOldSize,(unsigned)iNumIndices);
vIndices.resize( uNewSize );
for( Uint16 i=(Uint16)uOldSize/6; i<(Uint16)iNumQuads; i++ )
{
vIndices[i*6+0] = i*4+0;
vIndices[i*6+1] = i*4+1;
vIndices[i*6+2] = i*4+2;
vIndices[i*6+3] = i*4+2;
vIndices[i*6+4] = i*4+3;
vIndices[i*6+5] = i*4+0;
}
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, // PrimitiveType
0, // MinIndex
iNumVerts, // NumVertices
iNumTriangles, // PrimitiveCount,
&vIndices[0], // pIndexData,
D3DFMT_INDEX16, // IndexDataFormat,
v, // pVertexStreamZeroData,
sizeof(RageVertex) // VertexStreamZeroStride
);
StatsAddVerts( iNumVerts );
}
void RageDisplay::DrawFan( const RageVertex v[], int iNumVerts )
{
ASSERT( iNumVerts >= 3 );
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawPrimitiveUP(
D3DPT_TRIANGLEFAN, // PrimitiveType
iNumVerts-2, // PrimitiveCount,
v, // pVertexStreamZeroData,
sizeof(RageVertex)
);
StatsAddVerts( iNumVerts );
}
void RageDisplay::DrawStrip( const RageVertex v[], int iNumVerts )
{
ASSERT( iNumVerts >= 3 );
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawPrimitiveUP(
D3DPT_TRIANGLESTRIP, // PrimitiveType
iNumVerts-2, // PrimitiveCount,
v, // pVertexStreamZeroData,
sizeof(RageVertex)
);
StatsAddVerts( iNumVerts );
}
void RageDisplay::DrawTriangles( const RageVertex v[], int iNumVerts )
{
if( iNumVerts == 0 )
return;
ASSERT( iNumVerts >= 3 );
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawPrimitiveUP(
D3DPT_TRIANGLELIST, // PrimitiveType
iNumVerts/3, // PrimitiveCount,
v, // pVertexStreamZeroData,
sizeof(RageVertex)
);
StatsAddVerts( iNumVerts );
}
void RageDisplay::DrawIndexedTriangles( const RageVertex v[], const Uint16 pIndices[], int iNumIndices )
{
if( iNumIndices == 0 )
return;
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, // PrimitiveType
0, // MinIndex
iNumIndices, // NumVertices
iNumIndices/3, // PrimitiveCount,
pIndices, // pIndexData,
D3DFMT_INDEX16, // IndexDataFormat,
v, // pVertexStreamZeroData,
sizeof(RageVertex) // VertexStreamZeroStride
);
StatsAddVerts( iNumIndices );
}
void RageDisplay::DrawLineStrip( const RageVertex v[], int iNumVerts, float LineWidth )
{
ASSERT( iNumVerts >= 2 );
g_pd3dDevice->SetRenderState( D3DRS_POINTSIZE, *((DWORD*)&LineWidth) ); // funky cast. See D3DRENDERSTATETYPE doc
g_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
SEND_CURRENT_MATRICES;
g_pd3dDevice->DrawPrimitiveUP(
D3DPT_LINESTRIP, // PrimitiveType
iNumVerts-1, // PrimitiveCount,
v, // pVertexStreamZeroData,
sizeof(RageVertex)
);
StatsAddVerts( iNumVerts );
}
void RageDisplay::SetTexture( RageTexture* pTexture )
{
if( pTexture == NULL )
{
g_pd3dDevice->SetTexture( 0, NULL );
return;
}
unsigned uTexHandle = pTexture->GetTexHandle();
IDirect3DTexture8* pTex = (IDirect3DTexture8*)uTexHandle;
g_pd3dDevice->SetTexture( 0, pTex );
// Set palette (if any)
if( g_TexResourceToPaletteIndex.find(uTexHandle) != g_TexResourceToPaletteIndex.end() )
{
int iPaletteIndex = g_TexResourceToPaletteIndex.find(uTexHandle)->second;
#ifndef _XBOX
g_pd3dDevice->SetCurrentTexturePalette( iPaletteIndex );
#else
ASSERT(0);
#endif
}
}
void RageDisplay::SetTextureModeModulate()
{
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
}
void RageDisplay::SetTextureModeGlow(GlowMode m)
{
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
}
void RageDisplay::SetTextureFiltering( bool b )
{
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, b ? D3DTEXF_LINEAR : D3DTEXF_POINT );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, b ? D3DTEXF_LINEAR : D3DTEXF_POINT );
}
void RageDisplay::SetBlendMode( BlendMode mode )
{
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
switch( mode )
{
case BLEND_NORMAL:
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
break;
case BLEND_ADD:
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
break;
case BLEND_NO_EFFECT:
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
break;
default:
ASSERT(0);
}
}
bool RageDisplay::IsZBufferEnabled() const
{
DWORD b;
g_pd3dDevice->GetRenderState( D3DRS_ZENABLE, &b );
return b!=0;
}
void RageDisplay::SetZBuffer( bool b )
{
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, b );
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, b );
}
void RageDisplay::ClearZBuffer()
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
}
void RageDisplay::SetTextureWrapping( bool b )
{
int mode = b ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, mode );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, mode );
}
void RageDisplay::SetMaterial(
float emissive[4],
float ambient[4],
float diffuse[4],
float specular[4],
float shininess
)
{
D3DMATERIAL8 mat;
memcpy( &mat.Diffuse, diffuse, sizeof(diffuse) );
memcpy( &mat.Ambient, ambient, sizeof(ambient) );
memcpy( &mat.Specular, specular, sizeof(specular) );
memcpy( &mat.Emissive, emissive, sizeof(emissive) );
mat.Power = shininess;
g_pd3dDevice->SetMaterial( &mat );
}
void RageDisplay::SetLighting( bool b )
{
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, b );
}
void RageDisplay::SetLightOff( int index )
{
g_pd3dDevice->LightEnable( index, false );
}
void RageDisplay::SetLightDirectional(
int index,
RageColor ambient,
RageColor diffuse,
RageColor specular,
RageVector3 dir )
{
g_pd3dDevice->LightEnable( index, true );
D3DLIGHT8 light;
ZERO( light );
memcpy( &light.Direction, &dir, sizeof(dir) );
memcpy( &light.Direction, &dir, sizeof(dir) );
memcpy( &light.Diffuse, diffuse, sizeof(diffuse) );
memcpy( &light.Ambient, ambient, sizeof(ambient) );
memcpy( &light.Specular, specular, sizeof(specular) );
g_pd3dDevice->SetLight( index, &light );
}
void RageDisplay::SetBackfaceCull( bool b )
{
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, b ? D3DCULL_CCW : D3DCULL_NONE );
}
void RageDisplay::DeleteTexture( unsigned uTexHandle )
{
IDirect3DTexture8* pTex = (IDirect3DTexture8*) uTexHandle;
pTex->Release();
// Delete palette (if any)
if( g_TexResourceToPaletteIndex.find(uTexHandle) != g_TexResourceToPaletteIndex.end() )
g_TexResourceToPaletteIndex.erase( g_TexResourceToPaletteIndex.find(uTexHandle) );
}
unsigned RageDisplay::CreateTexture(
PixelFormat pixfmt,
SDL_Surface*& img )
{
// texture must be power of two
ASSERT( img->w == power_of_two(img->w) );
ASSERT( img->h == power_of_two(img->h) );
HRESULT hr;
IDirect3DTexture8* pTex;
hr = g_pd3dDevice->CreateTexture( img->w, img->h, 1, 0, D3DFORMATS[pixfmt], D3DPOOL_MANAGED, &pTex );
unsigned uTexHandle = (unsigned)pTex;
if( pixfmt == FMT_PAL )
{
int iPalIndex = GetUnusedPaletteIndex();
// Save palette
PALETTEENTRY pal[256];
memset( pal, 0, sizeof(pal) );
for( int i=0; i<img->format->palette->ncolors; i++ )
{
SDL_Color c = img->format->palette->colors[i];
pal[i].peRed = c.r;
pal[i].peGreen = c.g;
pal[i].peBlue = c.b;
bool bIsColorKey = img->flags & SDL_SRCCOLORKEY && (unsigned)i == img->format->colorkey;
pal[i].peFlags = bIsColorKey ? 0x00 : 0xFF;
}
#ifndef _XBOX
g_pd3dDevice->SetPaletteEntries( iPalIndex, pal );
#else
ASSERT(0);
#endif
ASSERT( g_TexResourceToPaletteIndex.find(uTexHandle) == g_TexResourceToPaletteIndex.end() );
g_TexResourceToPaletteIndex[uTexHandle] = iPalIndex;
}
UpdateTexture( uTexHandle, pixfmt, img, 0, 0, img->w, img->h );
return uTexHandle;
}
void RageDisplay::UpdateTexture(
unsigned uTexHandle,
PixelFormat pixfmt,
SDL_Surface*& img,
int xoffset, int yoffset, int width, int height )
{
IDirect3DTexture8* pTex = (IDirect3DTexture8*)uTexHandle;
RECT rect;
rect.left = xoffset;
rect.top = yoffset;
rect.right = width - xoffset;
rect.bottom = height - yoffset;
D3DLOCKED_RECT lr;
pTex->LockRect( 0, &lr, &rect, 0 );
// copy each row
int bytes_per_pixel = img->format->BytesPerPixel;
for( int y=rect.top; y<rect.bottom; y++ )
{
char* src = (char*)img->pixels + y*img->pitch + rect.left*bytes_per_pixel;
char* dst = (char*)lr.pBits + y*lr.Pitch + rect.left*bytes_per_pixel;
memcpy( dst, src, (rect.right-rect.left)*bytes_per_pixel );
}
pTex->UnlockRect( 0 );
// SDL_SaveBMP( (SDL_Surface*)img, "testing-SDL.bmp" );
// D3DXSaveTextureToFile(
// "testing-D3D.bmp",
// D3DXIFF_BMP,
// pTex,
// NULL );
}
void RageDisplay::SetAlphaTest( bool b )
{
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, b );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0 );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATER );
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -123,7 +123,7 @@ RageLog::~RageLog()
void RageLog::ShowConsole()
{
#if defined(WIN32)
#if defined(WIN32) || !defined(_XBOX)
// create a new console window and attach standard handles
AllocConsole();
freopen("CONOUT$","wb",stdout);
@@ -133,7 +133,7 @@ void RageLog::ShowConsole()
void RageLog::HideConsole()
{
#if defined(WIN32)
#if defined(WIN32) || !defined(_XBOX)
FreeConsole();
#endif
}
+86 -1
View File
@@ -222,7 +222,7 @@ void RageMatrixCommand( CString sCommandString, RageMatrix &mat )
{
CString sError = ssprintf( "Unrecognized matrix command name '%s' in command string '%s'.", sName.c_str(), sCommandString.c_str() );
LOG->Warn( sError );
#if defined(WIN32) // XXX arch?
#if defined(WIN32) || !defined(_XBOX) // XXX arch?
if( DISPLAY->IsWindowed() )
MessageBox(NULL, sError, "MatrixCommand", MB_OK);
#endif
@@ -401,3 +401,88 @@ void RageQuatSlerp(RageVector4 *pOut, const RageVector4 &from, const RageVector4
pOut->z = scale0 * from.z + scale1 * to1[2];
pOut->w = scale0 * from.w + scale1 * to1[3];
}
RageMatrix RageLookAt(
float eyex, float eyey, float eyez,
float centerx, float centery, float centerz,
float upx, float upy, float upz )
{
RageVector3 Z(eyex - centerx, eyey - centery, eyez - centerz);
RageVec3Normalize(&Z, &Z);
RageVector3 Y(upx, upy, upz);
RageVector3 X(
Y[1] * Z[2] - Y[2] * Z[1],
-Y[0] * Z[2] + Y[2] * Z[0],
Y[0] * Z[1] - Y[1] * Z[0]);
Y = RageVector3(
Z[1] * X[2] - Z[2] * X[1],
-Z[0] * X[2] + Z[2] * X[0],
Z[0] * X[1] - Z[1] * X[0] );
RageVec3Normalize(&X, &X);
RageVec3Normalize(&Y, &Y);
RageMatrix mat(
X[0], Y[0], Z[0], 0,
X[1], Y[1], Z[1], 0,
X[2], Y[2], Z[2], 0,
0, 0, 0, 1 );
RageMatrix mat2;
RageMatrixTranslation(&mat2, -eyex, -eyey, -eyez);
RageMatrix ret;
RageMatrixMultiply(&ret, &mat, &mat2);
return ret;
}
RageMatrix RageOrtho( float l, float r, float b, float t, float zn, float zf )
{
RageMatrix m(
2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, 1/(zf-zn), 0,
(l+r)/(l-r), (t+b)/(b-t), zn/(zn-zf), 1 );
return m;
}
RageMatrix RageMatrixIdentity()
{
RageMatrix m;
RageMatrixIdentity( &m );
return m;
}
RageMatrix RageMatrixFrustrum(
float left,
float right,
float bottom,
float top,
float znear,
float zfar ) // see glFrustrum docs
{
float A = (right+left) / (right-left);
float B = (top+bottom) / (top-bottom);
float C = -1 * (zfar+znear) / (zfar-znear);
float D = -1 * (2*zfar*znear) / (zfar-znear);
RageMatrix m(
2*znear/(right-left), 0, 0, 0,
0, 2*znear/(top-bottom), 0, 0,
A, B, C, -1,
0, 0, D, 0 );
return m;
}
RageMatrix RageMatrixPerspective(float fovy, float aspect, float zNear, float zFar)
{
float ymax = zNear * tanf(fovy * PI / 360.0f);
float ymin = -ymax;
float xmin = ymin * aspect;
float xmax = ymax * aspect;
return RageMatrixFrustrum(xmin, xmax, ymin, ymax, zNear, zFar);
}
+14
View File
@@ -22,6 +22,7 @@ void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV );
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
void RageVec4TransformCoord( RageVector4* pOut, const RageVector4* pV, const RageMatrix* pM );
void RageMatrixIdentity( RageMatrix* pOut );
RageMatrix RageMatrixIdentity();
void RageMatrixMultiply( RageMatrix* pOut, const RageMatrix* pA, const RageMatrix* pB );
void RageMatrixTranslation( RageMatrix* pOut, float x, float y, float z );
void RageMatrixScaling( RageMatrix* pOut, float x, float y, float z );
@@ -36,5 +37,18 @@ RageVector4 RageQuatFromH(float theta);
RageVector4 RageQuatFromP(float theta);
RageVector4 RageQuatFromR(float theta);
void RageQuatMultiply( RageVector4* pOut, const RageVector4 &pA, const RageVector4 &pB );
RageMatrix RageLookAt(
float eyex, float eyey, float eyez,
float centerx, float centery, float centerz,
float upx, float upy, float upz );
RageMatrix RageOrtho( float l, float r, float b, float t, float zn, float zf );
RageMatrix RageMatrixFrustrum(
float left,
float right,
float bottom,
float top,
float znear,
float zfar );
RageMatrix RageMatrixPerspective(float fovy, float aspect, float zNear, float zFar);
#endif
+15 -13
View File
@@ -53,6 +53,7 @@ bool RageTextureID::operator<(const RageTextureID &rhs) const
COMP(iMipMaps);
COMP(iAlphaBits);
COMP(iColorDepth);
COMP(iTransparencyOnly);
COMP(bDither);
COMP(bStretch);
COMP(bHotPinkColorKey);
@@ -68,6 +69,7 @@ bool RageTextureID::operator==(const RageTextureID &rhs) const
iMipMaps == rhs.iMipMaps &&
iAlphaBits == rhs.iAlphaBits &&
iColorDepth == rhs.iColorDepth &&
iTransparencyOnly == rhs.iTransparencyOnly &&
bDither == rhs.bDither &&
bStretch == rhs.bStretch &&
bHotPinkColorKey == rhs.bHotPinkColorKey;
@@ -81,7 +83,7 @@ RageTexture::RageTexture( RageTextureID name ):
m_iRefCount = 1;
SetActualID();
// SetActualID();
m_iSourceWidth = m_iSourceHeight = 0;
m_iTextureWidth = m_iTextureHeight = 0;
m_iImageWidth = m_iImageHeight = 0;
@@ -91,18 +93,18 @@ RageTexture::RageTexture( RageTextureID name ):
/* Set the initial ActualID; this is what the actual texture will start
* from. */
void RageTexture::SetActualID()
{
m_ActualID = m_ID;
/* Texture color depth preference can be overridden. */
if(m_ID.iColorDepth == -1)
m_ActualID.iColorDepth = TEXTUREMAN->GetTextureColorDepth();
/* The max texture size can never be higher than the preference,
* since it might be set to something to fix driver problems. */
m_ActualID.iMaxSize = min(m_ActualID.iMaxSize, TEXTUREMAN->GetMaxTextureResolution());
}
//void RageTexture::SetActualID()
//{
// m_ActualID = m_ID;
//
// /* Texture color depth preference can be overridden. */
// if(m_ID.iColorDepth == -1)
// m_ActualID.iColorDepth = TEXTUREMAN->GetTextureColorDepth();
//
// /* The max texture size can never be higher than the preference,
// * since it might be set to something to fix driver problems. */
// m_ActualID.iMaxSize = min(m_ActualID.iMaxSize, TEXTUREMAN->GetMaxTextureResolution());
//}
RageTexture::~RageTexture()
{
+3 -14
View File
@@ -15,8 +15,6 @@
#include "RageTypes.h"
const int MAX_TEXTURE_FRAMES = 256;
/* A unique texture is identified by a RageTextureID. (Loading the
* same file with two different dither settings is considered two
* different textures, for example.) See RageTexture.cpp for explanations
@@ -51,9 +49,9 @@ public:
RageTexture( RageTextureID file );
virtual ~RageTexture() = 0;
virtual void Update( float fDeltaTime ) {}
virtual void Reload() { SetActualID(); }
virtual void Reload() {}
virtual void Invalidate() { } /* only called by RageTextureManager::InvalidateTextures */
virtual unsigned int GetGLTextureID() = 0; // accessed by RageDisplay
virtual unsigned GetTexHandle() = 0; // accessed by RageDisplay
// movie texture/animated texture stuff
virtual void Play() {}
@@ -92,22 +90,13 @@ public:
/* The ID that we were asked to load: */
const RageTextureID &GetID() const { return m_ID; }
/* The ID that we actually got: */
const RageTextureID &GetActualID() const { return m_ActualID; }
static void GetFrameDimensionsFromFileName( CString sPath, int* puFramesWide, int* puFramesHigh );
static int GetFrameCountFromFileName( CString sPath );
private:
/* The file we were asked to load. (This is never changed.) */
const RageTextureID m_ID;
void SetActualID();
protected:
/* We might change settings when loading (due to hints, hardware
* limitations, etc). The data actually loaded is here: */
RageTextureID m_ActualID;
RageTextureID m_ID;
int m_iSourceWidth, m_iSourceHeight; // dimensions of the original image loaded from disk
int m_iTextureWidth, m_iTextureHeight; // dimensions of the texture in memory
+21 -5
View File
@@ -60,15 +60,20 @@ RageTexture* RageTextureManager::LoadTexture( RageTextureID ID )
{
Checkpoint( ssprintf( "RageTextureManager::LoadTexture(%s).", ID.filename.c_str() ) );
if( ID.iColorDepth == -1 )
ID.iColorDepth = m_iTextureColorDepth;
ID.iMaxSize = min( ID.iMaxSize, m_iMaxTextureResolution );
/* We could have two copies of the same bitmap if there are equivalent but
* different paths, e.g. "Bitmaps\me.bmp" and "..\Rage PC Edition\Bitmaps\me.bmp". */
std::map<RageTextureID, RageTexture*>::iterator p = m_mapPathToTexture.find(ID);
while(p != m_mapPathToTexture.end())
if(p != m_mapPathToTexture.end())
{
/* Found the texture. Just increase the refcount and return it. */
p->second->m_iRefCount++;
RageTexture* pTexture = p->second;
pTexture->m_iRefCount++;
LOG->UnmapLog( "LoadTexture" );
return p->second;
return pTexture;
}
// The texture is not already loaded. Load it.
@@ -128,8 +133,19 @@ void RageTextureManager::DeleteTexture( RageTexture *t )
{
ASSERT( t->m_iRefCount==0 );
LOG->Trace( "RageTextureManager: deleting '%s'.", t->GetID().filename.c_str() );
m_mapPathToTexture.erase( t->GetID() ); // remove map entry
SAFE_DELETE( t ); // free the texture
for( std::map<RageTextureID, RageTexture*>::iterator i = m_mapPathToTexture.begin();
i != m_mapPathToTexture.end(); i++ )
{
if( i->second == t )
{
m_mapPathToTexture.erase( i ); // remove map entry
SAFE_DELETE( t ); // free the texture
return;
}
}
ASSERT(0); // we tried to delete a texture that wasn't loaded.
}
void RageTextureManager::GarbageCollect( GCType type )
+10 -1
View File
@@ -18,6 +18,7 @@
enum GlowMode { GLOW_BRIGHTEN, GLOW_WHITEN };
enum BlendMode { BLEND_NORMAL, BLEND_ADD, BLEND_NO_EFFECT };
struct RageVector2
{
public:
@@ -154,8 +155,8 @@ inline unsigned char FTOC(float a) { if(a<0) a=0; if(a>1) a=1; return (unsigned
* precision of a float for our calculations anyway. -Chris */
class RageVColor
{
unsigned char r, g, b, a;
public:
unsigned char b,g,r,a; // specific ordering required by Direct3D
RageVColor() { }
RageVColor(const RageColor &rc) { *this = rc; }
@@ -187,10 +188,18 @@ typedef Rect<float> RectF;
// A structure for our custom vertex type. Note that these data structes have the same layout that D3D expects.
struct RageVertex
{
// Temporary hack. A better solution is coming. -Chris
#ifdef D3D
RageVector3 p; // position
RageVector3 n; // normal
RageVColor c; // diffuse color
RageVector2 t; // texture coordinates
#else
RageVector2 t; // texture coordinates
RageColor c; // diffuse color
RageVector3 n; // normal
RageVector3 p; // position
#endif
};
/* nonstandard extension used : nameless struct/union
+6 -4
View File
@@ -134,8 +134,8 @@ CString vssprintf( const char *fmt, va_list argList)
}
#ifdef WIN32
#include "dxerr8.h"
#pragma comment(lib, "DxErr8.lib")
//#include "dxerr8.h"
//#pragma comment(lib, "DxErr8.lib")
CString hr_ssprintf( int hr, const char *fmt, ...)
{
@@ -144,14 +144,16 @@ CString hr_ssprintf( int hr, const char *fmt, ...)
CString s = vssprintf( fmt, va );
va_end(va);
return s += ssprintf( " (%s)", DXGetErrorString8(hr) );
return s;// += ssprintf( " (%s)", DXGetErrorString8(hr) );
}
CString werr_ssprintf( int err, const char *fmt, ...)
{
char buf[1024];
char buf[1024] = "";
#ifndef _XBOX
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
0, err, 0, buf, sizeof(buf), NULL);
#endif
va_list va;
va_start(va, fmt);
+7 -1
View File
@@ -124,7 +124,13 @@ void mySDL_GetRGBAV(Uint32 pixel, const SDL_Surface *src, Uint8 *v)
void mySDL_GetRGBAV(const Uint8 *p, const SDL_Surface *src, Uint8 *v)
{
Uint32 pixel = decodepixel(p, src->format->BytesPerPixel);
mySDL_GetRGBAV(pixel, src, v);
if( src->format->BytesPerPixel == 1 ) // paletted
{
memcpy( v, &src->format->palette->colors[pixel], sizeof(SDL_Color));
v[3] = 0xFF; // full alpha
}
else // RGBA
mySDL_GetRGBAV(pixel, src, v);
}
+28 -33
View File
@@ -23,13 +23,10 @@
#include "GameConstantsAndTypes.h"
#include "SDL_utils.h"
#include "RageDisplayInternal.h"
Sprite::Sprite()
{
m_pTexture = NULL;
m_bDrawIfTextureNull = false;
m_iNumStates = 0;
m_iCurState = 0;
m_fSecsIntoState = 0.0;
m_bUsingCustomTexCoords = false;
@@ -120,32 +117,27 @@ bool Sprite::LoadFromSpriteFile( RageTextureID ID )
// Read in frames and delays from the sprite file,
// overwriting the states that LoadFromTexture created.
for( int i=0; i<MAX_SPRITE_STATES; i++ )
// If the .sprite file doesn't define any states, leave
// frames and delays created during LoadFromTexture().
for( int i=0; true; i++ )
{
CString sFrameKey = ssprintf( "Frame%04d", i );
CString sDelayKey = ssprintf( "Delay%04d", i );
m_iStateToFrame[i] = 0;
if( !ini.GetValueI( "Sprite", sFrameKey, m_iStateToFrame[i] ) )
State newState;
if( !ini.GetValueI( "Sprite", sFrameKey, newState.iFrameIndex ) )
break;
if( m_iStateToFrame[i] >= m_pTexture->GetNumFrames() )
if( newState.iFrameIndex >= m_pTexture->GetNumFrames() )
RageException::Throw( "In '%s', %s is %d, but the texture %s only has %d frames.",
m_sSpritePath.c_str(), sFrameKey.c_str(), m_iStateToFrame[i], ID.filename.c_str(), m_pTexture->GetNumFrames() );
m_fDelay[i] = 0.2f;
if( !ini.GetValueF( "Sprite", sDelayKey, m_fDelay[i] ) )
m_sSpritePath.c_str(), sFrameKey.c_str(), newState.iFrameIndex, ID.filename.c_str(), m_pTexture->GetNumFrames() );
if( !ini.GetValueF( "Sprite", sDelayKey, newState.fDelay ) )
break;
if( m_iStateToFrame[i] == 0 && m_fDelay[i] > -0.00001f && m_fDelay[i] < 0.00001f ) // both values are empty
break;
if( i == 0 ) // the ini file defines at least one frame
m_States.clear(); // clear before adding
m_iNumStates = i+1;
}
if( m_iNumStates == 0 )
{
m_iNumStates = 1;
m_iStateToFrame[0] = 0;
m_fDelay[0] = 10;
m_States.push_back( newState );
}
float f;
@@ -183,6 +175,8 @@ bool Sprite::LoadFromTexture( RageTextureID ID )
* to reset Sprite::m_size, etc. */
UnloadTexture();
m_pTexture = TEXTUREMAN->LoadTexture( ID );
ASSERT( m_pTexture->GetTextureWidth() >= 0 );
ASSERT( m_pTexture->GetTextureHeight() >= 0 );
}
ASSERT( m_pTexture != NULL );
@@ -192,13 +186,13 @@ bool Sprite::LoadFromTexture( RageTextureID ID )
Sprite::m_size.y = (float)m_pTexture->GetSourceFrameHeight();
// Assume the frames of this animation play in sequential order with 0.2 second delay.
m_States.clear();
for( int i=0; i<m_pTexture->GetNumFrames(); i++ )
{
m_iStateToFrame[i] = i;
m_fDelay[i] = 0.1f;
State newState = { i, 0.1f };
m_States.push_back( newState );
}
m_iNumStates = m_pTexture->GetNumFrames();
return true;
}
@@ -211,16 +205,17 @@ void Sprite::Update( float fDeltaTime )
if( !m_bIsAnimating )
return;
if( !m_pTexture ) // no texture, nothing to animate
return;
// update animation
m_fSecsIntoState += fDeltaTime;
if( m_fSecsIntoState > m_fDelay[m_iCurState] ) // it's time to switch frames
while( m_fSecsIntoState > m_States[m_iCurState].fDelay ) // it's time to switch frames
{
// increment frame and reset the counter
m_fSecsIntoState -= m_fDelay[m_iCurState]; // leave the left over time for the next frame
m_iCurState ++;
if( m_iCurState >= m_iNumStates )
m_iCurState = 0;
m_fSecsIntoState -= m_States[m_iCurState].fDelay; // leave the left over time for the next frame
m_iCurState = (m_iCurState+1) % m_States.size();
}
}
@@ -301,7 +296,7 @@ void Sprite::DrawPrimitives()
if( m_bShadow )
{
DISPLAY->PushMatrix();
DISPLAY->TranslateLocal( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
v[0].c = v[1].c = v[2].c = v[3].c = RageColor(0,0,0,0.5f*m_temp.diffuse[0].a); // semi-transparent black
DISPLAY->DrawQuad( v );
DISPLAY->PopMatrix();
@@ -335,9 +330,9 @@ void Sprite::SetState( int iNewState )
// This assert will likely trigger if the "missing" theme element graphic
// is loaded in place of a multi-frame sprite. We want to know about these
// problems in debug builds, but they're not fatal.
DEBUG_ASSERT( iNewState >= 0 && iNewState < m_iNumStates );
DEBUG_ASSERT( iNewState >= 0 && iNewState < (int)m_States.size() );
CLAMP(iNewState, 0, m_iNumStates-1);
CLAMP(iNewState, 0, (int)m_States.size()-1);
m_iCurState = iNewState;
m_fSecsIntoState = 0.0;
}
@@ -389,7 +384,7 @@ void Sprite::SetCustomImageCoords( float fImageCoords[8] ) // order: top left, b
const RectF *Sprite::GetCurrentTextureCoordRect() const
{
unsigned int uFrameNo = m_iStateToFrame[m_iCurState];
unsigned int uFrameNo = m_States[m_iCurState].iFrameIndex;
return m_pTexture->GetTextureCoordRect( uFrameNo );
}
+7 -9
View File
@@ -17,11 +17,6 @@
#include "RageTexture.h"
#define MAX_SPRITE_STATES 256
class Sprite: public Actor
{
public:
@@ -42,7 +37,7 @@ public:
virtual void EnableAnimation( bool bEnable );
virtual void SetState( int iNewState );
virtual int GetNumStates() { return m_iNumStates; };
virtual int GetNumStates() { return m_States.size(); };
CString GetTexturePath() { return m_pTexture==NULL ? "" : m_pTexture->GetID().filename; };
void SetCustomTextureRect( const RectF &new_texcoord_frect );
@@ -66,9 +61,12 @@ protected:
RageTexture* m_pTexture;
bool m_bDrawIfTextureNull;
int m_iStateToFrame[MAX_SPRITE_STATES]; // array of indicies into m_rectBitmapFrames
float m_fDelay[MAX_SPRITE_STATES];
int m_iNumStates;
struct State
{
int iFrameIndex;
float fDelay; // "seconds to show"
};
vector<State> m_States;
int m_iCurState;
float m_fSecsIntoState; // number of seconds that have elapsed since we switched to this frame
+7 -4
View File
@@ -260,8 +260,7 @@
#define STDSTRING_H
// In non-Visual C++ and/or non-Win32 builds, we can't use some cool stuff.
#if !defined(_MSC_VER) || !defined(_WIN32)
#if !defined(_MSC_VER) || !defined(_WIN32) || defined(_XBOX)
#define SS_ANSI
#endif
@@ -271,7 +270,7 @@
// On non-Win32 platforms, there is no TCHAR.H so define what we need
#ifndef _WIN32
#if !defined(_WIN32) || defined(_XBOX)
typedef const char* PCSTR;
typedef char* PSTR;
@@ -590,7 +589,11 @@ inline void ssadd(std::string& sDst, PCSTR pA)
#ifdef SS_ANSI
inline int ssvsprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl)
{
return vsnprintf(pA, nCount, pFmtA, vl);
#if defined(_XBOX)
return _vsnprintf(pA, nCount, pFmtA, vl);
#else
return vsnprintf(pA, nCount, pFmtA, vl);
#endif
}
#else
inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl)
+4 -3
View File
@@ -23,6 +23,7 @@
#include "RageTimer.h"
#include "RageException.h"
#include "RageMath.h"
#include "RageDisplay.h"
#include "arch/arch.h"
#include "arch/LoadingWindow/LoadingWindow.h"
@@ -438,10 +439,10 @@ bool HandleGlobalInputs( DeviceInput DeviceI, InputEventType type, GameInput Gam
return true;
}
}
if(DeviceI == DeviceInput(DEVICE_KEYBOARD, SDLK_F5)) // F5 conflicts with editor and AutoSync
if(DeviceI == DeviceInput(DEVICE_KEYBOARD, SDLK_F5))
{
// pressed F6. Save Screenshot.
// Save Screenshot.
CString sPath;
for( int i=0; i<1000; i++ )
{
File diff suppressed because it is too large Load Diff
+12 -6
View File
@@ -3,16 +3,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StepMania", "StepMania.vcpr
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
ConfigName.0 = Debug D3D
ConfigName.1 = Debug OGL
ConfigName.2 = Release D3D
ConfigName.3 = Release OGL
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug.ActiveCfg = Debug|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug.Build.0 = Debug|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release.ActiveCfg = Release|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release.Build.0 = Release|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug D3D.ActiveCfg = Debug D3D|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug D3D.Build.0 = Debug D3D|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug OGL.ActiveCfg = Debug OGL|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Debug OGL.Build.0 = Debug OGL|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release D3D.ActiveCfg = Release D3D|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release D3D.Build.0 = Release D3D|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release OGL.ActiveCfg = Release OGL|Win32
{670745A6-106B-420D-A2A9-D4F89A23986E}.Release OGL.Build.0 = Release OGL|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
DPBuild = 5
+198 -11
View File
@@ -12,7 +12,7 @@
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
Name="Debug OGL|Win32"
OutputDirectory=".\.."
IntermediateDirectory=".\../Debug"
ConfigurationType="1"
@@ -31,9 +31,9 @@
RuntimeLibrary="2"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Debug/StepMania.pch"
AssemblerListingLocation=".\../Debug/"
ObjectFile=".\../Debug/"
ProgramDataBaseFileName=".\../Debug/"
AssemblerListingLocation=".\../Debug_OGL/"
ObjectFile=".\../Debug_OGL/"
ProgramDataBaseFileName=".\../Debug_OGL/"
BrowseInformation="0"
WarningLevel="4"
SuppressStartupBanner="TRUE"
@@ -49,7 +49,7 @@
AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="wininet.lib;msimg32.lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="../debug/StepMania-debug.pdb"
ProgramDatabaseFile="../Debug_OGL/StepMania-debug.pdb"
GenerateMapFile="TRUE"
MapFileName="$(IntDir)\$(TargetName).map"
MapExports="TRUE"
@@ -81,7 +81,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
Name="Release OGL|Win32"
OutputDirectory="./.."
IntermediateDirectory="./../Release"
ConfigurationType="1"
@@ -109,9 +109,9 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
EnableFunctionLevelLinking="FALSE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\../Release/StepMania.pch"
AssemblerListingLocation=".\../Release/"
ObjectFile=".\../Release/"
ProgramDataBaseFileName=".\../Release/"
AssemblerListingLocation=".\../Release_OGL/"
ObjectFile=".\../Release_OGL/"
ProgramDataBaseFileName=".\../Release_OGL/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="TRUE"
@@ -128,7 +128,155 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="wininet.lib;msimg32.lib"
ProgramDatabaseFile="../release/StepMania.pdb"
ProgramDatabaseFile="../Release_OGL/StepMania.pdb"
GenerateMapFile="TRUE"
MapFileName="$(IntDir)\$(TargetName).map"
MapExports="TRUE"
SubSystem="2"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../StepMania.tlb"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="disasm\mapconv &quot;$(IntDir)\$(TargetName).map&quot; &quot;$(TargetDir)\StepMania.vdi&quot; &quot;ia32.vdi&quot;"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="disasm\verinc
cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug D3D|Win32"
OutputDirectory="Debug D3D"
IntermediateDirectory="Debug D3D"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/EHa"
Optimization="0"
AdditionalIncludeDirectories=".,SDL-1.2.5/include,SDL_image-1.2"
PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,DEBUG,D3D"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Debug/StepMania.pch"
AssemblerListingLocation=".\../Debug_D3D/"
ObjectFile=".\../Debug_D3D/"
ProgramDataBaseFileName=".\../Debug_D3D/"
BrowseInformation="0"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386 $(intdir)\verstub.obj"
OutputFile="../StepMania-debug.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="wininet.lib;msimg32.lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="../Debug_D3D/StepMania-debug.pdb"
GenerateMapFile="TRUE"
MapFileName="$(IntDir)\$(TargetName).map"
MapExports="TRUE"
SubSystem="2"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../StepMania.tlb"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="disasm\mapconv &quot;$(IntDir)\$(TargetName).map&quot; &quot;$(TargetDir)\StepMania.vdi&quot; &quot;ia32.vdi&quot;"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="disasm\verinc
cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Release D3D|Win32"
OutputDirectory="Release D3D"
IntermediateDirectory="Release D3D"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/EHa"
Optimization="3"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="2"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories=".,SDL-1.2.5/include,SDL_image-1.2"
PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS,RELEASE,D3D"
StringPooling="TRUE"
MinimalRebuild="FALSE"
ExceptionHandling="FALSE"
RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="FALSE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\../Release/StepMania.pch"
AssemblerListingLocation=".\../Release_D3D/"
ObjectFile=".\../Release_D3D/"
ProgramDataBaseFileName=".\../Release_D3D/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386 $(intdir)\verstub.obj
/FIXED:no
"
OutputFile=".\../StepMania.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="wininet.lib;msimg32.lib"
ProgramDatabaseFile="../Release_D3D/StepMania.pdb"
GenerateMapFile="TRUE"
MapFileName="$(IntDir)\$(TargetName).map"
MapExports="TRUE"
@@ -952,9 +1100,21 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
</File>
<File
RelativePath="arch\LowLevelWindow\LowLevelWindow_SDL.cpp">
<FileConfiguration
Name="Debug D3D|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="arch\LowLevelWindow\LowLevelWindow_SDL.h">
<FileConfiguration
Name="Debug D3D|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
</Filter>
</Filter>
@@ -1454,7 +1614,34 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
RelativePath="RageDisplay.h">
</File>
<File
RelativePath="RageDisplayInternal.h">
RelativePath="RageDisplay_D3D.cpp">
<FileConfiguration
Name="Debug OGL|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release OGL|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="RageDisplay_OGL.cpp">
<FileConfiguration
Name="Debug D3D|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release D3D|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="RageException.cpp">
@@ -28,7 +28,6 @@
#include "RageUtil.h"
#include "RageLog.h"
#include "RageException.h"
#include "RageDisplayInternal.h"
#include "archutils/win32/tls.h"
@@ -44,10 +43,11 @@ MovieTexture_DShow::MovieTexture_DShow( RageTextureID ID ) :
{
LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
m_uGLTextureID = 0;
m_uTexHandle = 0;
buffer = NULL;
buffer_lock = SDL_CreateSemaphore(1);
buffer_finished = SDL_CreateSemaphore(0);
m_img = NULL;
Create();
CreateFrameRects();
@@ -98,8 +98,9 @@ MovieTexture_DShow::~MovieTexture_DShow()
}
LOG->Trace("MovieTexture_DShow: shutdown ok");
LOG->Flush();
if(m_uGLTextureID)
glDeleteTextures(1, &m_uGLTextureID);
if(m_uTexHandle)
DISPLAY->DeleteTexture( m_uTexHandle );
SDL_FreeSurface( m_img );
SDL_DestroySemaphore(buffer_lock);
SDL_DestroySemaphore(buffer_finished);
@@ -134,32 +135,40 @@ void MovieTexture_DShow::Update(float fDeltaTime)
/* Just in case we were invalidated: */
CreateTexture();
glBindTexture( GL_TEXTURE_2D, m_uGLTextureID );
// DirectShow feeds us in BGR8
SDL_Surface *fromDShow = SDL_CreateRGBSurfaceFrom(
(void*)buffer, m_iSourceWidth, m_iSourceHeight,
24,
m_iSourceWidth*3,
0xFF0000,
0x00FF00,
0x0000FF,
0x000000 );
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
/* We don't want to actually blend the alpha channel over the destination converted
* surface; we want to simply blit it, so make sure SDL_SRCALPHA is not on. */
SDL_SetAlpha( fromDShow, 0, SDL_ALPHA_OPAQUE );
/* XXX: We should use m_lVidPitch; we might be padded. However, I can't
* find any codec that don't force the width to a multiple of at least
* 4 anyway, so I can't test it, so I'll leave it like this for now. */
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_iSourceWidth);
SDL_Rect area;
area.x = area.y = 0;
area.w = short(fromDShow->w);
area.h = short(fromDShow->h);
VDCHECKPOINT;
SDL_BlitSurface(fromDShow, &area, m_img, &area);
glTexSubImage2D(GL_TEXTURE_2D, 0,
DISPLAY->UpdateTexture(
m_uTexHandle,
m_PixelFormat,
m_img,
0, 0,
min(m_iSourceWidth, m_iTextureWidth),
min(m_iSourceHeight, m_iTextureHeight),
GL_BGR, GL_UNSIGNED_BYTE, buffer);
min(m_iSourceWidth,m_iTextureWidth), min(m_iSourceHeight,m_iTextureHeight) );
/* Must unset PixelStore when we're done! */
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glFlush();
SDL_FreeSurface( fromDShow );
buffer = NULL;
VDCHECKPOINT;
LOG->Trace("processed, signalling");
/* Start the decoding thread again. */
@@ -187,7 +196,7 @@ void MovieTexture_DShow::Create()
{
HRESULT hr;
m_ActualID.iAlphaBits = 0;
m_ID.iAlphaBits = 0;
if( FAILED( hr=CoInitialize(NULL) ) )
RageException::Throw( hr_ssprintf(hr, "Could not CoInitialize") );
@@ -208,7 +217,7 @@ void MovieTexture_DShow::Create()
// Add the source filter
CComPtr<IBaseFilter> pFSrc; // Source Filter
WCHAR wFileName[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, m_ActualID.filename.c_str(), -1, wFileName, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, m_ID.filename.c_str(), -1, wFileName, MAX_PATH);
// if this fails, it's probably because the user doesn't have DivX installed
if( FAILED( hr = m_pGB->AddSourceFilter( wFileName, L"SOURCE", &pFSrc ) ) )
@@ -236,14 +245,17 @@ void MovieTexture_DShow::Create()
// Pass us to our TextureRenderer.
pCTR->SetRenderTarget(this);
/* Cap the max texture size to the hardware max. */
m_ID.iMaxSize = min( m_ID.iMaxSize, DISPLAY->GetMaxTextureSize() );
// The graph is built, now get the set the output video width and height.
// The source and image width will always be the same since we can't scale the video
m_iSourceWidth = pCTR->GetVidWidth();
m_iSourceHeight = pCTR->GetVidHeight();
/* image size cannot exceed max size */
m_iImageWidth = min( m_iSourceWidth, m_ActualID.iMaxSize );
m_iImageHeight = min( m_iSourceHeight, m_ActualID.iMaxSize );
m_iImageWidth = min( m_iSourceWidth, m_ID.iMaxSize );
m_iImageHeight = min( m_iSourceHeight, m_ID.iMaxSize );
/* Texture dimensions need to be a power of two; jump to the next. */
m_iTextureWidth = power_of_two(m_iImageWidth);
@@ -283,14 +295,13 @@ void MovieTexture_DShow::NewData(const char *data)
void MovieTexture_DShow::CreateTexture()
{
if(m_uGLTextureID)
if(m_uTexHandle)
return;
glGenTextures(1, &m_uGLTextureID);
glBindTexture( GL_TEXTURE_2D, m_uGLTextureID );
/* Initialize the texture and set it to black. */
string buf(m_iTextureWidth*m_iTextureHeight*3, 0);
/* Have to free our frame holder becuase we might need a different
* PixelFormat than before. */
if( m_img )
SDL_FreeSurface( m_img );
/* My test clip (a high-res, MPEG1 video) goes from 12 fps to 14 fps
* if I use a 16-bit internalformat instead of a 32-bit one; that's a
@@ -303,12 +314,17 @@ void MovieTexture_DShow::CreateTexture()
* Some way to figure this out dynamically would be nice, but it's probably
* impossible. (For example, 24-bit textures may even be cheaper on pure
* AGP cards; 16-bit requires a conversion.) */
int internalformat = GL_RGB8;
m_PixelFormat = FMT_RGB8;
if(TEXTUREMAN->GetTextureColorDepth() == 16)
internalformat = GL_RGB5;
m_PixelFormat = FMT_RGB5;
glTexImage2D(GL_TEXTURE_2D, 0, internalformat,
m_iTextureWidth, m_iTextureHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, buf.data());
m_img = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, m_iTextureWidth, m_iTextureHeight, PIXEL_FORMAT_DESC[m_PixelFormat].bpp,
PIXEL_FORMAT_DESC[m_PixelFormat].masks[0], PIXEL_FORMAT_DESC[m_PixelFormat].masks[1],
PIXEL_FORMAT_DESC[m_PixelFormat].masks[2], PIXEL_FORMAT_DESC[m_PixelFormat].masks[3]);
m_uTexHandle = DISPLAY->CreateTexture(
m_PixelFormat,
m_img );
}
bool MovieTexture_DShow::PlayMovie()
@@ -36,7 +36,7 @@ typedef char TCHAR, *PTCHAR;
#include "RageDisplay.h"
#include "RageTexture.h"
#include "RageThreads.h"
struct SDL_Surface;
//-----------------------------------------------------------------------------
@@ -48,7 +48,7 @@ public:
MovieTexture_DShow( RageTextureID ID );
virtual ~MovieTexture_DShow();
/* only called by RageTextureManager::InvalidateTextures */
void Invalidate() { m_uGLTextureID = 0; }
void Invalidate() { m_uTexHandle = 0; }
void Update(float fDeltaTime);
virtual void Reload();
@@ -66,6 +66,8 @@ public:
private:
const char *buffer;
SDL_sem *buffer_lock, *buffer_finished;
SDL_Surface* m_img; // last frame in PixelFormat that is being used by graphics card
PixelFormat m_PixelFormat; // format being used by graphics card
void Create();
@@ -74,8 +76,8 @@ private:
void SkipUpdates();
void StopSkippingUpdates();
unsigned int GetGLTextureID() { return m_uGLTextureID; }
unsigned int m_uGLTextureID;
unsigned GetTexHandle() { return m_uTexHandle; }
unsigned m_uTexHandle;
CComPtr<IGraphBuilder> m_pGB; // GraphBuilder
bool m_bLoop;
+5
View File
@@ -131,6 +131,11 @@ inline float cosf(float x) { return float(cos(double(x))); }
inline float acosf(float x) { return float(acos(double(x))); }
#endif
#ifdef _XBOX
#include <xtl.h>
#include <xgraphics.h>
#include <stdio.h>
#endif
/* Don't include our own headers here, since they tend to change often. */