204 lines
5.6 KiB
Text
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;
|
|
}
|