📄 mgcgprenderer.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"
MgcImplementRTTI(MgcGPRenderer,MgcRenderer);
MgcImplementStream(MgcGPRenderer);
//---------------------------------------------------------------------------
MgcGPRenderer::MgcGPRenderer (int iWidth, int iHeight)
:
MgcRenderer(iWidth,iHeight)
{
m_fWidth = MgcReal(iWidth);
m_fHeight = MgcReal(iHeight);
m_fXScale = 0.5*(m_fWidth - 1.0);
m_fYScale = 0.5*(m_fHeight - 1.0);
// edge buffers for scan line rasterizing
int i;
m_aiXMin = new int[m_iHeight];
m_aiXMax = new int[m_iHeight];
m_aafLinAttrMin = new MgcReal*[m_iHeight];
m_aafLinAttrMax = new MgcReal*[m_iHeight];
m_aafPerAttrMin = new MgcReal*[m_iHeight];
m_aafPerAttrMax = new MgcReal*[m_iHeight];
for (i = 0; i < 3; i++)
{
m_aafLinAttr[i] = new MgcReal[m_iHeight];
m_aafPerAttr[i] = new MgcReal[m_iHeight];
}
for (i = 0; i < m_iHeight; i++)
{
m_aafLinAttrMin[i] = new MgcReal[MAX_ATTRIBUTES];
m_aafLinAttrMax[i] = new MgcReal[MAX_ATTRIBUTES];
m_aafPerAttrMin[i] = new MgcReal[MAX_ATTRIBUTES];
m_aafPerAttrMax[i] = new MgcReal[MAX_ATTRIBUTES];
}
}
//---------------------------------------------------------------------------
MgcGPRenderer::MgcGPRenderer ()
{
}
//---------------------------------------------------------------------------
MgcGPRenderer::~MgcGPRenderer ()
{
int i;
for (i = 0; i < 3; i++)
{
delete[] m_aafLinAttr[i];
delete[] m_aafPerAttr[i];
}
for (i = 0; i < m_iHeight; i++)
{
delete[] m_aafLinAttrMin[i];
delete[] m_aafLinAttrMax[i];
delete[] m_aafPerAttrMin[i];
delete[] m_aafPerAttrMax[i];
}
delete[] m_aiXMin;
delete[] m_aiXMax;
delete[] m_aafLinAttrMin;
delete[] m_aafLinAttrMax;
delete[] m_aafPerAttrMin;
delete[] m_aafPerAttrMax;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::ProjectVertices ()
{
unsigned int uiV, uiVMax = m_kMesh.GetVerticesUsed();
if ( ZBufferActive() )
{
// TO DO. Map depths to 16-bit, assert on integer values rather
// than float values. Remove clipping epsilon.
MgcReal fDepthCoeff = GetCamera()->GetFarDivideFarMinusNear();
for (uiV = 0; uiV < uiVMax; uiV++)
{
if ( m_kMesh.GetVertexVisible(uiV) )
{
MgcVector3& rkVertex = m_kMesh.Vertex(uiV);
MgcReal fInverseW = 1.0/rkVertex.z;
rkVertex.x = m_fXScale*(rkVertex.x*fInverseW + 1.0);
rkVertex.y = m_fYScale*(rkVertex.y*fInverseW + 1.0);
m_kMesh.Depth(uiV) = fDepthCoeff*(1.0 - fInverseW);
#ifdef _DEBUG
int iX = int(rkVertex.x);
int iY = int(rkVertex.y);
assert( 0 <= iX && iX < m_iWidth );
assert( 0 <= iY && iY < m_iHeight );
assert( m_kMesh.Depth(uiV) >= -0.0001
&& m_kMesh.Depth(uiV) <= 1.0001 );
#endif
}
}
}
else
{
for (uiV = 0; uiV < uiVMax; uiV++)
{
if ( m_kMesh.GetVertexVisible(uiV) )
{
MgcVector3& rkVertex = m_kMesh.Vertex(uiV);
MgcReal fInverseW = 1.0/rkVertex.z;
rkVertex.x = m_fXScale*(rkVertex.x*fInverseW + 1.0);
rkVertex.y = m_fYScale*(rkVertex.y*fInverseW + 1.0);
#if _DEBUG
int iX = int(rkVertex.x);
int iY = int(rkVertex.y);
assert( 0 <= iX && iX < m_iWidth );
assert( 0 <= iY && iY < m_iHeight );
#endif
}
}
}
}
//---------------------------------------------------------------------------
void MgcGPRenderer::Draw (const MgcGPTriMesh& rkTriMesh)
{
// copy trimesh to local memory
m_kMesh.Copy(rkTriMesh);
// determine status of vertex colors, lights, and materials
m_kMesh.GetLightingStatus(m_pkLightState,m_pkMaterialState,
m_pkVertexColorState,rkTriMesh.GetColors());
// transform camera to model space
const MgcVector3& rkWorldTranslate = rkTriMesh.WorldTranslate();
const MgcMatrix3& rkWorldRotate = rkTriMesh.WorldRotate();
MgcReal fWorldScale = rkTriMesh.WorldScale();
MgcVector3 kDiff = m_spkCamera->GetLocation() - rkWorldTranslate;
m_kMesh.m_kCameraModelLocation = (kDiff*rkWorldRotate)/fWorldScale;
// back face cull triangles (normals assumed to point outwards)
bool bAllTrianglesCulled = true;
for (unsigned int uiT = 0; uiT < rkTriMesh.GetTrianglesUsed(); uiT++)
{
const MgcPlane& rkFacetPlane = rkTriMesh.GetFacetPlane(uiT);
if ( rkFacetPlane.DistanceTo(m_kMesh.m_kCameraModelLocation) > 0.0 )
{
// triangle is front facing, tag front facing vertices and edges
bAllTrianglesCulled = false;
m_kMesh.m_abTriangleVisible[uiT] = true;
MgcGPTriMesh::TriangleRecord& rkTri = m_kMesh.Triangle(uiT);
for (int i = 0; i < 3; i++)
{
m_kMesh.m_abVertexVisible[rkTri.Vertex(i)] = true;
m_kMesh.m_abEdgeVisible[rkTri.Edge(i)] = true;
}
}
}
if ( bAllTrianglesCulled )
return;
// composition of model-to-world and world-to-view
MgcMatrix3 kMVMat;
MgcVector3 kMVTrn;
GetCamera()->ComputeModelToViewTransform(rkWorldRotate,rkWorldTranslate,
fWorldScale,kMVMat,kMVTrn);
// save model space vertices for deferred lighting calculations
if ( m_kMesh.m_bHasModelVertices )
{
memcpy(m_kMesh.GetModelVertices(),m_kMesh.GetVertices(),
m_kMesh.m_uiVerticesUsed*sizeof(MgcVector3));
}
// transform vertices
unsigned int uiOldVerticesUsed = m_kMesh.m_uiVerticesUsed;
unsigned int uiV;
for (uiV = 0; uiV < uiOldVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3 kVertex = m_kMesh.Vertex(uiV);
m_kMesh.Vertex(uiV) = kMVMat*kVertex + kMVTrn;
}
}
// clip triangles against view frustum.
if ( Clip() )
{
// trimesh is completely culled
return;
}
// compute attributes for lighting and for clip vertices
m_kMesh.ComputeVertexAttributes(uiOldVerticesUsed);
ProjectVertices();
if ( m_pkWireframeState->Enabled() )
RasterizeEdges();
else
RasterizeTriangles();
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetAlphaState (MgcAlphaState* pkState)
{
m_pkAlphaState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetDitherState (MgcDitherState* pkState)
{
m_pkDitherState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetFogState (MgcFogState* pkState)
{
m_pkFogState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetLightState (MgcLightState* pkState)
{
m_pkLightState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetMaterialState (MgcMaterialState* pkState)
{
m_pkMaterialState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetShadeState (MgcShadeState* pkState)
{
m_pkShadeState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetTextureState (MgcTextureState* pkState)
{
m_pkTextureState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetVertexColorState (MgcVertexColorState* pkState)
{
m_pkVertexColorState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetWireframeState (MgcWireframeState* pkState)
{
m_pkWireframeState = pkState;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::SetZBufferState (MgcZBufferState* pkState)
{
m_pkZBufferState = pkState;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcGPRenderer::Factory (MgcStream& rkStream)
{
// MgcGPRenderer is abstract, Factory never called.
return 0;
}
//---------------------------------------------------------------------------
void MgcGPRenderer::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcRenderer::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcGPRenderer::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcRenderer::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::Register (MgcStream& rkStream)
{
return MgcRenderer::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcGPRenderer::Save (MgcStream& rkStream)
{
MgcRenderer::Save(rkStream);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -