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

📄 testsoft.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 "TestSoft.h"

//---------------------------------------------------------------------------
MgcApplication* MgcApplication::Create ()
{
    return new TestSoft;
}
//---------------------------------------------------------------------------
TestSoft::TestSoft ()
    :
    MgcApplication("TestSoft",640,480,0,1)
{
    // set up bindings for camera turret
    m_fTrnSpeed = 0.5;
    m_fRotSpeed = 0.05;
    m_kTurret.BindKeysToTranslateRight('[',']',m_fTrnSpeed);
    m_kTurret.BindKeysToTranslateUp('U','D',m_fTrnSpeed);
    m_kTurret.BindKeysToTranslateDirection(VK_DOWN,VK_UP,m_fTrnSpeed);
    m_kTurret.BindKeysToRotateRight(VK_PRIOR,VK_NEXT,m_fRotSpeed);
    m_kTurret.BindKeysToRotateUp(VK_RIGHT,VK_LEFT,m_fRotSpeed);

    // initialize 'last time'
    MeasureTime();
}
//---------------------------------------------------------------------------
bool TestSoft::Initialize ()
{
    m_spkCamera = new MgcGPCamera(640.0,480.0);
    m_spkCamera->SetFrustum(0.1,100.0,-0.055,0.055,0.04125,-0.04125);
    m_spkCamera->Update();

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

    m_spkScene = new MgcNode(1);
    m_spkScene->Translate() = MgcVector3(0.0,0.0,8.0);

    m_spkSceneChild = new MgcNode(3);
    m_spkScene->AttachChild(m_spkSceneChild);

    m_spkCube = CreateColoredCube();
    m_spkSceneChild->AttachChild(m_spkCube);

    m_spkTFace = CreateTexturedFace();
    m_spkTFace->Translate() = MgcVector3(3.0,0.0,0.0);
    m_spkSceneChild->AttachChild(m_spkTFace);

    //m_spkLFace = CreateSiLeFace();
    m_spkLFace = CreateSiLdFace();
    m_spkLFace->Translate() = MgcVector3(-3.0,0.0,0.0);
    m_spkSceneChild->AttachChild(m_spkLFace);

    m_spkWireframeState = new MgcWireframeState;
    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_spkScene->UpdateGS(0.0);
    m_spkScene->UpdateRS();

    m_spkRotNode = m_spkSceneChild;

    return true;
}
//---------------------------------------------------------------------------
void TestSoft::Terminate ()
{
    m_spkWireframeState = 0;
    m_spkZBufferState = 0;
    m_spkCamera = 0;
    m_spkRenderer = 0;
    m_spkScene = 0;
}
//---------------------------------------------------------------------------
void TestSoft::OnIdle ()
{
    MeasureTime();

    if ( GetFocus() == GetWindowHandle() )
    {
        if ( m_kTurret.ReadKeyboard() )
        {
            m_spkRenderer->GetCamera()->SetFrame(m_kTurret.GetTranslate(),
                m_kTurret.GetRotate());
        }
    }

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

    DrawFrameRate();
    UpdateClicks();
}
//---------------------------------------------------------------------------
bool TestSoft::WmChar (char cCharCode, long lKeyData)
{
    switch ( cCharCode )
    {
    case '0':  // reset frame rate measurements
        ResetTime();
        return true;
    case 'b':
        if ( m_spkZBufferState->Compare() == MgcZBufferState::CF_NEVER )
            m_spkZBufferState->Compare() = MgcZBufferState::CF_LEQUAL;
        else
            m_spkZBufferState->Compare() = MgcZBufferState::CF_NEVER;
        return true;
    case 'w':
        m_spkWireframeState->Enabled() = !m_spkWireframeState->Enabled();
        return true;
    case '+':
    case '=':
        m_spkLight->Intensity() += 1.0;
        return true;
    case '-':
    case '_':
        if ( m_spkLight->Intensity() > 1.0 )
            m_spkLight->Intensity() -= 1.0;
        return true;
    case 'q':
    case 'Q':
    case VK_ESCAPE:
        PostMessage(GetWindowHandle(),WM_DESTROY,0,0);
        return true;
    }

    const MgcReal fTrnSpeed = 0.1;
    const MgcReal fRotSpeed = 0.1;
    MgcMatrix3 kRot, kIncr;

    switch ( cCharCode )
    {
        case 'f':
            m_spkRotNode = m_spkTFace;
            break;
        case 'l':
            m_spkRotNode = m_spkLFace;
            break;
        case 'c':
            m_spkRotNode = m_spkCube;
            break;
        case 't':
            m_spkRotNode = m_spkSceneChild;
            break;
        case 'x':
            m_spkScene->Translate().x -= fTrnSpeed;
            break;
        case 'X':
            m_spkScene->Translate().x += fTrnSpeed;
            break;
        case 'y':
            m_spkScene->Translate().y -= fTrnSpeed;
            break;
        case 'Y':
            m_spkScene->Translate().y += fTrnSpeed;
            break;
        case 'z':
            m_spkScene->Translate().z -= fTrnSpeed;
            break;
        case 'Z':
            m_spkScene->Translate().z += fTrnSpeed;
            break;
        case 'r':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_X,fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        case 'R':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_X,-fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        case 'a':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_Y,fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        case 'A':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_Y,-fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        case 'p':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_Z,fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        case 'P':
            kRot = m_spkRotNode->Rotate();
            kIncr.FromAxisAngle(MgcVector3::UNIT_Z,-fRotSpeed);
            m_spkRotNode->Rotate() = kIncr*kRot;
            break;
        default:
            return false;
    }

    m_spkScene->UpdateGS(0.0);

    return false;
}
//---------------------------------------------------------------------------
MgcGPTriMesh* TestSoft::CreateColoredCube ()
{
    unsigned int uiVertexQuantity = 8;
    unsigned int uiTriangleQuantity = 12;
    unsigned int uiEdgeQuantity = 18;

    MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];
    akVertex[0] = MgcVector3(-1,-1,-1);
    akVertex[1] = MgcVector3(+1,-1,-1);
    akVertex[2] = MgcVector3(+1,+1,-1);
    akVertex[3] = MgcVector3(-1,+1,-1);
    akVertex[4] = MgcVector3(-1,-1,+1);
    akVertex[5] = MgcVector3(+1,-1,+1);
    akVertex[6] = MgcVector3(+1,+1,+1);
    akVertex[7] = MgcVector3(-1,+1,+1);

    MgcColor* akColor = new MgcColor[uiVertexQuantity];
    akColor[0] = MgcColor(1,0,0);
    akColor[1] = MgcColor(0,1,0);
    akColor[2] = MgcColor(0,0,1);
    akColor[3] = MgcColor(0,0,0);
    akColor[4] = MgcColor(0,0,1);
    akColor[5] = MgcColor(1,0,1);
    akColor[6] = MgcColor(1,1,0);
    akColor[7] = MgcColor(1,1,1);

    MgcGPTriMesh* pkCube = new MgcGPTriMesh(uiVertexQuantity,akVertex,0,
        akColor,0,uiTriangleQuantity,uiEdgeQuantity);

    pkCube->InsertTriangle(0,2,1);
    pkCube->InsertTriangle(0,3,2);
    pkCube->InsertTriangle(4,5,6);
    pkCube->InsertTriangle(4,6,7);
    pkCube->InsertTriangle(1,6,5);
    pkCube->InsertTriangle(1,2,6);
    pkCube->InsertTriangle(0,7,3);
    pkCube->InsertTriangle(0,4,7);
    pkCube->InsertTriangle(0,1,5);
    pkCube->InsertTriangle(0,5,4);
    pkCube->InsertTriangle(3,6,2);
    pkCube->InsertTriangle(3,7,6);

    pkCube->UpdateModelBound();

    return pkCube;
}
//---------------------------------------------------------------------------
MgcGPTriMesh* TestSoft::CreateTexturedFace ()
{
    // textured face
    unsigned int uiVertexQuantity = 4;
    unsigned int uiTriangleQuantity = 2;
    unsigned int uiEdgeQuantity = 5;

    MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];
    akVertex[0] = MgcVector3(-1,-1,-1);
    akVertex[1] = MgcVector3(+1,-1,-1);
    akVertex[2] = MgcVector3(+1,+1,-1);
    akVertex[3] = MgcVector3(-1,+1,-1);

    MgcVector2* akTexture = new MgcVector2[uiVertexQuantity];
    akTexture[0] = MgcVector2(0,0);
    akTexture[1] = MgcVector2(1,0);
    akTexture[2] = MgcVector2(1,1);
    akTexture[3] = MgcVector2(0,1);

    MgcGPTriMesh* pkFace = new MgcGPTriMesh(uiVertexQuantity,akVertex,0,0,
        akTexture,uiTriangleQuantity,uiEdgeQuantity);

    pkFace->InsertTriangle(0,2,1);
    pkFace->InsertTriangle(0,3,2);

    pkFace->UpdateModelBound();

    int iXSize = 128;
    int iYSize = 128;
    int iQuantity = iXSize*iYSize;
    MgcSoftColor* akColor = new MgcSoftColor[iQuantity];
    for (int i = 0; i < iQuantity; i++)
    {
        akColor[i] = MgcSoftColor(MgcMath::UnitRandom(),
            MgcMath::UnitRandom(),MgcMath::UnitRandom());
    }

    MgcImage* pkImage = new MgcImage(MgcImage::IT_RGBA5551,iXSize,iYSize,
        (unsigned char*)akColor);

    MgcTexture* pkTexture = new MgcTexture;
    pkTexture->SetImage(pkImage);
    pkTexture->Correction() = MgcTexture::CM_AFFINE;
    pkTexture->Mipmap() = MgcTexture::MM_NONE;
    MgcTextureState* pkTextureState = new MgcTextureState;
    pkTextureState->Set(0,pkTexture);
    pkFace->SetRenderState(pkTextureState);

    return pkFace;
}
//---------------------------------------------------------------------------
MgcGPTriMesh* TestSoft::CreateSiLeFace ()
{
    unsigned int uiVertexQuantity = 4;
    unsigned int uiTriangleQuantity = 2;
    unsigned int uiEdgeQuantity = 5;

    MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];
    akVertex[0] = MgcVector3(-1,-1,-1);
    akVertex[1] = MgcVector3(+1,-1,-1);
    akVertex[2] = MgcVector3(+1,+1,-1);
    akVertex[3] = MgcVector3(-1,+1,-1);

    MgcGPTriMesh* pkFace = new MgcGPTriMesh(uiVertexQuantity,akVertex,0,0,
        0,uiTriangleQuantity,uiEdgeQuantity);

    pkFace->InsertTriangle(0,2,1);
    pkFace->InsertTriangle(0,3,2);

    pkFace->UpdateModelBound();

    MgcMaterialState* pkMState = new MgcMaterialState;
    pkMState->Emissive() = MgcColor(1.0,1.0,0.0);
    pkFace->SetRenderState(pkMState);

    MgcVertexColorState* pkVState = new MgcVertexColorState;
    pkVState->Source() = MgcVertexColorState::SM_IGNORE;
    pkVState->Lighting() = MgcVertexColorState::LM_EMISSIVE;
    pkFace->SetRenderState(pkVState);

    return pkFace;
}
//---------------------------------------------------------------------------
MgcGPTriMesh* TestSoft::CreateSiLdFace ()
{
    unsigned int uiVertexQuantity = 4;
    unsigned int uiTriangleQuantity = 2;
    unsigned int uiEdgeQuantity = 5;

    MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];
    akVertex[0] = MgcVector3(-1,-1,-1);
    akVertex[1] = MgcVector3(+1,-1,-1);
    akVertex[2] = MgcVector3(+1,+1,-1);
    akVertex[3] = MgcVector3(-1,+1,-1);

    MgcVector3* akNormal = new MgcVector3[uiVertexQuantity];
    for (int i = 0; i < 4; i++)
    {
        akNormal[i] = -akVertex[i];
        akNormal[i].Unitize();
    }

    MgcGPTriMesh* pkFace = new MgcGPTriMesh(uiVertexQuantity,akVertex,
        akNormal,0,0,uiTriangleQuantity,uiEdgeQuantity);

    pkFace->InsertTriangle(0,2,1);
    pkFace->InsertTriangle(0,3,2);

    pkFace->UpdateModelBound();

    m_spkLight = new MgcDirectionalLight;
    MgcVector3 kDir = MgcVector3(1.0,1.0,1.0);
    kDir.Unitize();
    m_spkLight->Direction() = kDir;
    m_spkLight->Ambient() = MgcColor(0.1,0.1,0.1);
    m_spkLight->Diffuse() = MgcColor(0.1,0.1,0.1);
    MgcLightState* pkLightState = new MgcLightState;
    pkLightState->Attach(m_spkLight);
    pkFace->SetRenderState(pkLightState);

    MgcMaterialState* pkMState = new MgcMaterialState;
    pkMState->Emissive() = MgcColor(0.25,0.25,0.0);
    pkMState->Ambient() = MgcColor(0.1,0.1,0.1);
    pkMState->Diffuse() = MgcColor(0.1,0.1,0.1);
    pkFace->SetRenderState(pkMState);

    MgcVertexColorState* pkVState = new MgcVertexColorState;
    pkVState->Source() = MgcVertexColorState::SM_IGNORE;
    pkVState->Lighting() = MgcVertexColorState::LM_DIFFUSE;
    pkFace->SetRenderState(pkVState);

    return pkFace;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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