⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmlrenderer.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -