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

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