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

📄 mgcgprenderermesh.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcGPRendererMesh.h"
#include "MgcLightState.h"
#include "MgcMaterialState.h"
#include "MgcPointLight.h"

MgcImplementRTTI(MgcGPRendererMesh,MgcGPTriMesh);
MgcImplementStream(MgcGPRendererMesh);

MgcGPRendererMesh::LightFunction MgcGPRendererMesh::ms_aaoLighter
    [MgcVertexColorState::SM_QUANTITY]
    [MgcVertexColorState::LM_QUANTITY] =
{
    MgcGPRendererMesh::SourceIgnoreLightingEmissive,
    MgcGPRendererMesh::SourceIgnoreLightingDiffuse,
    MgcGPRendererMesh::SourceEmissiveLightingEmissive,
    MgcGPRendererMesh::SourceEmissiveLightingDiffuse,
    MgcGPRendererMesh::SourceDiffuseLightingEmissive,
    MgcGPRendererMesh::SourceDiffuseLightingDiffuse
};

//----------------------------------------------------------------------------
MgcGPRendererMesh::MgcGPRendererMesh ()
{
}
//----------------------------------------------------------------------------
MgcGPRendererMesh::~MgcGPRendererMesh ()
{
}
//----------------------------------------------------------------------------
void MgcGPRendererMesh::GrowVertices (unsigned int uiNewQuantity, bool bCopy)
{
    m_akVertex.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_akNormal.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_akColor.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_akTexture.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);

    m_akModelVertex.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_akDiffuse.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_akSpecular.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);

    m_abVertexVisible.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_abVertexNeedsLighting.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_afDistance.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_auiOldEdge.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_auiNewEdge.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);
    m_afDepth.Resize(m_uiVertexQuantity,uiNewQuantity,bCopy);

    m_uiVertexQuantity = uiNewQuantity;
}
//----------------------------------------------------------------------------
void MgcGPRendererMesh::GrowEdges (unsigned int uiNewQuantity, bool bCopy)
{
    m_akEdge.Resize(m_uiEdgeQuantity,uiNewQuantity,bCopy);
    m_abEdgeVisible.Resize(m_uiEdgeQuantity,uiNewQuantity,bCopy);
    m_auiClipVertex.Resize(m_uiEdgeQuantity,uiNewQuantity,bCopy);
    m_afClipParam.Resize(m_uiEdgeQuantity,uiNewQuantity,bCopy);

    m_uiEdgeQuantity = uiNewQuantity;
}
//----------------------------------------------------------------------------
void MgcGPRendererMesh::GrowTriangles (unsigned int uiNewQuantity, bool bCopy)
{
    m_akTriangle.Resize(m_uiTriangleQuantity,uiNewQuantity,bCopy);
    m_akFacetPlane.Resize(m_uiTriangleQuantity,uiNewQuantity,bCopy);
    m_abTriangleVisible.Resize(m_uiTriangleQuantity,uiNewQuantity,bCopy);

    m_uiTriangleQuantity = uiNewQuantity;
}
//----------------------------------------------------------------------------
void MgcGPRendererMesh::Copy (const MgcGPTriMesh& rkMesh)
{
    // increase size of renderer mesh to accommodate input mesh
    m_uiVerticesUsed = rkMesh.GetVerticesUsed();
    if ( m_uiVerticesUsed > m_uiVertexQuantity )
        GrowVertices(m_uiVerticesUsed,false);

    m_uiEdgesUsed = rkMesh.GetEdgesUsed();
    if ( m_uiEdgesUsed > m_uiEdgeQuantity )
        GrowEdges(m_uiEdgesUsed,false);

    m_uiTrianglesUsed = rkMesh.GetTrianglesUsed();
    if ( m_uiTrianglesUsed > m_uiTriangleQuantity )
        GrowTriangles(m_uiTrianglesUsed,false);

    // copy vertices and attributes
    unsigned int uiQuantity = m_uiVerticesUsed*sizeof(MgcVector3);
    memcpy(GetVertices(),rkMesh.GetVertices(),uiQuantity);

    m_bHasModelVertices = false;
    m_bHasLights = false;

    m_bHasNormals = rkMesh.HasNormals();
    if ( m_bHasNormals )
        memcpy(GetNormals(),rkMesh.GetNormals(),uiQuantity);

    m_bHasColors = rkMesh.HasColors();
    if ( m_bHasColors )
    {
        uiQuantity = m_uiVerticesUsed*sizeof(MgcColor);
        memcpy(GetColors(),rkMesh.GetColors(),uiQuantity);
    }

    m_bHasTextures = rkMesh.HasTextures();
    if ( m_bHasTextures )
    {
        uiQuantity = m_uiVerticesUsed*sizeof(MgcVector2);
        memcpy(GetTextures(),rkMesh.GetTextures(),uiQuantity);
    }

    unsigned int uiCopySize = m_uiVerticesUsed*sizeof(bool);
    memset(m_abVertexVisible.GetStorage(),0,uiCopySize);
    memset(m_abVertexNeedsLighting.GetStorage(),0,uiCopySize);
    uiCopySize = m_uiVerticesUsed*sizeof(unsigned int);
    memset(m_auiOldEdge.GetStorage(),0xFF,uiCopySize);
    memset(m_auiNewEdge.GetStorage(),0xFF,uiCopySize);

    // copy edges
    for (unsigned int uiE = 0; uiE < m_uiEdgesUsed; uiE++)
        m_akEdge[uiE] = rkMesh.Edge(uiE);

    uiCopySize = m_uiEdgesUsed*sizeof(bool);
    memset(m_abEdgeVisible.GetStorage(),0,uiCopySize);

    uiCopySize = m_uiEdgesUsed*sizeof(unsigned int);
    memset(m_auiClipVertex.GetStorage(),0xFF,uiCopySize);

    // copy triangles (not facet planes, renderer uses only original ones)
    for (unsigned int uiT = 0; uiT < m_uiTrianglesUsed; uiT++)
        m_akTriangle[uiT] = rkMesh.Triangle(uiT);

    uiCopySize = m_uiTrianglesUsed*sizeof(bool);
    memset(m_abTriangleVisible.GetStorage(),0,uiCopySize);

    // NOTE:  The model bound is not copied since the renderer does not
    // use it.
}
//----------------------------------------------------------------------------
unsigned int MgcGPRendererMesh::AddVertex ()
{
    unsigned int uiV = m_uiVerticesUsed++;
    if ( uiV >= m_uiVertexQuantity )
        GrowVertices(uiV+ms_uiVertexGrowBy,true);

    m_abVertexVisible[uiV] = true;
    m_abVertexNeedsLighting[uiV] = true;
    m_auiOldEdge[uiV] = INVALID_INDEX;
    m_auiNewEdge[uiV] = INVALID_INDEX;
    return uiV;
}
//----------------------------------------------------------------------------
unsigned int MgcGPRendererMesh::AddEdge ()
{
    unsigned int uiE = m_uiEdgesUsed++;
    if ( uiE >= m_uiEdgeQuantity )
        GrowEdges(uiE+ms_uiEdgeGrowBy,true);

    m_abEdgeVisible[uiE] = true;
    m_auiClipVertex[uiE] = INVALID_INDEX;
    return uiE;
}
//----------------------------------------------------------------------------
unsigned int MgcGPRendererMesh::AddTriangle ()
{
    unsigned int uiT = m_uiTrianglesUsed++;
    if ( uiT >= m_uiTriangleQuantity )
        GrowTriangles(uiT+ms_uiTriangleGrowBy,true);

    m_abTriangleVisible[uiT] = true;
    return uiT;
}
//----------------------------------------------------------------------------
void MgcGPRendererMesh::GetLightingStatus (MgcLightState* pkLState,
    MgcMaterialState* pkMState, MgcVertexColorState* pkVState,
    MgcColor* akVertexColors)
{
    // remember the lighting state for use in deferred lighting routines
    m_pkLState = pkLState;
    m_pkMState = pkMState;
    m_pkVState = pkVState;

    // Status of active lights.  If point or spot lights are active, the
    // model space vertices need to be saved so that lighting calculations
    // using them can be deferred until after clipping.
    unsigned int uiLightQuantity = pkLState->GetQuantity();
    m_bHasLights = false;
    m_bHasModelVertices = false;
    if ( uiLightQuantity > 0 )
    {
        for (unsigned int uiI = 0; uiI < uiLightQuantity; uiI++)
        {
            MgcLight* pkLight = pkLState->Get(uiI);
            assert( pkLight );
            if ( pkLight->On() )
                m_bHasLights = true;

            if ( MgcIsDerivedFromClass(MgcPointLight,pkLight) )
            {
                m_bHasModelVertices = true;
                break;
            }
        }
    }

    // Status of emissive lighting.  Lighting is enabled if vertex colors
    // exist while in 'emissive source' mode, or if a non-black emissive
    // material color exists in all other source modes.
    if ( pkVState->Source() == MgcVertexColorState::SM_EMISSIVE )
    {
        // lighting enabled when vertex colors exist, 'emissive source' mode
        m_bHasLights = (akVertexColors != 0);
    }
    else if ( pkMState->Emissive() != MgcColor::BLACK )
    {
        // lighting enabled when emissive material color exists, other modes
        m_bHasLights = true;
    }

    m_bHasColors = (akVertexColors || m_bHasLights);
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcGPRendererMesh::Factory (MgcStream& rkStream)
{
    MgcGPRendererMesh* pkObject = new MgcGPRendererMesh;
    MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
    pkObject->Load(rkStream,pkLink);
    return pkObject;
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcGPTriMesh::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcGPTriMesh::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcGPRendererMesh::Register (MgcStream& rkStream)
{
    return MgcGPTriMesh::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::Save (MgcStream& rkStream)
{
    MgcGPTriMesh::Save(rkStream);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -