Direct3D renderer:
Fixed: Sqeezed image for 1x image size Fixed: Lowest scan line visible as first one with bilinear texture filtering enabled Optimized: Textures are now a power of 2 Optimized: Clear screen only when necessary Debug: Added #define D3D_DEBUG_INFO for debug builds git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@258 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
3c3fdf4a83
commit
7206d4c467
|
@ -1,8 +1,7 @@
|
||||||
Known Bugs:
|
Known Bugs:
|
||||||
|
|
||||||
- Direct3D: image is 1x1 pixel larger than it should be
|
|
||||||
- Linking: Doesnt work quite right yet.
|
- Linking: Doesnt work quite right yet.
|
||||||
- OpenGL: Fragment shaders do not work quite as well as original test build (Mudlord)
|
- OpenGL: Fragment shaders do not work quite as well as original test build (Mudlord)
|
||||||
- Audio core: assertation error occurs when disabling GB sound
|
- Audio core: assertation error occurs when disabling GB sound
|
||||||
- x64: Needs optimizations (x64 native code, whatever)
|
- x64: Needs optimizations (x64 native code, whatever)
|
||||||
- Wrong bit depth image is displayed for some frames when switching from/to Hq3x/4x ASM (most probably causes by 16bit to 32bit hack)
|
- Wrong bit depth image is displayed for some frames when switching from/to Hq3x/4x ASM (most probably caused by 16bit to 32bit hack)
|
|
@ -38,6 +38,9 @@
|
||||||
#include "../gb/gbGlobals.h"
|
#include "../gb/gbGlobals.h"
|
||||||
|
|
||||||
// Direct3D
|
// Direct3D
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define D3D_DEBUG_INFO
|
||||||
|
#endif
|
||||||
#define DIRECT3D_VERSION 0x0900
|
#define DIRECT3D_VERSION 0x0900
|
||||||
#include <d3d9.h> // main include file
|
#include <d3d9.h> // main include file
|
||||||
#include <D3dx9core.h> // required for font rendering
|
#include <D3dx9core.h> // required for font rendering
|
||||||
|
@ -71,11 +74,12 @@ private:
|
||||||
LPDIRECT3DTEXTURE9 emulatedImage[2];
|
LPDIRECT3DTEXTURE9 emulatedImage[2];
|
||||||
unsigned char mbCurrentTexture; // current texture for motion blur
|
unsigned char mbCurrentTexture; // current texture for motion blur
|
||||||
bool mbTextureEmpty;
|
bool mbTextureEmpty;
|
||||||
int width;
|
unsigned int width, height;
|
||||||
int height;
|
unsigned int textureSize;
|
||||||
RECT destRect;
|
RECT destRect;
|
||||||
bool failed;
|
bool failed;
|
||||||
ID3DXFont *pFont;
|
ID3DXFont *pFont;
|
||||||
|
bool rectangleFillsScreen;
|
||||||
|
|
||||||
struct VERTEX {
|
struct VERTEX {
|
||||||
FLOAT x, y, z, rhw; // screen coordinates
|
FLOAT x, y, z, rhw; // screen coordinates
|
||||||
|
@ -93,7 +97,7 @@ private:
|
||||||
|
|
||||||
void createFont();
|
void createFont();
|
||||||
void destroyFont();
|
void destroyFont();
|
||||||
void createTexture();
|
void createTexture( unsigned int textureWidth, unsigned int textureHeight );
|
||||||
void destroyTexture();
|
void destroyTexture();
|
||||||
void calculateDestRect();
|
void calculateDestRect();
|
||||||
bool resetDevice();
|
bool resetDevice();
|
||||||
|
@ -124,12 +128,14 @@ Direct3DDisplay::Direct3DDisplay()
|
||||||
screenFormat = D3DFMT_X8R8G8B8;
|
screenFormat = D3DFMT_X8R8G8B8;
|
||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
|
textureSize = 0;
|
||||||
failed = false;
|
failed = false;
|
||||||
pFont = NULL;
|
pFont = NULL;
|
||||||
emulatedImage[0] = NULL;
|
emulatedImage[0] = NULL;
|
||||||
emulatedImage[1] = NULL;
|
emulatedImage[1] = NULL;
|
||||||
mbCurrentTexture = 0;
|
mbCurrentTexture = 0;
|
||||||
mbTextureEmpty = true;
|
mbTextureEmpty = true;
|
||||||
|
rectangleFillsScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,10 +312,11 @@ bool Direct3DDisplay::initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
createFont();
|
createFont();
|
||||||
createTexture();
|
// width and height will be set from a prior call to changeRenderSize() before initialize()
|
||||||
|
createTexture( width, height );
|
||||||
|
calculateDestRect();
|
||||||
setOption( _T("d3dFilter"), theApp.d3dFilter );
|
setOption( _T("d3dFilter"), theApp.d3dFilter );
|
||||||
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
|
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
|
||||||
calculateDestRect();
|
|
||||||
|
|
||||||
if(failed) return false;
|
if(failed) return false;
|
||||||
|
|
||||||
|
@ -358,10 +365,15 @@ void Direct3DDisplay::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !rectangleFillsScreen ) {
|
||||||
|
// performance: clear only when you must
|
||||||
clear();
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
pDevice->BeginScene();
|
pDevice->BeginScene();
|
||||||
|
|
||||||
|
pDevice->SetSamplerState( 0, D3DSAMP_BORDERCOLOR, D3DCOLOR_XRGB( 0x00, 0xFF, 0x00 ) );
|
||||||
|
|
||||||
// copy pix to emulatedImage and apply pixel filter if selected
|
// copy pix to emulatedImage and apply pixel filter if selected
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
|
|
||||||
|
@ -478,10 +490,11 @@ void Direct3DDisplay::render()
|
||||||
bool Direct3DDisplay::changeRenderSize( int w, int h )
|
bool Direct3DDisplay::changeRenderSize( int w, int h )
|
||||||
{
|
{
|
||||||
if( (w != width) || (h != height) ) {
|
if( (w != width) || (h != height) ) {
|
||||||
width = w; height = h;
|
width = (unsigned int)w;
|
||||||
|
height = (unsigned int)h;
|
||||||
if( pDevice ) {
|
if( pDevice ) {
|
||||||
destroyTexture();
|
destroyTexture();
|
||||||
createTexture();
|
createTexture( width, height );
|
||||||
calculateDestRect();
|
calculateDestRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,13 +555,33 @@ void Direct3DDisplay::destroyFont()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Direct3DDisplay::createTexture()
|
// when either textureWidth or textureHeight is 0, last texture size will be used
|
||||||
|
void Direct3DDisplay::createTexture( unsigned int textureWidth, unsigned int textureHeight )
|
||||||
{
|
{
|
||||||
|
if( ( textureWidth != 0 ) && ( textureWidth != 0 ) ) {
|
||||||
|
// calculate next possible square texture size
|
||||||
|
textureSize = 1;
|
||||||
|
unsigned int reqSizeMin = ( textureWidth > textureHeight ) ? textureWidth : textureHeight;
|
||||||
|
while( textureSize < reqSizeMin ) {
|
||||||
|
textureSize <<= 1; // multiply by 2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// do not recalculate texture size
|
||||||
|
|
||||||
|
if( textureSize == 0 ) {
|
||||||
|
DXTRACE_MSG( _T("Error: createTexture: textureSize == 0") );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( !emulatedImage[0] ) {
|
if( !emulatedImage[0] ) {
|
||||||
HRESULT hr = pDevice->CreateTexture(
|
HRESULT hr = pDevice->CreateTexture(
|
||||||
width, height, 1, // 1 level, no mipmaps
|
textureSize, textureSize,
|
||||||
D3DUSAGE_DYNAMIC, dpp.BackBufferFormat,
|
1, // 1 level, no mipmaps
|
||||||
D3DPOOL_DEFAULT, // anything else won't work
|
D3DUSAGE_DYNAMIC, // dynamic textures can be locked
|
||||||
|
dpp.BackBufferFormat,
|
||||||
|
D3DPOOL_DEFAULT,
|
||||||
&emulatedImage[0],
|
&emulatedImage[0],
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
|
@ -561,9 +594,11 @@ void Direct3DDisplay::createTexture()
|
||||||
|
|
||||||
if( !emulatedImage[1] && theApp.d3dMotionBlur ) {
|
if( !emulatedImage[1] && theApp.d3dMotionBlur ) {
|
||||||
HRESULT hr = pDevice->CreateTexture(
|
HRESULT hr = pDevice->CreateTexture(
|
||||||
width, height, 1, // 1 level, no mipmaps
|
textureSize, textureSize,
|
||||||
D3DUSAGE_DYNAMIC, dpp.BackBufferFormat,
|
1,
|
||||||
D3DPOOL_DEFAULT, // anything else won't work
|
D3DUSAGE_DYNAMIC,
|
||||||
|
dpp.BackBufferFormat,
|
||||||
|
D3DPOOL_DEFAULT,
|
||||||
&emulatedImage[1],
|
&emulatedImage[1],
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
|
@ -594,6 +629,7 @@ void Direct3DDisplay::destroyTexture()
|
||||||
void Direct3DDisplay::calculateDestRect()
|
void Direct3DDisplay::calculateDestRect()
|
||||||
{
|
{
|
||||||
if( theApp.fullScreenStretch ) {
|
if( theApp.fullScreenStretch ) {
|
||||||
|
rectangleFillsScreen = true; // no clear() necessary
|
||||||
destRect.left = 0;
|
destRect.left = 0;
|
||||||
destRect.top = 0;
|
destRect.top = 0;
|
||||||
destRect.right = dpp.BackBufferWidth; // for some reason there'l be a black
|
destRect.right = dpp.BackBufferWidth; // for some reason there'l be a black
|
||||||
|
@ -620,34 +656,45 @@ void Direct3DDisplay::calculateDestRect()
|
||||||
destRect.top += diff;
|
destRect.top += diff;
|
||||||
destRect.bottom += diff;
|
destRect.bottom += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ( destRect.left == 0 ) &&
|
||||||
|
( destRect.top == 0 ) &&
|
||||||
|
( destRect.right == dpp.BackBufferWidth ) &&
|
||||||
|
( destRect.bottom == dpp.BackBufferHeight ) ) {
|
||||||
|
rectangleFillsScreen = true;
|
||||||
|
} else {
|
||||||
|
rectangleFillsScreen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLOAT textureX = (FLOAT)width / (FLOAT)textureSize;
|
||||||
|
FLOAT textureY = (FLOAT)height / (FLOAT)textureSize;
|
||||||
|
|
||||||
|
|
||||||
// configure triangles
|
// configure triangles
|
||||||
Vertices[0].x = (FLOAT)destRect.left;
|
Vertices[0].x = (FLOAT)destRect.left;
|
||||||
Vertices[0].y = (FLOAT)destRect.bottom;
|
Vertices[0].y = (FLOAT)destRect.bottom;
|
||||||
Vertices[0].z = 0.5f;
|
Vertices[0].z = 0.0f;
|
||||||
Vertices[0].rhw = 1.0f;
|
Vertices[0].rhw = 1.0f;
|
||||||
Vertices[0].tx = 0.0f;
|
Vertices[0].tx = 0.0f;
|
||||||
Vertices[0].ty = 1.0f;
|
Vertices[0].ty = textureY;
|
||||||
Vertices[1].x = (FLOAT)destRect.left;
|
Vertices[1].x = (FLOAT)destRect.left;
|
||||||
Vertices[1].y = (FLOAT)destRect.top;
|
Vertices[1].y = (FLOAT)destRect.top;
|
||||||
Vertices[1].z = 0.5f;
|
Vertices[1].z = 0.0f;
|
||||||
Vertices[1].rhw = 1.0f;
|
Vertices[1].rhw = 1.0f;
|
||||||
Vertices[1].tx = 0.0f;
|
Vertices[1].tx = 0.0f;
|
||||||
Vertices[1].ty = 0.0f;
|
Vertices[1].ty = 0.0f;
|
||||||
Vertices[2].x = (FLOAT)destRect.right;
|
Vertices[2].x = (FLOAT)destRect.right;
|
||||||
Vertices[2].y = (FLOAT)destRect.bottom;
|
Vertices[2].y = (FLOAT)destRect.bottom;
|
||||||
Vertices[2].z = 0.5f;
|
Vertices[2].z = 0.0f;
|
||||||
Vertices[2].rhw = 1.0f;
|
Vertices[2].rhw = 1.0f;
|
||||||
Vertices[2].tx = 1.0f;
|
Vertices[2].tx = textureX;
|
||||||
Vertices[2].ty = 1.0f;
|
Vertices[2].ty = textureY;
|
||||||
Vertices[3].x = (FLOAT)destRect.right;
|
Vertices[3].x = (FLOAT)destRect.right;
|
||||||
Vertices[3].y = (FLOAT)destRect.top;
|
Vertices[3].y = (FLOAT)destRect.top;
|
||||||
Vertices[3].z = 0.5f;
|
Vertices[3].z = 0.0f;
|
||||||
Vertices[3].rhw = 1.0f;
|
Vertices[3].rhw = 1.0f;
|
||||||
Vertices[3].tx = 1.0f;
|
Vertices[3].tx = textureX;
|
||||||
Vertices[3].ty = 0.0f;
|
Vertices[3].ty = 0.0f;
|
||||||
|
|
||||||
if( theApp.d3dMotionBlur ) {
|
if( theApp.d3dMotionBlur ) {
|
||||||
|
@ -737,7 +784,7 @@ void Direct3DDisplay::setOption( const char *option, int value )
|
||||||
// apply vertex alpha values to texture
|
// apply vertex alpha values to texture
|
||||||
pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
|
pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
|
||||||
calculateDestRect();
|
calculateDestRect();
|
||||||
createTexture(); // create the second texture
|
createTexture( 0, 0 ); // create the second texture
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -766,7 +813,7 @@ bool Direct3DDisplay::resetDevice()
|
||||||
// re-aquires font resources
|
// re-aquires font resources
|
||||||
pFont->OnResetDevice();
|
pFont->OnResetDevice();
|
||||||
}
|
}
|
||||||
createTexture();
|
createTexture( 0, 0 );
|
||||||
setOption( _T("d3dFilter"), theApp.d3dFilter );
|
setOption( _T("d3dFilter"), theApp.d3dFilter );
|
||||||
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
|
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
|
||||||
failed = false;
|
failed = false;
|
||||||
|
|
Loading…
Reference in New Issue