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

📄 mgcgprendererinterp.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 "MgcGPRenderer.h"

//---------------------------------------------------------------------------
void MgcGPRendererMesh::ComputeDiffuseSpecular (unsigned int uiQ,
    MgcColor& rkAmbient, bool& rbHasSpecular)
{
    memset(m_akDiffuse.GetStorage(),0,uiQ*sizeof(MgcColor));
    rbHasSpecular = false;

    rkAmbient = MgcColor::BLACK;
    for (unsigned int uiI = 0; uiI < m_pkLState->GetQuantity(); uiI++)
    {
        MgcLight* pkLight = m_pkLState->Get(uiI);
        if ( pkLight->On() )
        {
            rkAmbient += pkLight->Intensity()*pkLight->Ambient();

            pkLight->ComputeDiffuse(m_kWorldRotate,m_kWorldTranslate,
                m_fWorldScale,m_akModelVertex.GetStorage(),
                m_akNormal.GetStorage(),uiQ,
                m_abVertexNeedsLighting.GetStorage(),
                m_akDiffuse.GetStorage());

            bool bLightHasSpecular = pkLight->Specular() != MgcColor::BLACK;
            if ( !rbHasSpecular && bLightHasSpecular )
            {
                // set colors to black on first occurrence of specular light
                rbHasSpecular = true;
                memset(m_akSpecular.GetStorage(),0,uiQ*sizeof(MgcColor));
            }

            if ( bLightHasSpecular )
            {
                pkLight->ComputeSpecular(m_kWorldRotate,m_kWorldTranslate,
                    m_fWorldScale,m_akModelVertex.GetStorage(),
                    m_akNormal.GetStorage(),uiQ,
                    m_abVertexNeedsLighting.GetStorage(),
                    m_kCameraModelLocation,m_akSpecular.GetStorage());
            }
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceIgnoreLightingEmissive (unsigned int uiQ)
{
    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
    {
        if ( m_abVertexNeedsLighting[uiV] )
        {
            m_akColor[uiV] = m_pkMState->Emissive();
            m_abVertexNeedsLighting[uiV] = false;
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceIgnoreLightingDiffuse (unsigned int uiQ)
{
    // TO DO: Handle attenuation.

    MgcColor kAmbient;
    bool bHasSpecular;
    ComputeDiffuseSpecular(uiQ,kAmbient,bHasSpecular);

    kAmbient = m_pkMState->Emissive() + kAmbient*m_pkMState->Ambient();
    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
    {
        if ( m_abVertexNeedsLighting[uiV] )
        {
            MgcColor kDiffuse = m_pkMState->Diffuse()*m_akDiffuse[uiV];
            m_akColor[uiV] = kAmbient + kDiffuse;
            if ( bHasSpecular )
            {
                MgcColor kSpecular = m_pkMState->Specular()*m_akSpecular[uiV];
                m_akColor[uiV] += kSpecular;
            }
            m_akColor[uiV].Clamp();
            m_abVertexNeedsLighting[uiV] = false;
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceEmissiveLightingEmissive (unsigned int uiQ)
{
    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
        m_abVertexNeedsLighting[uiV] = false;
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceEmissiveLightingDiffuse (unsigned int uiQ)
{
    // TO DO: Handle attenuation.

    MgcColor kAmbient;
    bool bHasSpecular;
    ComputeDiffuseSpecular(uiQ,kAmbient,bHasSpecular);

    kAmbient = kAmbient*m_pkMState->Ambient();
    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
    {
        if ( m_abVertexNeedsLighting[uiV] )
        {
            MgcColor kDiffuse = m_pkMState->Diffuse()*m_akDiffuse[uiV];
            m_akColor[uiV] = kAmbient + kDiffuse;
            if ( bHasSpecular )
            {
                MgcColor kSpecular = m_pkMState->Specular()*m_akSpecular[uiV];
                m_akColor[uiV] += kSpecular;
            }
            m_akColor[uiV].Clamp();
            m_abVertexNeedsLighting[uiV] = false;
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceDiffuseLightingEmissive (unsigned int uiQ)
{
    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
    {
        if ( m_abVertexNeedsLighting[uiV] )
        {
            m_akColor[uiV] = m_pkMState->Emissive();
            m_abVertexNeedsLighting[uiV] = false;
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::SourceDiffuseLightingDiffuse (unsigned int uiQ)
{
    // TO DO: Handle attenuation.

    MgcColor kAmbient;
    bool bHasSpecular;
    ComputeDiffuseSpecular(uiQ,kAmbient,bHasSpecular);

    for (unsigned int uiV = 0; uiV < uiQ; uiV++)
    {
        if ( m_abVertexNeedsLighting[uiV] )
        {
            m_akColor[uiV] *= kAmbient + m_akDiffuse[uiV];
            m_akColor[uiV] += m_pkMState->Emissive();
            if ( bHasSpecular )
            {
                MgcColor kSpecular = m_pkMState->Specular()*m_akSpecular[uiV];
                m_akColor[uiV] += kSpecular;
            }
            m_akColor[uiV].Clamp();
            m_abVertexNeedsLighting[uiV] = false;
        }
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::Interpolate (unsigned int uiV0, unsigned int uiV1,
    MgcReal fParam, unsigned int uiClipV)
{
    if ( m_bHasModelVertices )
    {
        MgcVector3& rkV0 = m_akModelVertex[uiV0];
        MgcVector3& rkV1 = m_akModelVertex[uiV1];
        m_akModelVertex[uiClipV] = rkV0 + fParam*(rkV1 - rkV0);
    }

    if ( m_bHasColors )
    {
        MgcColor& rkC0 = m_akColor[uiV0];
        MgcColor& rkC1 = m_akColor[uiV1];
        m_akColor[uiClipV] = rkC0 + fParam*(rkC1 - rkC0);
    }

    if ( m_bHasTextures )
    {
        MgcVector2& rkT0 = m_akTexture[uiV0];
        MgcVector2& rkT1 = m_akTexture[uiV1];
        m_akTexture[uiClipV] = rkT0 + fParam*(rkT1 - rkT0);
    }
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::InterpolateVertexAttributes (unsigned int uiV)
{
    // old edge on which clipped vertex lives
    unsigned int uiE = m_auiOldEdge[uiV];
    EdgeRecord& rkEdge = m_akEdge[uiE];

    // end points of edge
    unsigned int uiV0 = rkEdge.Vertex(0), uiV1 = rkEdge.Vertex(1);

    // compute vertex attributes if not yet known
    if ( m_abVertexNeedsLighting[uiV0] )
        InterpolateVertexAttributes(uiV0);
    if ( m_abVertexNeedsLighting[uiV1] )
        InterpolateVertexAttributes(uiV1);

    Interpolate(uiV0,uiV1,m_afClipParam[uiE],uiV);

    m_abVertexNeedsLighting[uiV] = false;
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::MarkVertexForLighting (
    unsigned int uiOldVerticesUsed, unsigned int uiV)
{
    // old edge on which clip vertex lives
    EdgeRecord& rkEdge = m_akEdge[m_auiOldEdge[uiV]];

    // process an edge end point
    uiV = rkEdge.Vertex(0);
    if ( uiV < uiOldVerticesUsed )
        m_abVertexNeedsLighting[uiV] = true;
    else
        MarkVertexForLighting(uiOldVerticesUsed,uiV);

    // process other edge end point
    uiV = rkEdge.Vertex(1);
    if ( uiV < uiOldVerticesUsed )
        m_abVertexNeedsLighting[uiV] = true;
    else
        MarkVertexForLighting(uiOldVerticesUsed,uiV);
}
//---------------------------------------------------------------------------
void MgcGPRendererMesh::ComputeVertexAttributes (
    unsigned int uiOldVerticesUsed)
{
    // visible original vertices need to be lit
    unsigned int uiSize = uiOldVerticesUsed*sizeof(bool);
    memcpy(m_abVertexNeedsLighting.GetStorage(),
        m_abVertexVisible.GetStorage(),uiSize);

    // traverse tree of clip vertices and mark leaf vertices for lighting
    unsigned int uiV;
    for (uiV = uiOldVerticesUsed; uiV < m_uiVerticesUsed; uiV++)
    {
        if ( m_abVertexVisible[uiV] )
            MarkVertexForLighting(uiOldVerticesUsed,uiV);
    }

    // light the visible original vertices
    if ( m_bHasLights )
    {
        LightFunction oLighter =
            ms_aaoLighter[m_pkVState->Source()][m_pkVState->Lighting()];
        (this->*oLighter)(uiOldVerticesUsed);
    }
    else
    {
        for (uiV = 0; uiV < uiOldVerticesUsed; uiV++)
            m_abVertexNeedsLighting[uiV] = false;
    }

    // traverse tree of clip vertices and interpolate
    for (uiV = uiOldVerticesUsed; uiV < m_uiVerticesUsed; uiV++)
    {
        if ( m_abVertexVisible[uiV] && m_abVertexNeedsLighting[uiV] )
            InterpolateVertexAttributes(uiV);
    }
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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