📄 wmlrenderer.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003. All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.
#include "WmlRenderer.h"
#include "WmlNode.h"
#include "WmlPointLight.h"
#include "WmlSpotLight.h"
#include "WmlDirectionalLight.h"
#include "WmlScreenPolygon.h"
using namespace Wml;
WmlImplementRTTI(Renderer,Object);
WmlImplementStream(Renderer);
Renderer::List* Renderer::ms_pkRendererList = NULL;
//----------------------------------------------------------------------------
Renderer::Renderer (int iWidth, int iHeight)
:
m_kBackgroundColor(ColorRGB::WHITE)
{
m_iX = 0;
m_iY = 0;
m_iWidth = iWidth;
m_iHeight = iHeight;
m_iQuantity = m_iWidth*m_iHeight;
m_bCapMultitexture = false;
m_bCapSpecularAfterTexture = false;
m_bCapPlanarReflection = false;
m_bCapPlanarShadow = false;
m_bCapTextureClampToBorder = false;
m_bCapTextureApplyAdd = false;
m_bCapTextureApplyCombine = false;
m_bCapTextureApplyCombineDot3 = false;
m_bCapDot3BumpMapping = false;
m_iCapVertShaderVersion = Shader::UNSUPPORTED;
m_iCapPixShaderVersion = Shader::UNSUPPORTED;
m_bOverrideState = false;
m_bReverseCullState = false;
m_bDrawingReflected = false;
m_bOverrideAlphaState = false;
m_bOverrideTextureState = false;
m_eOverrideLightingMode = OLM_NONE;
m_pkCurrentBumpMap = NULL;
m_pkCurPixelShader = NULL;
m_pkCurVertexShader = NULL;
m_iTextureUnitRequested = 0;
m_iMaxTextureUnits = 0;
// add renderer to global list of renderers
List* pkItem = new List;
pkItem->m_pkRenderer = this;
pkItem->m_pkNext = ms_pkRendererList;
ms_pkRendererList = pkItem;
}
//----------------------------------------------------------------------------
Renderer::Renderer ()
:
m_kBackgroundColor(ColorRGB::WHITE)
{
m_iX = 0;
m_iY = 0;
m_iWidth = 0;
m_iHeight = 0;
m_iQuantity = 0;
m_pkCurPixelShader = NULL;
m_pkCurVertexShader = NULL;
// add renderer to global list of renderers
List* pkItem = new List;
pkItem->m_pkRenderer = this;
pkItem->m_pkNext = ms_pkRendererList;
ms_pkRendererList = pkItem;
}
//----------------------------------------------------------------------------
Renderer::~Renderer ()
{
m_spkCamera = NULL;
// remove renderer from global list of renderers
List* pkList = ms_pkRendererList;
List* pkPrev = NULL;
for (/**/; pkList; pkPrev = pkList, pkList = pkList->m_pkNext)
{
if ( pkList->m_pkRenderer == this )
{
if ( pkPrev )
{
// renderer not at front of list
pkPrev->m_pkNext = pkList->m_pkNext;
}
else
{
// render state at front of list
assert( pkList == ms_pkRendererList );
ms_pkRendererList = pkList->m_pkNext;
}
pkList->m_pkNext = NULL;
delete pkList;
break;
}
}
}
//----------------------------------------------------------------------------
void Renderer::Move (int iXPos, int iYPos)
{
if ( iXPos >= 0 && iYPos >= 0 )
{
m_iX = iXPos;
m_iY = iYPos;
}
}
//----------------------------------------------------------------------------
void Renderer::Resize (int iWidth, int iHeight)
{
if ( iWidth > 0 && iHeight > 0 )
{
m_iWidth = iWidth;
m_iHeight = iHeight;
m_iQuantity = m_iWidth*m_iHeight;
if ( m_spkCamera )
m_spkCamera->OnResize(iWidth,iHeight);
}
}
//----------------------------------------------------------------------------
void Renderer::Reshape (int iStartX, int iStartY, int iEndX, int iEndY)
{
int iWidth = iEndX - iStartX;
int iHeight = iEndY - iStartY;
if ( iWidth > 0 && iHeight > 0 )
{
m_iX = iStartX;
m_iY = iStartY;
m_iWidth = iWidth;
m_iHeight = iHeight;
m_iQuantity = m_iWidth*m_iHeight;
if ( m_spkCamera )
m_spkCamera->OnResize(iWidth,iHeight);
}
}
//----------------------------------------------------------------------------
void Renderer::Activate ()
{
}
//----------------------------------------------------------------------------
void Renderer::Suspend ()
{
}
//----------------------------------------------------------------------------
void Renderer::Resume ()
{
}
//----------------------------------------------------------------------------
CameraPtr Renderer::SetCamera (Camera* pkCamera)
{
CameraPtr spkSave = m_spkCamera;
if ( spkSave )
spkSave->m_bActive = false;
m_spkCamera = pkCamera;
if ( m_spkCamera )
m_spkCamera->m_bActive = true;
return spkSave;
}
//----------------------------------------------------------------------------
void Renderer::Draw (Node* pkScene)
{
if ( pkScene )
pkScene->OnDraw(*this);
}
//----------------------------------------------------------------------------
void Renderer::Draw (ScreenPolygon* pkPolygon)
{
if ( pkPolygon )
pkPolygon->OnDraw(*this);
}
//----------------------------------------------------------------------------
void Renderer::InitializeState ()
{
if ( m_bOverrideState )
return;
RenderState** apkState = RenderState::GetDefaultStates();
RenderState* pkState;
if ( !m_bOverrideAlphaState )
{
pkState = apkState[RenderState::RS_ALPHA];
SetAlphaState((AlphaState*)pkState);
}
pkState = apkState[RenderState::RS_CULL];
SetCullState((CullState*)pkState);
pkState = apkState[RenderState::RS_DITHER];
SetDitherState((DitherState*)pkState);
pkState = apkState[RenderState::RS_FOG];
SetFogState((FogState*)pkState);
pkState = apkState[RenderState::RS_LIGHT];
SetLightState((LightState*)pkState);
pkState = apkState[RenderState::RS_MATERIAL];
SetMaterialState((MaterialState*)pkState);
pkState = apkState[RenderState::RS_POLYGONOFFSET];
SetPolygonOffsetState((PolygonOffsetState*)pkState);
pkState = apkState[RenderState::RS_SHADE];
SetShadeState((ShadeState*)pkState);
if ( !m_bOverrideTextureState )
{
pkState = apkState[RenderState::RS_TEXTURE];
SetTextureState((TextureState*)pkState);
}
pkState = apkState[RenderState::RS_VERTEXCOLOR];
SetVertexColorState((VertexColorState*)pkState);
pkState = apkState[RenderState::RS_WIREFRAME];
SetWireframeState((WireframeState*)pkState);
pkState = apkState[RenderState::RS_ZBUFFER];
SetZBufferState((ZBufferState*)pkState);
}
//----------------------------------------------------------------------------
void Renderer::SetState (const RenderStatePtr aspkState[])
{
if ( m_bOverrideState )
return;
RenderState* pkState;
if ( !m_bOverrideAlphaState )
{
pkState = aspkState[RenderState::RS_ALPHA];
SetAlphaState((AlphaState*)pkState);
}
pkState = aspkState[RenderState::RS_DITHER];
SetDitherState((DitherState*)pkState);
pkState = aspkState[RenderState::RS_CULL];
SetCullState((CullState*)pkState);
pkState = aspkState[RenderState::RS_FOG];
SetFogState((FogState*)pkState);
pkState = aspkState[RenderState::RS_LIGHT];
SetLightState((LightState*)pkState);
pkState = aspkState[RenderState::RS_MATERIAL];
SetMaterialState((MaterialState*)pkState);
pkState = aspkState[RenderState::RS_POLYGONOFFSET];
SetPolygonOffsetState((PolygonOffsetState*)pkState);
pkState = aspkState[RenderState::RS_SHADE];
SetShadeState((ShadeState*)pkState);
if ( !m_bOverrideTextureState )
{
pkState = aspkState[RenderState::RS_TEXTURE];
SetTextureState((TextureState*)pkState);
}
pkState = aspkState[RenderState::RS_VERTEXCOLOR];
SetVertexColorState((VertexColorState*)pkState);
pkState = aspkState[RenderState::RS_WIREFRAME];
SetWireframeState((WireframeState*)pkState);
pkState = aspkState[RenderState::RS_ZBUFFER];
SetZBufferState((ZBufferState*)pkState);
}
//----------------------------------------------------------------------------
Object* Renderer::GetObjectByName (const char* acName)
{
Object* pkFound = Object::GetObjectByName(acName);
if ( pkFound )
return pkFound;
if ( m_spkCamera )
{
pkFound = m_spkCamera->GetObjectByName(acName);
if ( pkFound )
return pkFound;
}
return 0;
}
//----------------------------------------------------------------------------
void Renderer::GetAllObjectsByName (const char* acName,
std::vector<Object*>& rkObjects)
{
Object::GetAllObjectsByName(acName,rkObjects);
if ( m_spkCamera )
m_spkCamera->GetAllObjectsByName(acName,rkObjects);
}
//----------------------------------------------------------------------------
int Renderer::RequestTextureUnit (int iUnit)
{
if ( iUnit <= -1 )
{
// Tries to grab a texture unit for a RenderEffect, starting
// with the highest unit so it does not conflict with
// model textures.
iUnit = m_iMaxTextureUnits - 1;
if ( iUnit >= TextureState::MAX_TEXTURES )
{
// TO DO. The current MAX_TEXTURES is 4. Trap this block of code
// to see if we should increase the supported number.
iUnit = TextureState::MAX_TEXTURES - 1;
}
// TO DO. Render effects who are children will override parents, if
// necessary, when all texture units are in use by the render effect.
// However, if a render effect ends up requesting units that are used
// by models that it renders, the render effect will not show up.
// That behavior could be modified later by changing the "requested
// bit vector" to a "reserved bit vector" and changing the appropriate
// code in Wml<Renderer>TextureState.cpp.
while ( iUnit > -1 && (m_iTextureUnitRequested & (1 << iUnit)) )
{
// try a lower unit
iUnit--;
}
if ( iUnit > -1 )
{
// grab the unit
m_iTextureUnitRequested |= (1 << iUnit);
}
}
else
{
if ( iUnit >= TextureState::MAX_TEXTURES
|| (m_iTextureUnitRequested & (1 << iUnit)) )
{
// texture unit invalid or already in use
return -1;
}
// grab the unit
m_iTextureUnitRequested |= (1 << iUnit);
}
return iUnit;
}
//----------------------------------------------------------------------------
bool Renderer::TextureUnitRequested (int iUnit)
{
// Check if a texture unit is requested (or used) to avoid performance
// warning.
return (m_iTextureUnitRequested & (1 << iUnit)) != 0;
}
//----------------------------------------------------------------------------
void Renderer::ReleaseTextureUnit (int iUnit)
{
m_iTextureUnitRequested &= ~(1 << iUnit);
}
//----------------------------------------------------------------------------
void Renderer::OnDestroyTexture (Texture* pkTexture)
{
List* pkItem = ms_pkRendererList;
while ( pkItem )
{
// tell renderer to release the texture and associated resources
pkItem->m_pkRenderer->ReleaseTexture(pkTexture);
pkItem = pkItem->m_pkNext;
}
}
//----------------------------------------------------------------------------
void Renderer::OnDestroyShader (Shader* pkShader)
{
List* pkItem = ms_pkRendererList;
while ( pkItem )
{
// tell renderer to release the shader and associated resources
pkItem->m_pkRenderer->ReleaseShader(pkShader);
pkItem = pkItem->m_pkNext;
}
}
//----------------------------------------------------------------------------
void Renderer::ReleaseTextures (Spatial* pkScene)
{
TextureState* pkTS = WmlStaticCast(TextureState,
pkScene->GetRenderState(RenderState::RS_TEXTURE));
if ( pkTS )
{
for (int i = 0; i < pkTS->GetQuantity(); i++)
{
Texture* pkTexture = pkTS->Get(i);
if ( pkTexture )
ReleaseTexture(pkTexture);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -