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

📄 wmlapplication2.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlApplication2.h"

//----------------------------------------------------------------------------
Application2::Application2 (char* acWindowTitle, int iXPos, int iYPos,
    int iWidth, int iHeight, const ColorRGB& rkBackgroundColor, bool bUseCLI)
    :
    Application(
        acWindowTitle,
        iXPos,
        iYPos,
        iWidth - (iWidth % 4),  // rows required to be multiple of 4 bytes 
        iHeight,
        rkBackgroundColor,
        bUseCLI)
{
    m_iScrWidth = 0;
    m_iScrHeight = 0;
    m_akScreen = NULL;
    m_bClampToWindow = true;
    m_akFlipScreen = NULL;
}
//----------------------------------------------------------------------------
bool Application2::OnInitialize ()
{
    if ( !Application::OnInitialize() )
        return false;

    // the RGB screen pixels
    m_iScrWidth = GetWidth();
    m_iScrHeight = GetHeight();
    m_akScreen = new Color[m_iScrWidth*m_iScrHeight];
    ClearScreen();
    return true;
}
//----------------------------------------------------------------------------
void Application2::OnTerminate ()
{
    delete[] m_akScreen;
    delete[] m_akFlipScreen;
    Application::OnTerminate();
}
//----------------------------------------------------------------------------
void Application2::OnDisplay ()
{
    ms_spkRenderer->ClearBuffers();
    if ( ms_spkRenderer->BeginScene() )
    {
        if ( !m_akFlipScreen )
        {
            ms_spkRenderer->Draw((const unsigned char*)m_akScreen);
        }
        else
        {
            // flip the screen
            Color* akSPtr = m_akScreen;
            Color* akFPtr = m_akFlipScreen + m_iScrWidth*(m_iScrHeight-1);
            int iQuantity = m_iScrWidth*sizeof(Color);
            for (int i = 0; i < m_iScrHeight; i++)
            {
                memcpy(akFPtr,akSPtr,iQuantity);
                akSPtr += m_iScrWidth;
                akFPtr -= m_iScrWidth;
            }

            ms_spkRenderer->Draw((const unsigned char*)m_akFlipScreen);
        }

        // Screen overlays should use ms_spkRenderer and not access the
        // m_akScreen array directly.
        ScreenOverlay();

        ms_spkRenderer->EndScene();
    }
    ms_spkRenderer->DisplayBackBuffer();
}
//----------------------------------------------------------------------------
void Application2::OnReshape (int iWidth, int iHeight)
{
    iWidth = iWidth - (iWidth % 4);
    Application::OnReshape(iWidth,iHeight);
    if ( iWidth*iHeight <= 0 )
        return;

    if ( iWidth != m_iScrWidth || iHeight != m_iScrHeight )
    {
        delete[] m_akScreen;
        m_iScrWidth = iWidth;
        m_iScrHeight = iHeight;
        m_akScreen = new Color[m_iScrWidth*m_iScrHeight];
        ClearScreen();

        if ( m_akFlipScreen )
        {
            delete[] m_akFlipScreen;
            m_akFlipScreen = new Color[m_iScrWidth*m_iScrHeight];
        }
    }
}
//----------------------------------------------------------------------------
void Application2::ScreenOverlay ()
{
    // stub for derived classes
}
//----------------------------------------------------------------------------
void Application2::ClearScreen ()
{
    for (int i = 0; i < ms_iWidth*ms_iHeight; i++)
    {
        // This can lead to slow float-to-int conversions.
        //m_akScreen[i].r = (unsigned char)(255.0f*ms_kBackgroundColor.r);
        //m_akScreen[i].b = (unsigned char)(255.0f*ms_kBackgroundColor.g);
        //m_akScreen[i].b = (unsigned char)(255.0f*ms_kBackgroundColor.b);

        // fast float-to-int conversions
        int iValue;
        WmlScaledFloatToInt(ms_kBackgroundColor.r,8,iValue);
        m_akScreen[i].r = (unsigned char)iValue;
        WmlScaledFloatToInt(ms_kBackgroundColor.g,8,iValue);
        m_akScreen[i].g = (unsigned char)iValue;
        WmlScaledFloatToInt(ms_kBackgroundColor.b,8,iValue);
        m_akScreen[i].b = (unsigned char)iValue;
    }
}
//----------------------------------------------------------------------------
bool& Application2::ClampToWindow ()
{
    return m_bClampToWindow;
}
//----------------------------------------------------------------------------
void Application2::SetPixel (int iX, int iY, Color kColor)
{
    if ( m_bClampToWindow )
    {
        if ( 0 <= iX && iX < ms_iWidth && 0 <= iY && iY < ms_iHeight )
            m_akScreen[Index(iX,iY)] = kColor;
    }
    else
    {
        m_akScreen[Index(iX,iY)] = kColor;
    }
}
//----------------------------------------------------------------------------
Application2::Color Application2::GetPixel (int iX, int iY)
{
    if ( m_bClampToWindow )
    {
        if ( 0 <= iX && iX < ms_iWidth && 0 <= iY && iY < ms_iHeight )
            return m_akScreen[Index(iX,iY)];
        else
            return Color(0,0,0);
    }
    else
    {
        return m_akScreen[Index(iX,iY)];
    }
}
//----------------------------------------------------------------------------
void Application2::DrawLine (int iX0, int iY0, int iX1, int iY1, Color kColor)
{
    int iX = iX0, iY = iY0;

    // direction of line
    int iDx = iX1-iX0, iDy = iY1-iY0;

    // increment or decrement depending on direction of line
    int iSx = (iDx > 0 ? 1 : (iDx < 0 ? -1 : 0));
    int iSy = (iDy > 0 ? 1 : (iDy < 0 ? -1 : 0));

    // decision parameters for voxel selection
    if ( iDx < 0 ) iDx = -iDx;
    if ( iDy < 0 ) iDy = -iDy;
    int iAx = 2*iDx, iAy = 2*iDy;
    int iDecX, iDecY;

    // determine largest direction component, single-step related variable
    int iMax = iDx, iVar = 0;
    if ( iDy > iMax ) { iVar = 1; }

    // traverse Bresenham line
    switch ( iVar )
    {
    case 0:  // single-step in x-direction
        iDecY = iAy - iDx;
        for (/**/; /**/; iX += iSx, iDecY += iAy)
        {
            // process pixel
            SetPixel(iX,iY,kColor);

            // take Bresenham step
            if ( iX == iX1 )  break;
            if ( iDecY >= 0 ) { iDecY -= iAx; iY += iSy; }
        }
        break;
    case 1:  // single-step in y-direction
        iDecX = iAx - iDy;
        for (/**/; /**/; iY += iSy, iDecX += iAx)
        {
            // process pixel
            SetPixel(iX,iY,kColor);

            // take Bresenham step
            if ( iY == iY1 ) break;
            if ( iDecX >= 0 ) { iDecX -= iAy; iX += iSx; }
        }
        break;
    }
}
//----------------------------------------------------------------------------
void Application2::DrawRectangle (int iXMin, int iYMin, int iXMax, int iYMax,
    Color kColor, bool bSolid)
{
    if ( iXMin >= ms_iWidth || iXMax < 0
    ||   iYMin >= ms_iHeight || iYMax < 0 )
    {
        // rectangle not visible
        return;
    }

    // clamp to window border
    if ( iXMin < 0 )
        iXMin = 0;
    if ( iXMax >= ms_iWidth )
        iXMax = ms_iWidth-1;
    if ( iYMin < 0 )
        iYMin = 0;
    if ( iYMax >= ms_iHeight )
        iYMax = ms_iHeight-1;

    int iX, iY;

    if ( bSolid )
    {
        for (iY = iYMin; iY <= iYMax; iY++)
        {
            for (iX = iXMin; iX <= iXMax; iX++)
                m_akScreen[Index(iX,iY)] = kColor;
        }
    }
    else
    {
        for (iX = iXMin; iX <= iXMax; iX++)
        {
            m_akScreen[Index(iX,iYMin)] = kColor;
            m_akScreen[Index(iX,iYMax)] = kColor;
        }
        for (iY = iYMin+1; iY <= iYMax-1; iY++)
        {
            m_akScreen[Index(iXMin,iY)] = kColor;
            m_akScreen[Index(iXMax,iY)] = kColor;
        }
    }
}
//----------------------------------------------------------------------------
void Application2::DrawCircle (int iXCenter, int iYCenter, int iRadius,
    Color kColor, bool bSolid)
{
    int iX, iY, iDec;

    if ( bSolid )
    {
        int iXValue, iYMin, iYMax, i;
        for (iX = 0, iY = iRadius, iDec = 3-2*iRadius; iX <= iY; iX++)
        {
            iXValue = iXCenter + iX;
            iYMin = iYCenter - iY;
            iYMax = iYCenter + iY;
            for (i = iYMin; i <= iYMax; i++)
                m_akScreen[Index(iXValue,i)] = kColor;

            iXValue = iXCenter - iX;
            for (i = iYMin; i <= iYMax; i++)
                m_akScreen[Index(iXValue,i)] = kColor;

            iXValue = iXCenter + iY;
            iYMin = iYCenter - iX;
            iYMax = iYCenter + iX;
            for (i = iYMin; i <= iYMax; i++)
                m_akScreen[Index(iXValue,i)] = kColor;

            iXValue = iXCenter - iY;
            for (i = iYMin; i <= iYMax; i++)
                m_akScreen[Index(iXValue,i)] = kColor;

            if ( iDec >= 0 )
                iDec += -4*(iY--)+4;
            iDec += 4*iX+6;
        }
    }
    else
    {
        for (iX = 0, iY = iRadius, iDec = 3-2*iRadius; iX <= iY; iX++)
        {
            m_akScreen[Index(iXCenter+iX,iYCenter+iY)] = kColor;
            m_akScreen[Index(iXCenter+iX,iYCenter-iY)] = kColor;
            m_akScreen[Index(iXCenter-iX,iYCenter+iY)] = kColor;
            m_akScreen[Index(iXCenter-iX,iYCenter-iY)] = kColor;
            m_akScreen[Index(iXCenter+iY,iYCenter+iX)] = kColor;
            m_akScreen[Index(iXCenter+iY,iYCenter-iX)] = kColor;
            m_akScreen[Index(iXCenter-iY,iYCenter+iX)] = kColor;
            m_akScreen[Index(iXCenter-iY,iYCenter-iX)] = kColor;

            if ( iDec >= 0 )
                iDec += -4*(iY--)+4;
            iDec += 4*iX+6;
        }
    }
}
//----------------------------------------------------------------------------
void Application2::DoFlip (bool bDoFlip)
{
    if ( m_akFlipScreen )
    {
        if ( !bDoFlip )
        {
            delete[] m_akFlipScreen;
            m_akFlipScreen = NULL;
        }
    }
    else
    {
        if ( bDoFlip )
            m_akFlipScreen = new Color[m_iScrWidth*m_iScrHeight];
    }
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

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