📄 mgcgpedgebuffers.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 MgcGPRenderer::ComputeEdgeBuffer (int iX0, int iY0, MgcReal* afLinAttr0,
MgcReal* afPerAttr0, int iX1, int iY1, MgcReal* afLinAttr1,
MgcReal* afPerAttr1, int* aiXBuffer, MgcReal** aafLinAttrBuffer,
MgcReal** aafPerAttrBuffer)
{
// assign attributes to end points of edge buffer
aiXBuffer[iY0] = iX0;
aiXBuffer[iY1] = iX1;
unsigned int i;
for (i = 0; i < m_uiNumLinAttr; i++)
{
aafLinAttrBuffer[iY0][i] = afLinAttr0[i];
aafLinAttrBuffer[iY1][i] = afLinAttr1[i];
}
for (i = 0; i < m_uiNumPerAttr; i++)
{
aafPerAttrBuffer[iY0][i] = afPerAttr0[i];
aafPerAttrBuffer[iY1][i] = afPerAttr1[i];
}
int iDy = iY1 - iY0; // assert: iDy > 0 always, so don't need test
if ( iDy > 1 )
{
int iY, iYMin = iY0+1, iYMax = iY1-1;
MgcReal fInv, fCoeffC, fCoeffD;
// compute perspective-correct attributes for edge buffers
if ( m_uiNumPerAttr > 0 )
{
unsigned int uiNumPerAttrM1 = m_uiNumPerAttr-1;
MgcReal fW0 = afPerAttr0[uiNumPerAttrM1];
MgcReal fW1 = afPerAttr1[uiNumPerAttrM1];
fCoeffC = fW0 - fW1;
fCoeffD = fW1*iY1 - fW0*iY0;
MgcReal afCoeffA[MAX_ATTRIBUTES];
MgcReal afCoeffB[MAX_ATTRIBUTES];
for (i = 0; i < m_uiNumPerAttr; i++)
{
MgcReal fW0Attr1 = fW0*afPerAttr1[i];
MgcReal fW1Attr0 = fW1*afPerAttr0[i];
afCoeffA[i] = fW0Attr1 - fW1Attr0;
afCoeffB[i] = fW1Attr0*iY1 - fW0Attr1*iY0;
}
for (iY = iYMin; iY <= iYMax; iY++)
{
fInv = 1.0/(fCoeffC*iY+fCoeffD);
for (i = 0; i < m_uiNumPerAttr; i++)
{
aafPerAttrBuffer[iY][i] =
(afCoeffA[i]*iY+afCoeffB[i])*fInv;
}
}
}
// compute linear attributes for edge buffers
fInv = 1.0/iDy;
if ( m_uiNumLinAttr > 0 )
{
MgcReal afDAttr[MAX_ATTRIBUTES];
MgcReal afDet[MAX_ATTRIBUTES];
for (i = 0; i < m_uiNumLinAttr; i++)
{
afDAttr[i] = afLinAttr1[i] - afLinAttr0[i];
afDet[i] = afLinAttr0[i]*iY1 - afLinAttr1[i]*iY0;
}
for (iY = iYMin; iY <= iYMax; iY++)
{
for (i = 0; i < m_uiNumLinAttr; i++)
aafLinAttrBuffer[iY][i] = (afDet[i]+afDAttr[i]*iY)*fInv;
}
}
// compute x-values for edge buffers
int iDx = iX1 - iX0;
int iDet = iX0*iY1 - iX1*iY0;
fCoeffC = iDet*fInv;
fCoeffD = iDx*fInv;
for (iY = iYMin; iY <= iYMax; iY++)
aiXBuffer[iY] = fCoeffC + iY*fCoeffD;
}
}
//---------------------------------------------------------------------------
#define ThreeBuffers(i0,i1,i2,buf0,buf1) \
m_iYMin = m_aiY[i0]; \
m_iYMax = m_aiY[i2]; \
ComputeEdgeBuffer( \
m_aiX[i0],m_aiY[i0],m_aafLinAttr[i0], m_aafPerAttr[i0], \
m_aiX[i1],m_aiY[i1],m_aafLinAttr[i1], m_aafPerAttr[i1], \
m_aiX##buf0,m_aafLinAttr##buf0,m_aafPerAttr##buf0); \
ComputeEdgeBuffer( \
m_aiX[i1],m_aiY[i1],m_aafLinAttr[i1], m_aafPerAttr[i1], \
m_aiX[i2],m_aiY[i2],m_aafLinAttr[i2], m_aafPerAttr[i2],\
m_aiX##buf0,m_aafLinAttr##buf0,m_aafPerAttr##buf0); \
ComputeEdgeBuffer( \
m_aiX[i0],m_aiY[i0],m_aafLinAttr[i0], m_aafPerAttr[i0], \
m_aiX[i2],m_aiY[i2],m_aafLinAttr[i2], m_aafPerAttr[i2], \
m_aiX##buf1,m_aafLinAttr##buf1,m_aafPerAttr##buf1);
//---------------------------------------------------------------------------
#define TwoBuffers(i0,i1,j0,j1) \
m_iYMin = m_aiY[i0]; \
m_iYMax = m_aiY[i1]; \
ComputeEdgeBuffer( \
m_aiX[i0],m_aiY[i0],m_aafLinAttr[i0], m_aafPerAttr[i0], \
m_aiX[i1],m_aiY[i1],m_aafLinAttr[i1], m_aafPerAttr[i1], \
m_aiXMin,m_aafLinAttrMin,m_aafPerAttrMin); \
ComputeEdgeBuffer( \
m_aiX[j0],m_aiY[j0],m_aafLinAttr[j0], m_aafPerAttr[j0], \
m_aiX[j1],m_aiY[j1],m_aafLinAttr[j1], m_aafPerAttr[j1], \
m_aiXMax,m_aafLinAttrMax,m_aafPerAttrMax);
//---------------------------------------------------------------------------
bool MgcGPRenderer::ComputeEdgeBuffers ()
{
int iDx0, iDy0, iDx1, iDy1, iDet;
if ( m_aiY[0] < m_aiY[1] )
{
if ( m_aiY[0] < m_aiY[2] )
{
if ( m_aiY[1] < m_aiY[2] )
{
// y0 < y1 < y2
iDx0 = m_aiX[1] - m_aiX[0];
iDy0 = m_aiY[1] - m_aiY[0];
iDx1 = m_aiX[2] - m_aiX[0];
iDy1 = m_aiY[2] - m_aiY[0];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(0,1,2,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(0,1,2,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else if ( m_aiY[1] > m_aiY[2] )
{
// y0 < y2 < y1
iDx0 = m_aiX[2] - m_aiX[0];
iDy0 = m_aiY[2] - m_aiY[0];
iDx1 = m_aiX[1] - m_aiX[0];
iDy1 = m_aiY[1] - m_aiY[0];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(0,2,1,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(0,2,1,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else
{
// y0 < y1 = y2
if ( m_aiX[1] < m_aiX[2] )
{
TwoBuffers(0,1,0,2);
return true;
}
if ( m_aiX[1] > m_aiX[2] )
{
TwoBuffers(0,2,0,1);
return true;
}
// degenerate triangle
return false;
}
}
else if ( m_aiY[0] > m_aiY[2] )
{
// y2 < y0 < y1
iDx0 = m_aiX[0] - m_aiX[2];
iDy0 = m_aiY[0] - m_aiY[2];
iDx1 = m_aiX[1] - m_aiX[2];
iDy1 = m_aiY[1] - m_aiY[2];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(2,0,1,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(2,0,1,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else
{
// y2 = y0 < y1
if ( m_aiX[0] < m_aiX[2] )
{
TwoBuffers(0,1,2,1);
return true;
}
if ( m_aiX[0] > m_aiX[2] )
{
TwoBuffers(2,1,0,1);
return true;
}
// degenerate triangle
return false;
}
}
else if ( m_aiY[0] > m_aiY[1] )
{
if ( m_aiY[0] > m_aiY[2] )
{
if ( m_aiY[1] > m_aiY[2] )
{
// y2 < y1 < y0
iDx0 = m_aiX[1] - m_aiX[2];
iDy0 = m_aiY[1] - m_aiY[2];
iDx1 = m_aiX[0] - m_aiX[2];
iDy1 = m_aiY[0] - m_aiY[2];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(2,1,0,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(2,1,0,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else if ( m_aiY[1] < m_aiY[2] )
{
// y1 < y2 < y0
iDx0 = m_aiX[2] - m_aiX[1];
iDy0 = m_aiY[2] - m_aiY[1];
iDx1 = m_aiX[0] - m_aiX[1];
iDy1 = m_aiY[0] - m_aiY[1];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(1,2,0,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(1,2,0,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else
{
// y1 = y2 < y0
if ( m_aiX[1] < m_aiX[2] )
{
TwoBuffers(1,0,2,0);
return true;
}
if ( m_aiX[1] > m_aiX[2] )
{
TwoBuffers(2,0,1,0);
return true;
}
// degenerate triangle
return false;
}
}
else if ( m_aiY[0] < m_aiY[2] )
{
// y1 < y0 < y2
iDx0 = m_aiX[0] - m_aiX[1];
iDy0 = m_aiY[0] - m_aiY[1];
iDx1 = m_aiX[2] - m_aiX[1];
iDy1 = m_aiY[2] - m_aiY[1];
iDet = iDx0*iDy1 - iDx1*iDy0;
if ( iDet > 0 )
{
// midpoint to right
ThreeBuffers(1,0,2,Max,Min);
return true;
}
if ( iDet < 0 )
{
// midpoint to left
ThreeBuffers(1,0,2,Min,Max);
return true;
}
// degenerate triangle
return false;
}
else
{
// y1 < y0 = y2
if ( m_aiX[0] < m_aiX[2] )
{
TwoBuffers(1,0,1,2);
return true;
}
if ( m_aiX[0] > m_aiX[2] )
{
TwoBuffers(1,2,1,0);
return true;
}
// degenerate triangle
return false;
}
}
else
{
if ( m_aiY[2] < m_aiY[0] )
{
// y2 < y1 = y0
if ( m_aiX[0] < m_aiX[1] )
{
TwoBuffers(2,0,2,1);
return true;
}
if ( m_aiX[0] > m_aiX[1] )
{
TwoBuffers(2,1,2,0);
return true;
}
// degenerate triangle
return false;
}
else if ( m_aiY[2] > m_aiY[0] )
{
// y1 = y0 < y2
if ( m_aiX[0] < m_aiX[1] )
{
TwoBuffers(0,2,1,2);
return true;
}
if ( m_aiX[0] > m_aiX[1] )
{
TwoBuffers(1,2,0,2);
return true;
}
// degenerate triangle
return false;
}
else
{
// y0 = y1 = y2
// degenerate triangle
return false;
}
}
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -