historical/toontown-classic.git/panda/include/dxGraphicsStateGuardian9.I
2024-01-16 11:20:27 -06:00

204 lines
5.6 KiB
Text

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dxGraphicsStateGuardian9.I
* @author mike
* @date 1999-02-02
*/
/**
* Converts Panda's floating-point LColor structure to DirectX's D3DCOLOR
* packed structure.
*/
INLINE DWORD DXGraphicsStateGuardian9::
LColor_to_D3DCOLOR(const LColor &cLColor) {
// MS VC defines _M_IX86 for x86. gcc should define _X86_
#if (defined(_M_IX86) || defined(_X86_)) && !defined(STDFLOAT_DOUBLE)
DWORD d3dcolor, tempcolorval=255;
// note the default FPU rounding mode will give 255*0.5f=0x80, not 0x7F as
// VC would force it to by resetting rounding mode don't think this makes
// much difference
__asm {
push ebx ; want to save this in case this fn is inlined
push ecx
mov ecx, cLColor
fild tempcolorval
fld DWORD PTR [ecx]
fmul ST(0), ST(1)
fistp tempcolorval ; no way to store directly to int register
mov eax, tempcolorval
shl eax, 16
fld DWORD PTR [ecx+4] ;grn
fmul ST(0), ST(1)
fistp tempcolorval
mov ebx, tempcolorval
shl ebx, 8
or eax, ebx
fld DWORD PTR [ecx+8] ;blue
fmul ST(0), ST(1)
fistp tempcolorval
or eax, tempcolorval
fld DWORD PTR [ecx+12] ;alpha
fmul ST(0), ST(1)
fistp tempcolorval
; simulate pop 255.0 off FP stack w/o store, mark top as empty and increment stk ptr
ffree ST(0)
fincstp
mov ebx, tempcolorval
shl ebx, 24
or eax, ebx
mov d3dcolor, eax
pop ecx
pop ebx
}
// dxgsg9_cat.debug() << (void*)d3dcolor << endl;
return d3dcolor;
#else //!_X86_
return D3DCOLOR_COLORVALUE(cLColor[0], cLColor[1], cLColor[2], cLColor[3]);
#endif //!_X86_
}
/**
* Maps from the Texture's internal wrap mode symbols to GL's.
*/
INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian9::
get_texture_wrap_mode(SamplerState::WrapMode wm) {
switch (wm) {
case SamplerState::WM_clamp:
return D3DTADDRESS_CLAMP;
case SamplerState::WM_repeat:
return D3DTADDRESS_WRAP;
case SamplerState::WM_mirror:
return D3DTADDRESS_MIRROR;
case SamplerState::WM_mirror_once:
return D3DTADDRESS_MIRRORONCE;
case SamplerState::WM_border_color:
return D3DTADDRESS_BORDER;
}
dxgsg9_cat.error() << "Invalid Texture::Mode value" << std::endl;
return D3DTADDRESS_WRAP;
}
/**
* Maps from the fog types to gl version
*/
INLINE D3DFOGMODE DXGraphicsStateGuardian9::
get_fog_mode_type(Fog::Mode m) {
switch (m) {
case Fog::M_linear:
return D3DFOG_LINEAR;
case Fog::M_exponential:
return D3DFOG_EXP;
case Fog::M_exponential_squared:
return D3DFOG_EXP2;
}
dxgsg9_cat.error() << "Invalid Fog::Mode value" << std::endl;
return D3DFOG_EXP;
}
/**
* Returns the nth D3DTS_TEXTURE(n) constant.
*/
INLINE D3DTRANSFORMSTATETYPE DXGraphicsStateGuardian9::
get_tex_mat_sym(int stage_index) {
return (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + stage_index);
}
/**
* Returns the address of a 64K buffer that is allocated at the beginning of a
* 64K block.
*/
INLINE unsigned char *DXGraphicsStateGuardian9::
get_safe_buffer_start() {
if (_temp_buffer == nullptr) {
// Guarantee we get a buffer of size 0x10000 bytes that begins on an even
// multiple of 0x10000. We do this by allocating double the required
// buffer, and then pointing to the first multiple of 0x10000 within that
// buffer.
_temp_buffer = new unsigned char[0x1ffff];
_safe_buffer_start = (unsigned char *)(((uintptr_t)_temp_buffer + 0xffff) & ~0xffff);
}
return _safe_buffer_start;
}
#define ALWAYS_SET_RENDER_STATE true
/**
* This function creates a common layer between DX and Panda for
* SetRenderState. It also keeps avoids setting redundant render states.
*/
INLINE HRESULT DXGraphicsStateGuardian9::
set_render_state (D3DRENDERSTATETYPE state, DWORD value)
{
HRESULT hr;
hr = D3D_OK;
if (ALWAYS_SET_RENDER_STATE || _render_state_array [state] != value)
{
hr = _d3d_device->SetRenderState(state, value);
_render_state_array [state] = value;
}
return hr;
}
/**
* This function creates a common layer between DX and Panda. It also keeps
* avoids setting redundant render states.
*/
INLINE HRESULT DXGraphicsStateGuardian9::
set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
{
HRESULT hr;
hr = D3D_OK;
if (ALWAYS_SET_RENDER_STATE || _texture_stage_states_array [stage].state_array [type] != value)
{
hr = _d3d_device->SetTextureStageState(stage, type, value);
_texture_stage_states_array [stage].state_array [type] = value;
}
return hr;
}
/**
* This function creates a common layer between DX and Panda. It also keeps
* avoids setting redundant render states.
*/
INLINE HRESULT DXGraphicsStateGuardian9::
set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value)
{
HRESULT hr;
hr = D3D_OK;
if (ALWAYS_SET_RENDER_STATE || _texture_render_states_array [sampler].state_array [type] != value)
{
hr = _d3d_device->SetSamplerState(sampler, type, value);
_texture_render_states_array [sampler].state_array [type] = value;
}
return hr;
}
/**
* Returns true if this particular GSG can render from a wdxGraphicsBuffer9
* directly into a texture, or false if it must always copy-to-texture at the
* end of each frame to achieve this effect.
*/
INLINE bool DXGraphicsStateGuardian9::
get_supports_render_texture() const {
return _supports_render_texture;
}