Reorganize RageDisplay
Add Direct3D renderer (separate project configuration) Add Xbox project config (doesn't yet compile)
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
+246
-875
File diff suppressed because it is too large
Load Diff
+87
-45
@@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++ )
|
||||
{
|
||||
|
||||
+3260
-65
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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 "$(IntDir)\$(TargetName).map" "$(TargetDir)\StepMania.vdi" "ia32.vdi""/>
|
||||
<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 "$(IntDir)\$(TargetName).map" "$(TargetDir)\StepMania.vdi" "ia32.vdi""/>
|
||||
<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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user