just code indentation
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4280 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ef6e574ea1
commit
3117bde5fb
|
@ -89,191 +89,191 @@ void EnableAlphaToCoverage()
|
||||||
D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
|
D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
|
void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
|
||||||
|
{
|
||||||
|
int FSResX = adapters[adapter].resolutions[resolution].xres;
|
||||||
|
int FSResY = adapters[adapter].resolutions[resolution].yres;
|
||||||
|
|
||||||
|
ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS));
|
||||||
|
pp->hDeviceWindow = hWnd;
|
||||||
|
if (auto_depth_stencil)
|
||||||
{
|
{
|
||||||
int FSResX = adapters[adapter].resolutions[resolution].xres;
|
pp->EnableAutoDepthStencil = TRUE;
|
||||||
int FSResY = adapters[adapter].resolutions[resolution].yres;
|
pp->AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||||
|
} else {
|
||||||
ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS));
|
pp->EnableAutoDepthStencil = FALSE;
|
||||||
pp->hDeviceWindow = hWnd;
|
pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||||
if (auto_depth_stencil)
|
|
||||||
{
|
|
||||||
pp->EnableAutoDepthStencil = TRUE;
|
|
||||||
pp->AutoDepthStencilFormat = D3DFMT_D24S8;
|
|
||||||
} else {
|
|
||||||
pp->EnableAutoDepthStencil = FALSE;
|
|
||||||
pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
|
||||||
}
|
|
||||||
pp->BackBufferFormat = D3DFMT_A8R8G8B8;
|
|
||||||
if (aa_mode >= (int)adapters[adapter].aa_levels.size())
|
|
||||||
aa_mode = 0;
|
|
||||||
|
|
||||||
pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting;
|
|
||||||
pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting;
|
|
||||||
|
|
||||||
pp->Flags = auto_depth_stencil ? D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL : 0;
|
|
||||||
if (fullScreen)
|
|
||||||
{
|
|
||||||
xres = pp->BackBufferWidth = FSResX;
|
|
||||||
yres = pp->BackBufferHeight = FSResY;
|
|
||||||
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
||||||
pp->Windowed = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RECT client;
|
|
||||||
GetClientRect(hWnd, &client);
|
|
||||||
xres = pp->BackBufferWidth = client.right - client.left;
|
|
||||||
yres = pp->BackBufferHeight = client.bottom - client.top;
|
|
||||||
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
||||||
pp->PresentationInterval = g_Config.bVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
||||||
pp->Windowed = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pp->BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||||
|
if (aa_mode >= (int)adapters[adapter].aa_levels.size())
|
||||||
|
aa_mode = 0;
|
||||||
|
|
||||||
void Enumerate()
|
pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting;
|
||||||
|
pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting;
|
||||||
|
|
||||||
|
pp->Flags = auto_depth_stencil ? D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL : 0;
|
||||||
|
if (fullScreen)
|
||||||
{
|
{
|
||||||
numAdapters = D3D::D3D->GetAdapterCount();
|
xres = pp->BackBufferWidth = FSResX;
|
||||||
for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++)
|
yres = pp->BackBufferHeight = FSResY;
|
||||||
|
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
pp->Windowed = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RECT client;
|
||||||
|
GetClientRect(hWnd, &client);
|
||||||
|
xres = pp->BackBufferWidth = client.right - client.left;
|
||||||
|
yres = pp->BackBufferHeight = client.bottom - client.top;
|
||||||
|
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
pp->PresentationInterval = g_Config.bVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
|
pp->Windowed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enumerate()
|
||||||
|
{
|
||||||
|
numAdapters = D3D::D3D->GetAdapterCount();
|
||||||
|
for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++)
|
||||||
|
{
|
||||||
|
Adapter &a = adapters[i];
|
||||||
|
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident);
|
||||||
|
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
|
||||||
|
|
||||||
|
// Add multisample modes
|
||||||
|
a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0));
|
||||||
|
|
||||||
|
DWORD qlevels = 0;
|
||||||
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
||||||
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
||||||
|
if (qlevels > 0)
|
||||||
|
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
|
||||||
|
|
||||||
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
||||||
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
||||||
|
if (qlevels > 0)
|
||||||
|
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
|
||||||
|
|
||||||
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
||||||
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
||||||
|
if (qlevels > 0)
|
||||||
|
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
||||||
|
|
||||||
|
if (isNvidia)
|
||||||
{
|
{
|
||||||
Adapter &a = adapters[i];
|
// CSAA support
|
||||||
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident);
|
|
||||||
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
|
|
||||||
|
|
||||||
// Add multisample modes
|
|
||||||
a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0));
|
|
||||||
|
|
||||||
DWORD qlevels = 0;
|
|
||||||
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
||||||
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
|
||||||
if (qlevels > 0)
|
{
|
||||||
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
|
if (qlevels > 2)
|
||||||
|
{
|
||||||
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
// 8x, 8xQ are available
|
||||||
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
||||||
if (qlevels > 0)
|
a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2));
|
||||||
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
|
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
||||||
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
||||||
if (qlevels > 0)
|
|
||||||
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
|
||||||
|
|
||||||
if (isNvidia)
|
|
||||||
{
|
{
|
||||||
// CSAA support
|
if (qlevels > 2)
|
||||||
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
||||||
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
|
|
||||||
{
|
{
|
||||||
if (qlevels > 2)
|
// 16x, 16xQ are available
|
||||||
{
|
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
||||||
// 8x, 8xQ are available
|
a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4));
|
||||||
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2));
|
||||||
a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2));
|
|
||||||
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
||||||
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
|
||||||
{
|
|
||||||
if (qlevels > 2)
|
|
||||||
{
|
|
||||||
// 16x, 16xQ are available
|
|
||||||
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
|
||||||
a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4));
|
|
||||||
a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (a.aa_levels.size() == 1)
|
|
||||||
{
|
|
||||||
strcpy(a.aa_levels[0].name, "(Not supported on this device)");
|
|
||||||
}
|
|
||||||
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
|
|
||||||
for (int m = 0; m < numModes; m++)
|
|
||||||
{
|
|
||||||
D3DDISPLAYMODE mode;
|
|
||||||
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
|
|
||||||
|
|
||||||
int found = -1;
|
|
||||||
for (int x = 0; x < (int)a.resolutions.size(); x++)
|
|
||||||
{
|
|
||||||
if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height)
|
|
||||||
{
|
|
||||||
found = x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Resolution temp;
|
|
||||||
Resolution &r = found==-1 ? temp : a.resolutions[found];
|
|
||||||
|
|
||||||
sprintf(r.name, "%ix%i", mode.Width, mode.Height);
|
|
||||||
r.bitdepths.insert(mode.Format);
|
|
||||||
r.refreshes.insert(mode.RefreshRate);
|
|
||||||
if (found == -1 && mode.Width >= 640 && mode.Height >= 480)
|
|
||||||
{
|
|
||||||
r.xres = mode.Width;
|
|
||||||
r.yres = mode.Height;
|
|
||||||
a.resolutions.push_back(r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (a.aa_levels.size() == 1)
|
||||||
|
{
|
||||||
|
strcpy(a.aa_levels[0].name, "(Not supported on this device)");
|
||||||
|
}
|
||||||
|
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
|
||||||
|
for (int m = 0; m < numModes; m++)
|
||||||
|
{
|
||||||
|
D3DDISPLAYMODE mode;
|
||||||
|
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
|
||||||
|
|
||||||
|
int found = -1;
|
||||||
|
for (int x = 0; x < (int)a.resolutions.size(); x++)
|
||||||
|
{
|
||||||
|
if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height)
|
||||||
|
{
|
||||||
|
found = x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Resolution temp;
|
||||||
|
Resolution &r = found==-1 ? temp : a.resolutions[found];
|
||||||
|
|
||||||
|
sprintf(r.name, "%ix%i", mode.Width, mode.Height);
|
||||||
|
r.bitdepths.insert(mode.Format);
|
||||||
|
r.refreshes.insert(mode.RefreshRate);
|
||||||
|
if (found == -1 && mode.Width >= 640 && mode.Height >= 480)
|
||||||
|
{
|
||||||
|
r.xres = mode.Width;
|
||||||
|
r.yres = mode.Height;
|
||||||
|
a.resolutions.push_back(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode, bool auto_depth)
|
HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode, bool auto_depth)
|
||||||
|
{
|
||||||
|
hWnd = wnd;
|
||||||
|
fullScreen = _fullscreen;
|
||||||
|
nextFullScreen = _fullscreen;
|
||||||
|
multisample = aa_mode;
|
||||||
|
resolution = _resolution;
|
||||||
|
auto_depth_stencil = auto_depth;
|
||||||
|
cur_adapter = adapter;
|
||||||
|
D3DPRESENT_PARAMETERS d3dpp;
|
||||||
|
InitPP(adapter, resolution, aa_mode, &d3dpp);
|
||||||
|
|
||||||
|
if (FAILED(D3D->CreateDevice(
|
||||||
|
adapter,
|
||||||
|
D3DDEVTYPE_HAL,
|
||||||
|
wnd,
|
||||||
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||||
|
&d3dpp, &dev)))
|
||||||
{
|
{
|
||||||
hWnd = wnd;
|
MessageBox(wnd,
|
||||||
fullScreen = _fullscreen;
|
_T("Sorry, but it looks like your 3D accelerator is too old,\n")
|
||||||
nextFullScreen = _fullscreen;
|
_T("or doesn't support features that Dolphin requires.\n")
|
||||||
multisample = aa_mode;
|
_T("Falling back to software vertex processing.\n"),
|
||||||
resolution = _resolution;
|
_T("Dolphin Direct3D plugin"), MB_OK | MB_ICONERROR);
|
||||||
auto_depth_stencil = auto_depth;
|
|
||||||
cur_adapter = adapter;
|
|
||||||
D3DPRESENT_PARAMETERS d3dpp;
|
|
||||||
InitPP(adapter, resolution, aa_mode, &d3dpp);
|
|
||||||
|
|
||||||
if (FAILED(D3D->CreateDevice(
|
if (FAILED(D3D->CreateDevice(
|
||||||
adapter,
|
adapter,
|
||||||
D3DDEVTYPE_HAL,
|
D3DDEVTYPE_HAL,
|
||||||
wnd,
|
wnd,
|
||||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
|
||||||
|
// |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/,
|
||||||
|
//D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
|
||||||
&d3dpp, &dev)))
|
&d3dpp, &dev)))
|
||||||
{
|
{
|
||||||
MessageBox(wnd,
|
MessageBox(wnd,
|
||||||
_T("Sorry, but it looks like your 3D accelerator is too old,\n")
|
_T("Software VP failed too. Upgrade your graphics card."),
|
||||||
_T("or doesn't support features that Dolphin requires.\n")
|
|
||||||
_T("Falling back to software vertex processing.\n"),
|
|
||||||
_T("Dolphin Direct3D plugin"), MB_OK | MB_ICONERROR);
|
_T("Dolphin Direct3D plugin"), MB_OK | MB_ICONERROR);
|
||||||
if (FAILED(D3D->CreateDevice(
|
return E_FAIL;
|
||||||
adapter,
|
|
||||||
D3DDEVTYPE_HAL,
|
|
||||||
wnd,
|
|
||||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
|
|
||||||
// |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/,
|
|
||||||
//D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
|
|
||||||
&d3dpp, &dev)))
|
|
||||||
{
|
|
||||||
MessageBox(wnd,
|
|
||||||
_T("Software VP failed too. Upgrade your graphics card."),
|
|
||||||
_T("Dolphin Direct3D plugin"), MB_OK | MB_ICONERROR);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dev->GetDeviceCaps(&caps);
|
|
||||||
dev->GetRenderTarget(0, &back_buffer);
|
|
||||||
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
|
||||||
back_buffer_z = NULL;
|
|
||||||
|
|
||||||
// Device state would normally be set here
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
dev->GetDeviceCaps(&caps);
|
||||||
|
dev->GetRenderTarget(0, &back_buffer);
|
||||||
|
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
||||||
|
back_buffer_z = NULL;
|
||||||
|
|
||||||
void Close()
|
// Device state would normally be set here
|
||||||
{
|
return S_OK;
|
||||||
dev->Release();
|
}
|
||||||
dev = 0;
|
|
||||||
}
|
void Close()
|
||||||
|
{
|
||||||
|
dev->Release();
|
||||||
|
dev = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const D3DCAPS9 &GetCaps()
|
const D3DCAPS9 &GetCaps()
|
||||||
{
|
{
|
||||||
|
@ -318,86 +318,96 @@ void ShowD3DError(HRESULT err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
{
|
||||||
|
if (dev)
|
||||||
{
|
{
|
||||||
if (dev)
|
ForgetCachedState();
|
||||||
{
|
|
||||||
// Can't keep a pointer around to the backbuffer surface when resetting.
|
// Can't keep a pointer around to the backbuffer surface when resetting.
|
||||||
if (back_buffer_z)
|
if (back_buffer_z)
|
||||||
back_buffer_z->Release();
|
back_buffer_z->Release();
|
||||||
|
back_buffer_z = NULL;
|
||||||
|
back_buffer->Release();
|
||||||
|
back_buffer = NULL;
|
||||||
|
|
||||||
|
D3DPRESENT_PARAMETERS d3dpp;
|
||||||
|
InitPP(cur_adapter, resolution, multisample, &d3dpp);
|
||||||
|
HRESULT hr = dev->Reset(&d3dpp);
|
||||||
|
ShowD3DError(hr);
|
||||||
|
|
||||||
|
dev->GetRenderTarget(0, &back_buffer);
|
||||||
|
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
||||||
back_buffer_z = NULL;
|
back_buffer_z = NULL;
|
||||||
back_buffer->Release();
|
|
||||||
back_buffer = NULL;
|
|
||||||
|
|
||||||
D3DPRESENT_PARAMETERS d3dpp;
|
|
||||||
InitPP(cur_adapter, resolution, multisample, &d3dpp);
|
|
||||||
HRESULT hr = dev->Reset(&d3dpp);
|
|
||||||
ShowD3DError(hr);
|
|
||||||
|
|
||||||
dev->GetRenderTarget(0, &back_buffer);
|
|
||||||
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
|
||||||
back_buffer_z = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsFullscreen()
|
bool IsFullscreen()
|
||||||
|
{
|
||||||
|
return fullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetBackBufferWidth()
|
||||||
|
{
|
||||||
|
return xres;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetBackBufferHeight()
|
||||||
|
{
|
||||||
|
return yres;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwitchFullscreen(bool fullscreen)
|
||||||
|
{
|
||||||
|
nextFullScreen = fullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginFrame()
|
||||||
|
{
|
||||||
|
if (bFrameInProgress)
|
||||||
{
|
{
|
||||||
return fullScreen;
|
PanicAlert("BeginFrame WTF");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
bFrameInProgress = true;
|
||||||
int GetBackBufferWidth()
|
if (dev)
|
||||||
{
|
{
|
||||||
return xres;
|
dev->BeginScene();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int GetBackBufferHeight()
|
void EndFrame()
|
||||||
|
{
|
||||||
|
if (!bFrameInProgress)
|
||||||
{
|
{
|
||||||
return yres;
|
PanicAlert("EndFrame WTF");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
bFrameInProgress = false;
|
||||||
|
|
||||||
void SwitchFullscreen(bool fullscreen)
|
if (dev)
|
||||||
{
|
{
|
||||||
nextFullScreen = fullscreen;
|
dev->EndScene();
|
||||||
|
dev->Present(NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BeginFrame()
|
if (fullScreen != nextFullScreen)
|
||||||
{
|
{
|
||||||
if (bFrameInProgress)
|
fullScreen = nextFullScreen;
|
||||||
{
|
Reset();
|
||||||
PanicAlert("BeginFrame WTF");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bFrameInProgress = true;
|
|
||||||
if (dev)
|
|
||||||
{
|
|
||||||
dev->BeginScene();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EndFrame()
|
void ForgetCachedState()
|
||||||
{
|
{
|
||||||
if (!bFrameInProgress)
|
memset(m_Textures, 0, sizeof(m_Textures));
|
||||||
{
|
memset(m_RenderStates, 0xFF, sizeof(m_RenderStates));
|
||||||
PanicAlert("EndFrame WTF");
|
memset(m_TextureStageStates, 0xFF, sizeof(m_TextureStageStates));
|
||||||
return;
|
memset(m_SamplerStates, 0xFF, sizeof(m_SamplerStates));
|
||||||
}
|
}
|
||||||
bFrameInProgress = false;
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
{
|
|
||||||
dev->EndScene();
|
|
||||||
dev->Present(NULL, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullScreen != nextFullScreen)
|
|
||||||
{
|
|
||||||
fullScreen = nextFullScreen;
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
|
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@ void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
|
||||||
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
||||||
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
||||||
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
||||||
|
void ForgetCachedState();
|
||||||
|
|
||||||
// Utility functions for vendor specific hacks. So far, just the one.
|
// Utility functions for vendor specific hacks. So far, just the one.
|
||||||
void EnableAlphaToCoverage();
|
void EnableAlphaToCoverage();
|
||||||
|
|
|
@ -23,352 +23,353 @@
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
CD3DFont font;
|
CD3DFont font;
|
||||||
|
|
||||||
#define MAX_NUM_VERTICES 50*6
|
#define MAX_NUM_VERTICES 50*6
|
||||||
struct FONT2DVERTEX {
|
struct FONT2DVERTEX {
|
||||||
float x,y,z;
|
float x,y,z;
|
||||||
float rhw;
|
float rhw;
|
||||||
u32 color;
|
u32 color;
|
||||||
float tu, tv;
|
float tu, tv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||||
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1)
|
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1)
|
||||||
|
|
||||||
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
|
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
|
||||||
|
{
|
||||||
|
FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
CD3DFont::CD3DFont()
|
||||||
|
{
|
||||||
|
m_pTexture = NULL;
|
||||||
|
m_pVB = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {m_dwTexWidth = 512, m_dwTexHeight = 512};
|
||||||
|
|
||||||
|
int CD3DFont::Init()
|
||||||
|
{
|
||||||
|
// Create vertex buffer for the letters
|
||||||
|
HRESULT hr;
|
||||||
|
if (FAILED(hr = dev->CreateVertexBuffer(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX),
|
||||||
|
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVB, NULL)))
|
||||||
{
|
{
|
||||||
FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv;
|
return hr;
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
||||||
|
|
||||||
CD3DFont::CD3DFont()
|
// Prepare to create a bitmap
|
||||||
|
int *pBitmapBits;
|
||||||
|
BITMAPINFO bmi;
|
||||||
|
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||||
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
||||||
|
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
||||||
|
bmi.bmiHeader.biPlanes = 1;
|
||||||
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||||||
|
bmi.bmiHeader.biBitCount = 32;
|
||||||
|
|
||||||
|
// Create a DC and a bitmap for the font
|
||||||
|
HDC hDC = CreateCompatibleDC(NULL);
|
||||||
|
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
|
||||||
|
SetMapMode(hDC, MM_TEXT);
|
||||||
|
|
||||||
|
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
||||||
|
// antialiased font, but this is not guaranteed.
|
||||||
|
// We definitely don't want to get it cleartype'd, anyway.
|
||||||
|
int m_dwFontHeight = 24;
|
||||||
|
int nHeight = -MulDiv(m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72);
|
||||||
|
int dwBold = FW_NORMAL; ///FW_BOLD
|
||||||
|
HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
|
||||||
|
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||||
|
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
||||||
|
VARIABLE_PITCH, _T("Tahoma"));
|
||||||
|
if (NULL == hFont)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
||||||
|
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
||||||
|
|
||||||
|
// Set text properties
|
||||||
|
SetTextColor(hDC, 0xFFFFFF);
|
||||||
|
SetBkColor (hDC, 0);
|
||||||
|
SetTextAlign(hDC, TA_TOP);
|
||||||
|
|
||||||
|
// Loop through all printable character and output them to the bitmap..
|
||||||
|
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||||
|
int x = 0, y = 0;
|
||||||
|
char str[2] = "\0";
|
||||||
|
for (int c = 0; c < 127 - 32; c++)
|
||||||
{
|
{
|
||||||
m_pTexture = NULL;
|
str[0] = c + 32;
|
||||||
m_pVB = NULL;
|
SIZE size;
|
||||||
}
|
GetTextExtentPoint32A(hDC, str, 1, &size);
|
||||||
enum {m_dwTexWidth = 512, m_dwTexHeight = 512};
|
if ((int)(x+size.cx+1) > m_dwTexWidth)
|
||||||
|
|
||||||
int CD3DFont::Init()
|
|
||||||
{
|
|
||||||
// Create vertex buffer for the letters
|
|
||||||
HRESULT hr;
|
|
||||||
if (FAILED(hr = dev->CreateVertexBuffer(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX),
|
|
||||||
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVB, NULL)))
|
|
||||||
{
|
{
|
||||||
return hr;
|
x = 0;
|
||||||
}
|
y += size.cy + 1;
|
||||||
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
|
||||||
|
|
||||||
// Prepare to create a bitmap
|
|
||||||
int *pBitmapBits;
|
|
||||||
BITMAPINFO bmi;
|
|
||||||
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
|
||||||
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
|
||||||
|
|
||||||
// Create a DC and a bitmap for the font
|
|
||||||
HDC hDC = CreateCompatibleDC(NULL);
|
|
||||||
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
|
|
||||||
SetMapMode(hDC, MM_TEXT);
|
|
||||||
|
|
||||||
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
|
||||||
// antialiased font, but this is not guaranteed.
|
|
||||||
// We definitely don't want to get it cleartype'd, anyway.
|
|
||||||
int m_dwFontHeight = 24;
|
|
||||||
int nHeight = -MulDiv(m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72);
|
|
||||||
int dwBold = FW_NORMAL; ///FW_BOLD
|
|
||||||
HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
|
|
||||||
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
|
||||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
|
||||||
VARIABLE_PITCH, _T("Tahoma"));
|
|
||||||
if (NULL == hFont)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
|
||||||
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
|
||||||
|
|
||||||
// Set text properties
|
|
||||||
SetTextColor(hDC, 0xFFFFFF);
|
|
||||||
SetBkColor (hDC, 0);
|
|
||||||
SetTextAlign(hDC, TA_TOP);
|
|
||||||
|
|
||||||
// Loop through all printable character and output them to the bitmap..
|
|
||||||
// Meanwhile, keep track of the corresponding tex coords for each character.
|
|
||||||
int x = 0, y = 0;
|
|
||||||
char str[2] = "\0";
|
|
||||||
for (int c = 0; c < 127 - 32; c++)
|
|
||||||
{
|
|
||||||
str[0] = c + 32;
|
|
||||||
SIZE size;
|
|
||||||
GetTextExtentPoint32A(hDC, str, 1, &size);
|
|
||||||
if ((int)(x+size.cx+1) > m_dwTexWidth)
|
|
||||||
{
|
|
||||||
x = 0;
|
|
||||||
y += size.cy + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
|
||||||
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
|
|
||||||
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
|
|
||||||
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
|
||||||
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
|
||||||
|
|
||||||
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new texture for the font
|
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
||||||
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
|
||||||
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
|
||||||
if (FAILED(hr))
|
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
||||||
{
|
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
||||||
PanicAlert("Failed to create font texture");
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock the surface and write the alpha values for the set pixels
|
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i)
|
||||||
D3DLOCKED_RECT d3dlr;
|
|
||||||
m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD);
|
|
||||||
int bAlpha; // 4-bit measure of pixel intensity
|
|
||||||
|
|
||||||
for (y = 0; y < m_dwTexHeight; y++)
|
|
||||||
{
|
|
||||||
u16 *pDst16 = (u16*)((u8 *)d3dlr.pBits + y * d3dlr.Pitch);
|
|
||||||
for (x = 0; x < m_dwTexWidth; x++)
|
|
||||||
{
|
|
||||||
bAlpha = ((pBitmapBits[m_dwTexWidth * y + x] & 0xff) >> 4);
|
|
||||||
pDst16[x] = (bAlpha << 12) | 0x0fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done updating texture, so clean up used objects
|
|
||||||
m_pTexture->UnlockRect(0);
|
|
||||||
|
|
||||||
SelectObject(hDC, hOldbmBitmap);
|
|
||||||
DeleteObject(hbmBitmap);
|
|
||||||
|
|
||||||
SelectObject(hDC, hOldFont);
|
|
||||||
DeleteObject(hFont);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CD3DFont::Shutdown()
|
// Create a new texture for the font
|
||||||
|
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
||||||
|
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
m_pVB->Release();
|
PanicAlert("Failed to create font texture");
|
||||||
m_pVB = NULL;
|
return hr;
|
||||||
m_pTexture->Release();
|
|
||||||
m_pTexture = NULL;
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lock the surface and write the alpha values for the set pixels
|
||||||
|
D3DLOCKED_RECT d3dlr;
|
||||||
|
m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD);
|
||||||
|
int bAlpha; // 4-bit measure of pixel intensity
|
||||||
|
|
||||||
const int RS[6][2] =
|
for (y = 0; y < m_dwTexHeight; y++)
|
||||||
{
|
{
|
||||||
{D3DRS_ALPHABLENDENABLE, TRUE},
|
u16 *pDst16 = (u16*)((u8 *)d3dlr.pBits + y * d3dlr.Pitch);
|
||||||
{D3DRS_SRCBLEND, D3DBLEND_SRCALPHA},
|
for (x = 0; x < m_dwTexWidth; x++)
|
||||||
{D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA},
|
|
||||||
{D3DRS_CULLMODE, D3DCULL_NONE},
|
|
||||||
{D3DRS_ZENABLE, FALSE},
|
|
||||||
{D3DRS_FOGENABLE, FALSE},
|
|
||||||
};
|
|
||||||
const int TS[6][2] =
|
|
||||||
{
|
|
||||||
{D3DTSS_COLOROP, D3DTOP_MODULATE},
|
|
||||||
{D3DTSS_COLORARG1, D3DTA_TEXTURE},
|
|
||||||
{D3DTSS_COLORARG2, D3DTA_DIFFUSE },
|
|
||||||
{D3DTSS_ALPHAOP, D3DTOP_MODULATE },
|
|
||||||
{D3DTSS_ALPHAARG1, D3DTA_TEXTURE },
|
|
||||||
{D3DTSS_ALPHAARG2, D3DTA_DIFFUSE },
|
|
||||||
};
|
|
||||||
|
|
||||||
static DWORD RS_old[6];
|
|
||||||
static DWORD TS_old[6];
|
|
||||||
static LPDIRECT3DBASETEXTURE9 texture_old;
|
|
||||||
static LPDIRECT3DPIXELSHADER9 ps_old;
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 vs_old;
|
|
||||||
|
|
||||||
void SaveRenderStates()
|
|
||||||
{
|
|
||||||
// TODO: Get rid of these Gets so we can potentially switch to Pure Device
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
{
|
||||||
dev->GetRenderState((_D3DRENDERSTATETYPE)RS[i][0], &(RS_old[i]));
|
bAlpha = ((pBitmapBits[m_dwTexWidth * y + x] & 0xff) >> 4);
|
||||||
dev->GetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), &(TS_old[i]));
|
pDst16[x] = (bAlpha << 12) | 0x0fff;
|
||||||
}
|
|
||||||
dev->GetTexture(0, &texture_old);
|
|
||||||
dev->GetPixelShader(&ps_old);
|
|
||||||
dev->GetVertexShader(&vs_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RestoreRenderStates()
|
|
||||||
{
|
|
||||||
D3D::SetTexture(0, texture_old);
|
|
||||||
|
|
||||||
dev->SetPixelShader(ps_old);
|
|
||||||
dev->SetVertexShader(vs_old);
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
D3D::SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS_old[i]);
|
|
||||||
D3D::SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CD3DFont::SetRenderStates()
|
// Done updating texture, so clean up used objects
|
||||||
|
m_pTexture->UnlockRect(0);
|
||||||
|
|
||||||
|
SelectObject(hDC, hOldbmBitmap);
|
||||||
|
DeleteObject(hbmBitmap);
|
||||||
|
|
||||||
|
SelectObject(hDC, hOldFont);
|
||||||
|
DeleteObject(hFont);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CD3DFont::Shutdown()
|
||||||
|
{
|
||||||
|
m_pVB->Release();
|
||||||
|
m_pVB = NULL;
|
||||||
|
m_pTexture->Release();
|
||||||
|
m_pTexture = NULL;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int RS[6][2] =
|
||||||
|
{
|
||||||
|
{D3DRS_ALPHABLENDENABLE, TRUE},
|
||||||
|
{D3DRS_SRCBLEND, D3DBLEND_SRCALPHA},
|
||||||
|
{D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA},
|
||||||
|
{D3DRS_CULLMODE, D3DCULL_NONE},
|
||||||
|
{D3DRS_ZENABLE, FALSE},
|
||||||
|
{D3DRS_FOGENABLE, FALSE},
|
||||||
|
};
|
||||||
|
const int TS[6][2] =
|
||||||
|
{
|
||||||
|
{D3DTSS_COLOROP, D3DTOP_MODULATE},
|
||||||
|
{D3DTSS_COLORARG1, D3DTA_TEXTURE},
|
||||||
|
{D3DTSS_COLORARG2, D3DTA_DIFFUSE },
|
||||||
|
{D3DTSS_ALPHAOP, D3DTOP_MODULATE },
|
||||||
|
{D3DTSS_ALPHAARG1, D3DTA_TEXTURE },
|
||||||
|
{D3DTSS_ALPHAARG2, D3DTA_DIFFUSE },
|
||||||
|
};
|
||||||
|
|
||||||
|
static DWORD RS_old[6];
|
||||||
|
static DWORD TS_old[6];
|
||||||
|
static LPDIRECT3DBASETEXTURE9 texture_old;
|
||||||
|
static LPDIRECT3DPIXELSHADER9 ps_old;
|
||||||
|
static LPDIRECT3DVERTEXSHADER9 vs_old;
|
||||||
|
|
||||||
|
void SaveRenderStates()
|
||||||
|
{
|
||||||
|
// TODO: Get rid of these Gets so we can potentially switch to Pure Device
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
D3D::SetTexture(0, m_pTexture);
|
dev->GetRenderState((_D3DRENDERSTATETYPE)RS[i][0], &(RS_old[i]));
|
||||||
|
dev->GetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), &(TS_old[i]));
|
||||||
|
}
|
||||||
|
dev->GetTexture(0, &texture_old);
|
||||||
|
dev->GetPixelShader(&ps_old);
|
||||||
|
dev->GetVertexShader(&vs_old);
|
||||||
|
}
|
||||||
|
|
||||||
dev->SetPixelShader(0);
|
void RestoreRenderStates()
|
||||||
dev->SetVertexShader(0);
|
{
|
||||||
|
D3D::SetTexture(0, texture_old);
|
||||||
|
|
||||||
dev->SetFVF(D3DFVF_FONT2DVERTEX);
|
dev->SetPixelShader(ps_old);
|
||||||
|
dev->SetVertexShader(vs_old);
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
D3D::SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS[i][1]);
|
D3D::SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS_old[i]);
|
||||||
D3D::SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]);
|
D3D::SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CD3DFont::SetRenderStates()
|
||||||
|
{
|
||||||
|
D3D::SetTexture(0, m_pTexture);
|
||||||
|
|
||||||
|
dev->SetPixelShader(0);
|
||||||
|
dev->SetVertexShader(0);
|
||||||
|
|
||||||
|
dev->SetFVF(D3DFVF_FONT2DVERTEX);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
D3D::SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS[i][1]);
|
||||||
|
D3D::SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center)
|
||||||
|
{
|
||||||
|
if (!m_pVB)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SaveRenderStates();
|
||||||
|
SetRenderStates();
|
||||||
|
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
|
||||||
|
|
||||||
|
float vpWidth = 1;
|
||||||
|
float vpHeight = 1;
|
||||||
|
|
||||||
|
float sx = x*vpWidth-0.5f;
|
||||||
|
float sy = y*vpHeight-0.5f;
|
||||||
|
|
||||||
|
float fStartX = sx;
|
||||||
|
|
||||||
|
float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight);
|
||||||
|
// Fill vertex buffer
|
||||||
|
FONT2DVERTEX* pVertices;
|
||||||
|
int dwNumTriangles = 0L;
|
||||||
|
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
||||||
|
|
||||||
|
const char *oldstrText=strText;
|
||||||
|
//First, let's measure the text
|
||||||
|
float tw=0;
|
||||||
|
float mx=0;
|
||||||
|
float maxx=0;
|
||||||
|
|
||||||
|
while (*strText)
|
||||||
|
{
|
||||||
|
char c = *strText++;
|
||||||
|
|
||||||
|
if (c == ('\n'))
|
||||||
|
mx = 0;
|
||||||
|
if (c < (' '))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float tx1 = m_fTexCoords[c-32][0];
|
||||||
|
float tx2 = m_fTexCoords[c-32][2];
|
||||||
|
|
||||||
|
float w = (tx2-tx1)*m_dwTexWidth;
|
||||||
|
w *= (fXScale*vpHeight)*invLineHeight;
|
||||||
|
mx += w + spacing*fXScale*vpWidth;
|
||||||
|
if (mx > maxx) maxx = mx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float offset = -maxx/2;
|
||||||
int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center)
|
strText = oldstrText;
|
||||||
|
//Then let's draw it
|
||||||
|
if (center)
|
||||||
{
|
{
|
||||||
if (!m_pVB)
|
sx+=offset;
|
||||||
return 0;
|
fStartX+=offset;
|
||||||
|
}
|
||||||
|
|
||||||
SaveRenderStates();
|
float wScale = (fXScale*vpHeight)*invLineHeight;
|
||||||
SetRenderStates();
|
float hScale = (fYScale*vpHeight)*invLineHeight;
|
||||||
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
|
|
||||||
|
|
||||||
float vpWidth = 1;
|
while (*strText)
|
||||||
float vpHeight = 1;
|
{
|
||||||
|
char c = *strText++;
|
||||||
|
|
||||||
float sx = x*vpWidth-0.5f;
|
if (c == ('\n'))
|
||||||
float sy = y*vpHeight-0.5f;
|
|
||||||
|
|
||||||
float fStartX = sx;
|
|
||||||
|
|
||||||
float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight);
|
|
||||||
// Fill vertex buffer
|
|
||||||
FONT2DVERTEX* pVertices;
|
|
||||||
int dwNumTriangles = 0L;
|
|
||||||
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
|
||||||
|
|
||||||
const char *oldstrText=strText;
|
|
||||||
//First, let's measure the text
|
|
||||||
float tw=0;
|
|
||||||
float mx=0;
|
|
||||||
float maxx=0;
|
|
||||||
|
|
||||||
while (*strText)
|
|
||||||
{
|
{
|
||||||
char c = *strText++;
|
sx = fStartX;
|
||||||
|
sy += fYScale*vpHeight;
|
||||||
if (c == ('\n'))
|
|
||||||
mx = 0;
|
|
||||||
if (c < (' '))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float tx1 = m_fTexCoords[c-32][0];
|
|
||||||
float tx2 = m_fTexCoords[c-32][2];
|
|
||||||
|
|
||||||
float w = (tx2-tx1)*m_dwTexWidth;
|
|
||||||
w *= (fXScale*vpHeight)*invLineHeight;
|
|
||||||
mx += w + spacing*fXScale*vpWidth;
|
|
||||||
if (mx > maxx) maxx = mx;
|
|
||||||
}
|
}
|
||||||
|
if (c < (' '))
|
||||||
|
continue;
|
||||||
|
|
||||||
float offset = -maxx/2;
|
c-=32;
|
||||||
strText = oldstrText;
|
float tx1 = m_fTexCoords[c][0];
|
||||||
//Then let's draw it
|
float ty1 = m_fTexCoords[c][1];
|
||||||
if (center)
|
float tx2 = m_fTexCoords[c][2];
|
||||||
|
float ty2 = m_fTexCoords[c][3];
|
||||||
|
|
||||||
|
float w = (tx2-tx1)*m_dwTexWidth;
|
||||||
|
float h = (ty2-ty1)*m_dwTexHeight;
|
||||||
|
|
||||||
|
w *= wScale;
|
||||||
|
h *= hScale;
|
||||||
|
|
||||||
|
FONT2DVERTEX v[6];
|
||||||
|
v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
|
||||||
|
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
||||||
|
v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
|
||||||
|
v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
|
||||||
|
v[4] = v[2];
|
||||||
|
v[5] = v[1];
|
||||||
|
|
||||||
|
memcpy(pVertices, v, 6*sizeof(FONT2DVERTEX));
|
||||||
|
|
||||||
|
pVertices+=6;
|
||||||
|
dwNumTriangles += 2;
|
||||||
|
|
||||||
|
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
||||||
{
|
{
|
||||||
sx+=offset;
|
// Unlock, render, and relock the vertex buffer
|
||||||
fStartX+=offset;
|
m_pVB->Unlock();
|
||||||
}
|
|
||||||
|
|
||||||
float wScale = (fXScale*vpHeight)*invLineHeight;
|
|
||||||
float hScale = (fYScale*vpHeight)*invLineHeight;
|
|
||||||
|
|
||||||
while (*strText)
|
|
||||||
{
|
|
||||||
char c = *strText++;
|
|
||||||
|
|
||||||
if (c == ('\n'))
|
|
||||||
{
|
|
||||||
sx = fStartX;
|
|
||||||
sy += fYScale*vpHeight;
|
|
||||||
}
|
|
||||||
if (c < (' '))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
c-=32;
|
|
||||||
float tx1 = m_fTexCoords[c][0];
|
|
||||||
float ty1 = m_fTexCoords[c][1];
|
|
||||||
float tx2 = m_fTexCoords[c][2];
|
|
||||||
float ty2 = m_fTexCoords[c][3];
|
|
||||||
|
|
||||||
float w = (tx2-tx1)*m_dwTexWidth;
|
|
||||||
float h = (ty2-ty1)*m_dwTexHeight;
|
|
||||||
|
|
||||||
w *= wScale;
|
|
||||||
h *= hScale;
|
|
||||||
|
|
||||||
FONT2DVERTEX v[6];
|
|
||||||
v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
|
|
||||||
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
|
||||||
v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
|
|
||||||
v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
|
|
||||||
v[4] = v[2];
|
|
||||||
v[5] = v[1];
|
|
||||||
|
|
||||||
memcpy(pVertices, v, 6*sizeof(FONT2DVERTEX));
|
|
||||||
|
|
||||||
pVertices+=6;
|
|
||||||
dwNumTriangles += 2;
|
|
||||||
|
|
||||||
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
|
||||||
{
|
|
||||||
// Unlock, render, and relock the vertex buffer
|
|
||||||
m_pVB->Unlock();
|
|
||||||
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
|
||||||
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
|
||||||
dwNumTriangles = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sx += w + spacing*fXScale*vpWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock and render the vertex buffer
|
|
||||||
m_pVB->Unlock();
|
|
||||||
if (dwNumTriangles > 0)
|
|
||||||
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
||||||
RestoreRenderStates();
|
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
||||||
return S_OK;
|
dwNumTriangles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sx += w + spacing*fXScale*vpWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2)
|
// Unlock and render the vertex buffer
|
||||||
{
|
m_pVB->Unlock();
|
||||||
SaveRenderStates();
|
if (dwNumTriangles > 0)
|
||||||
struct Q2DVertex { float x,y,z,rhw; u32 color; float u, v; } coords[4] = {
|
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
||||||
{x1-0.5f, y1-0.5f, 0, 1, color, u1, v1},
|
RestoreRenderStates();
|
||||||
{x2-0.5f, y1-0.5f, 0, 1, color, u2, v1},
|
return S_OK;
|
||||||
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
}
|
||||||
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
|
||||||
};
|
|
||||||
dev->SetPixelShader(0);
|
|
||||||
dev->SetVertexShader(0);
|
|
||||||
dev->SetVertexDeclaration(0);
|
|
||||||
|
|
||||||
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2)
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
{
|
||||||
|
SaveRenderStates();
|
||||||
|
struct Q2DVertex { float x,y,z,rhw; u32 color; float u, v; } coords[4] = {
|
||||||
|
{x1-0.5f, y1-0.5f, 0, 1, color, u1, v1},
|
||||||
|
{x2-0.5f, y1-0.5f, 0, 1, color, u2, v1},
|
||||||
|
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
||||||
|
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
||||||
|
};
|
||||||
|
dev->SetPixelShader(0);
|
||||||
|
dev->SetVertexShader(0);
|
||||||
|
dev->SetVertexDeclaration(0);
|
||||||
|
|
||||||
RestoreRenderStates();
|
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||||
}
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
||||||
|
|
||||||
|
RestoreRenderStates();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue