📄 wmlrenderer.cpp
字号:
Node* pkNode = WmlDynamicCast(Node,pkScene);
if ( pkNode )
{
for (int i = 0; i < pkNode->GetQuantity(); i++)
{
Spatial* pkChild = pkNode->GetChild(i);
if ( pkChild )
ReleaseTextures(pkChild);
}
}
}
//----------------------------------------------------------------------------
void Renderer::ReleaseShaders (Spatial* pkScene)
{
Node* pkNode = WmlDynamicCast(Node,pkScene);
if ( pkNode )
{
Geometry* pkGeom = WmlDynamicCast(Geometry, pkScene);
if ( pkGeom )
{
if ( pkGeom->GetVertexShader() )
{
ReleaseShader( pkGeom->GetVertexShader() );
}
if ( pkGeom->GetPixelShader() )
{
ReleaseShader( pkGeom->GetPixelShader() );
}
}
for (int i = 0; i < pkNode->GetQuantity(); i++)
{
Spatial* pkChild = pkNode->GetChild(i);
if ( pkChild )
{
ReleaseShaders( pkChild );
}
}
}
}
//----------------------------------------------------------------------------
void Renderer::SetStateConst (float* afData, const Geometry& rkGeom,
StateConstantType iType, int iTypeNum)
{
// This handles state that is not specific to the specific renderer.
// *Renderer should call this function in their own SetStateConst function
// to handle the rest.
// If the user asks for some light which does not exist, then
// it will throw an assert in debug mode and quietly fail with reasonable
// data (black for colors, the origin for positions, and
// UNIT_X for directions, etc...) which shouldn't break any shaders.
RenderState* pkState;
Light* pkLight;
switch( iType )
{
// things not handled here, but in the specific renderer
case RENDERER_MODVIEW:
case RENDERER_PROJ:
case RENDERER_MODVIEWPROJ:
case RENDERER_MOD:
// Camera State
case CAMERA_POSITION:
memcpy(afData, &m_spkCamera->GetLocation(), 3*sizeof(float));
afData[3] = 1.0f;
break;
case CAMERA_UP:
memcpy(afData, &m_spkCamera->GetUp(), 3*sizeof(float));
afData[3] = 0.0f;
break;
case CAMERA_LEFT:
memcpy(afData, &m_spkCamera->GetLeft(), 3*sizeof(float));
afData[3] = 0.0f;
break;
// Fog State
case FOG_COLOR:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_FOG];
memcpy(afData,((FogState*)pkState)->Color(),3*sizeof(float));
afData[3] = 1.0f;
break;
case FOG_PARAMS:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_FOG];
afData[0] = ((FogState*)pkState)->Start();
afData[1] = ((FogState*)pkState)->End();
afData[2] = ((FogState*)pkState)->Density();
afData[3] = (float)((FogState*)pkState)->Enabled();
break;
// Material State
case MATERIAL_EMISSIVE:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_MATERIAL];
memcpy(afData,((MaterialState*)pkState)->Emissive(),3*
sizeof(float) );
break;
case MATERIAL_AMBIENT:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_MATERIAL];
memcpy(afData,((MaterialState*)pkState)->Ambient(),3*
sizeof(float) );
break;
case MATERIAL_DIFFUSE:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_MATERIAL];
memcpy(afData,((MaterialState*)pkState)->Diffuse(),3*
sizeof(float) );
break;
case MATERIAL_SPECULAR:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_MATERIAL];
memcpy(afData,((MaterialState*)pkState)->Specular(),3*
sizeof(float) );
break;
case MATERIAL_SHININESS:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_MATERIAL];
afData[0] = ((MaterialState*)pkState)->Shininess();
break;
// Lights
// Because it's hard (right now) to do conditional statements in
// shader code, lights that are off will be supported by setting their
// color to (0,0,0,1), so that they do not emit any light. If the
// shader code uses light colors unconventionally, this may
// cause problems. Otherwise, you can use the same shader code with
// arbitrary lights that turn on and off.
case LIGHT_POSITION:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"No light to send position from" );
// For release mode, quietly fail with reasonable data
memcpy(afData,Vector3f::ZERO,3*sizeof(float));
afData[3] = 1.0f;
}
else if ( pkLight->GetType() == Light::LT_POINT )
{
memcpy(afData,((PointLight*)pkLight)->Location(),3*
sizeof(float));
afData[3] = 1.0f;
}
else if ( pkLight->GetType() == Light::LT_SPOT )
{
memcpy(afData,((SpotLight*)pkLight)->Location(),3*
sizeof(float));
afData[3] = 1.0f;
}
else
{
assert( !"Light type does not have a position." );
// For release mode, quietly fail with reasonable data
memcpy(afData,Vector3f::ZERO,3*sizeof(float));
afData[3] = 1.0f;
}
break;
case LIGHT_DIRECTION:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"No light to send direction from" );
// For release mode, quietly fail with reasonable data
memcpy(&afData[1],Vector3f::ZERO,3*sizeof(float));
afData[0] = 1.0f;
}
else if ( pkLight->GetType() == Light::LT_SPOT )
{
memcpy(afData,((SpotLight*)pkLight)->Direction(),3*
sizeof(float));
afData[3] = 0.0f;
}
else if ( pkLight->GetType() == Light::LT_DIRECTIONAL )
{
memcpy(afData,((DirectionalLight*)pkLight)->Direction(),3*
sizeof(float));
afData[3] = 0.0f;
}
else
{
assert( !"Light type does not have a direction." );
// For release mode, quietly fail with reasonable data
memcpy(&afData[1],Vector3f::ZERO,3*sizeof(float));
afData[0] = 1.0f;
}
break;
case LIGHT_AMBIENT:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"Light doesn't exist to send ambient from." );
// In release mode, quietly fail with no color
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
else if ( pkLight->On() )
{
memcpy(afData,pkLight->Ambient(),3*sizeof(float) );
afData[3] = 1.0f;
}
else
{
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
break;
case LIGHT_DIFFUSE:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"Light doesn't exist to send diffuse from." );
// In release mode, quietly fail with no color
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
else if ( pkLight->On() )
{
memcpy(afData,pkLight->Diffuse(),3*sizeof(float) );
afData[3] = 1.0f;
}
else
{
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
break;
case LIGHT_SPECULAR:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"Light doesn't exist to send specular from." );
// In release mode, quietly fail with no color
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
else if ( pkLight->On() )
{
memcpy(afData,pkLight->Specular(),3*sizeof(float) );
afData[3] = 1.0f;
}
else
{
memcpy(afData,&ColorRGB::BLACK,3*sizeof(float) );
afData[3] = 1.0f;
}
break;
case LIGHT_SPOTCUTOFF:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
assert( !"Light doesn't exist to send cut-off from." );
// Release mode reasonable data
afData[0] = 0.0f;
afData[1] = 1.0f;
afData[2] = 0.0f;
afData[3] = 1.0f;
}
if ( pkLight->GetType() == Light::LT_SPOT )
{
afData[0] = ((SpotLight*)pkLight)->GetAngle();
afData[1] = Mathf::Cos( afData[0] );
afData[2] = Mathf::Sin( afData[1] );
afData[3] = ((SpotLight*)pkLight)->Exponent();
}
else
{
assert( !"Not a spotlight!" );
// Release mode reasonable data
afData[0] = 0.0f;
afData[1] = 1.0f;
afData[2] = 0.0f;
afData[3] = 1.0f;
}
break;
case LIGHT_ATTENPARAMS:
pkState = rkGeom.GetRenderStateArray()[RenderState::RS_LIGHT];
pkLight = ((LightState*)pkState)->Get(iTypeNum);
if ( !pkLight )
{
afData[0] = 0.0f;
afData[1] = 0.0f;
afData[2] = 0.0f;
afData[3] = 0.0f;
}
else
{
afData[0] = pkLight->Constant();
afData[1] = pkLight->Linear();
afData[2] = pkLight->Quadratic();
afData[3] = pkLight->Intensity();
}
break;
case USER_DEFINED:
default:
// do nothing
break;
};
}
//----------------------------------------------------------------------------
void Renderer::SetShaderState (const Geometry* pkGeom)
{
if ( !pkGeom )
{
SetCurrentVertexShader(NULL);
SetCurrentPixelShader(NULL);
return;
}
SetCurrentVertexShader(pkGeom->GetVertexShader());
SetCurrentPixelShader(pkGeom->GetPixelShader());
}
//----------------------------------------------------------------------------
void Renderer::SetShaderConstants (const Geometry* pkGeom)
{
if ( !pkGeom )
return;
if ( m_pkCurVertexShader != pkGeom->GetVertexShader() )
{
// Your graphics card does not support vertex shaders.
return;
}
if ( m_pkCurPixelShader != pkGeom->GetPixelShader() )
{
// Your graphics card does not support pixel shaders.
return;
}
if ( m_pkCurVertexShader )
SetVertexShaderConst(pkGeom->GetVertexShaderConstants(),*pkGeom);
if ( m_pkCurPixelShader )
SetPixelShaderConst(pkGeom->GetPixelShaderConstants(),*pkGeom);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// streaming
//----------------------------------------------------------------------------
Object* Renderer::Factory (Stream&)
{
// Renderer is abstract, Factory never called. Renderers cannot be
// streamed anyway...
return NULL;
}
//----------------------------------------------------------------------------
void Renderer::Load (Stream&, Stream::Link*)
{
// Renderers cannot be streamed.
assert( false );
}
//----------------------------------------------------------------------------
void Renderer::Link (Stream&, Stream::Link*)
{
// Renderers cannot be streamed.
assert( false );
}
//----------------------------------------------------------------------------
bool Renderer::Register (Stream&)
{
// Renderers cannot be streamed.
assert( false );
return false;
}
//----------------------------------------------------------------------------
void Renderer::Save (Stream&)
{
// Renderers cannot be streamed.
assert( false );
}
//----------------------------------------------------------------------------
StringTree* Renderer::SaveStrings ()
{
StringTree* pkTree = new StringTree(4,0,2,0);
// strings
pkTree->SetString(0,MakeString(&ms_kRTTI,GetName()));
pkTree->SetString(1,MakeString("width =",m_iWidth));
pkTree->SetString(2,MakeString("height =",m_iHeight));
pkTree->SetString(3,MakeString("background color =",
m_kBackgroundColor));
// children
pkTree->SetChild(0,Object::SaveStrings());
pkTree->SetChild(1,m_spkCamera->SaveStrings());
return pkTree;
}
//----------------------------------------------------------------------------
int Renderer::GetMemoryUsed () const
{
int iBaseSize = sizeof(Renderer) - sizeof(Object);
int iTotalSize = iBaseSize + Object::GetMemoryUsed();
return iTotalSize;
}
//----------------------------------------------------------------------------
int Renderer::GetDiskUsed () const
{
// Renderers cannot be streamed.
assert( false );
return 0;
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -