📄 mgcgprendererinterp.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 + -