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

📄 testtubesurface.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
//
// FREE SOURCE CODE
// http://www.magic-software.com/License.html/free.pdf

#include "TestTubeSurface.h"

//---------------------------------------------------------------------------
MgcApplication* MgcApplication::Create ()
{
    return new TestTubeSurface;
}
//---------------------------------------------------------------------------
TestTubeSurface::TestTubeSurface ()
    :
    MgcApplication("TestTubeSurface",640,480,0,1)
{
    m_fDeltaTime = 0.01;
    MeasureTime();
}
//---------------------------------------------------------------------------
MgcImage* TestTubeSurface::CreateImageFromBMP (const char* acFilename)
{
    HBITMAP hImage = (HBITMAP) LoadImage(NULL,acFilename,IMAGE_BITMAP,0,0,
        LR_LOADFROMFILE | LR_CREATEDIBSECTION);

    DIBSECTION dibSection;
    GetObject(hImage,sizeof(DIBSECTION),&dibSection);

    int iWidth = dibSection.dsBm.bmWidth;
    int iHeight = dibSection.dsBm.bmHeight;
    int iQuantity = dibSection.dsBm.bmWidth*dibSection.dsBm.bmHeight;
    assert( dibSection.dsBm.bmBitsPixel == 24 );

    // Windows BMP stores BGR, need to invert to RGB.
    unsigned char* acSrc = (unsigned char*) dibSection.dsBm.bmBits;
    unsigned char* acDst = new unsigned char[3*iQuantity];
    for (int i = 0, i0 = 0, i1 = 1, i2 = 2; i < iQuantity; i++)
    {
        acDst[i0] = acSrc[i2];
        acDst[i1] = acSrc[i1];
        acDst[i2] = acSrc[i0];
        i0 += 3;
        i1 += 3;
        i2 += 3;
    }

    DeleteObject(hImage);

    return new MgcImage(MgcImage::IT_RGB888,iWidth,iHeight,acDst);
}
//---------------------------------------------------------------------------
MgcMultipleCurve3* TestTubeSurface::CreateCurve ()
{
    // sample points on a looped helix (first and last point must match)
    const MgcReal fFourPi = 4.0f*MgcMath::PI;
    int iSegments = 32;
    int iSegmentsP1 = iSegments + 1;
    MgcReal* afTime = new MgcReal[iSegmentsP1];
    MgcVector3* akPoint = new MgcVector3[iSegmentsP1];
    int i;
    for (i = 0; i <= iSegmentsP1/2; i++)
    {
        afTime[i] = i*fFourPi/iSegmentsP1;
        akPoint[i].x = MgcMath::Cos(afTime[i]);
        akPoint[i].y = MgcMath::Sin(afTime[i]);
        akPoint[i].z = afTime[i];
    }

    for (i = iSegmentsP1/2 + 1; i < iSegments; i++)
    {
        afTime[i] = i*fFourPi/iSegments;
        akPoint[i].x = 2.0f - MgcMath::Cos(afTime[i]);
        akPoint[i].y = MgcMath::Sin(afTime[i]);
        akPoint[i].z = fFourPi - afTime[i];
    }

    afTime[iSegments] = fFourPi;
    akPoint[iSegments] = akPoint[0];

    // save min and max times
    m_fMinCurveTime = 0.0;
    m_fMaxCurveTime = fFourPi;
    m_fCurvePeriod = m_fMaxCurveTime - m_fMinCurveTime;
    m_fCurveTime = m_fMinCurveTime;

    // create a closed cubic curve containing the sample points
    MgcNaturalSpline3* pkCurve = new MgcNaturalSpline3(
        MgcNaturalSpline3::BT_CLOSED,iSegments,afTime,akPoint);

    return pkCurve;
}
//---------------------------------------------------------------------------
MgcReal TestTubeSurface::Radial (MgcReal fT)
{
    return 0.0625;
}
//---------------------------------------------------------------------------
bool TestTubeSurface::Initialize ()
{
    m_spkCamera = new MgcOglCamera(640,480);
    m_spkCamera->SetFrustum(0.01,10.0,-0.0055,0.0055,0.004125,-0.004125);

    m_spkRenderer = new MgcOglRenderer(GetWindowHandle(),640,480);
    m_spkRenderer->SetBackgroundColor(MgcColor(0.5f,0.0f,1.0f));
    m_spkRenderer->SetCamera(m_spkCamera);

    m_spkScene = new MgcNode;

    m_spkTexture = new MgcTexture;
    m_spkTexture->SetImage(CreateImageFromBMP("grating.bmp"));
    m_spkTexture->Filter() = MgcTexture::FM_LINEAR;
    m_spkTexture->Mipmap() = MgcTexture::MM_LINEAR;
    m_spkTexture->Wrap() = MgcTexture::WM_WRAP_S_WRAP_T;
    m_spkTextureState = new MgcTextureState;
    m_spkTextureState->Set(0,m_spkTexture);
    m_spkScene->SetRenderState(m_spkTextureState);

    m_spkWireframeState = new MgcWireframeState;
    m_spkWireframeState->Enabled() = false;
    m_spkScene->SetRenderState(m_spkWireframeState);

    m_spkZBufferState = new MgcZBufferState;
    m_spkZBufferState->Enabled() = true;
    m_spkZBufferState->Writeable() = true;
    m_spkZBufferState->Compare() = MgcZBufferState::CF_LEQUAL;
    m_spkScene->SetRenderState(m_spkZBufferState);

    m_pkCurve = CreateCurve();
    MgcTubeSurface* pkTube = new MgcTubeSurface(m_pkCurve,Radial,true,
        256,32,true,false,&MgcVector3::UNIT_Z,MgcVector2(0.0,0.0),
        MgcVector2(1.0,32.0));

    m_spkScene->AttachChild(pkTube);

    MoveCamera();
    m_spkScene->UpdateGS(0.0);
    m_spkScene->UpdateRS();
    return true;
}
//---------------------------------------------------------------------------
void TestTubeSurface::Terminate ()
{
    m_spkTexture = 0;
    m_spkTextureState = 0;
    m_spkWireframeState = 0;
    m_spkZBufferState = 0;
    m_spkCamera = 0;
    m_spkRenderer = 0;
    m_spkScene = 0;
}
//---------------------------------------------------------------------------
void TestTubeSurface::MoveCamera ()
{
    MgcVector3 kP = m_pkCurve->GetPosition(m_fCurveTime);
    MgcVector3 kT = m_pkCurve->GetTangent(m_fCurveTime);
    MgcVector3 kB = kT.UnitCross(MgcVector3::UNIT_Z);
    MgcVector3 kN = kB.UnitCross(kT);

    m_spkCamera->SetLocation(kP);
    m_spkCamera->SetAxes(-kB,kN,kT);
    m_spkCamera->Update();
}
//---------------------------------------------------------------------------
void TestTubeSurface::OnIdle ()
{
    MeasureTime();

    m_spkRenderer->ClearBuffers();
    m_spkRenderer->Draw(m_spkScene);
    m_spkRenderer->DisplayBackBuffer();

    DrawFrameRate();
    UpdateClicks();
}
//---------------------------------------------------------------------------
bool TestTubeSurface::WmChar (char cCharCode, long lKeyData)
{
    switch ( cCharCode )
    {
    case '0':  // reset frame rate measurements
        ResetTime();
        return true;
    case 'w':
        m_spkWireframeState->Enabled() = !m_spkWireframeState->Enabled();
        return true;
    case '+':
    case '=':
        m_fDeltaTime *= 2.0;
        return true;
    case '-':
    case '_':
        m_fDeltaTime *= 0.5;
        return true;
    case 'q':
    case 'Q':
    case VK_ESCAPE:
        PostMessage(GetWindowHandle(),WM_DESTROY,0,0);
        return true;
    }

    return false;
}
//---------------------------------------------------------------------------
bool TestTubeSurface::WmKeyDown (int iVirtKey, long lKeyData)
{
    switch ( iVirtKey )
    {
    case VK_UP:
        m_fCurveTime += m_fDeltaTime;
        if ( m_fCurveTime > m_fMaxCurveTime )
            m_fCurveTime -= m_fCurvePeriod;
        MoveCamera();
        return true;
    case VK_DOWN:
        m_fCurveTime -= m_fDeltaTime;
        if ( m_fCurveTime < m_fMinCurveTime )
            m_fCurveTime += m_fCurvePeriod;
        MoveCamera();
        return true;
    }

    return false;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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