Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
605 lines
19 KiB
C++
605 lines
19 KiB
C++
//-----------------------------------------------------------------------------
|
|
// File: SkinnedMesh.cpp
|
|
//
|
|
// Desc: Example code showing how to use animated models with skinning.
|
|
//
|
|
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
#define STRICT
|
|
#include <tchar.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <mmsystem.h>
|
|
#include <commdlg.h>
|
|
#include <tchar.h>
|
|
#include <d3d8.h>
|
|
#include <d3dx8.h>
|
|
#include "resource.h"
|
|
#include "D3DApp.h"
|
|
#include "D3DFont.h"
|
|
#include "D3DUtil.h"
|
|
#include "DXUtil.h"
|
|
#include "SkinnedMesh.h"
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: WinMain()
|
|
// Desc: Entry point to the program. Initializes everything, and goes into a
|
|
// message-processing loop. Idle time is used to render the scene.
|
|
//-----------------------------------------------------------------------------
|
|
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
|
|
{
|
|
CMyD3DApplication d3dApp;
|
|
|
|
if( FAILED( d3dApp.Create( hInst ) ) )
|
|
return 0;
|
|
|
|
return d3dApp.Run();
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: CMyD3DApplication()
|
|
// Desc: Application constructor. Sets attributes for the app.
|
|
//-----------------------------------------------------------------------------
|
|
CMyD3DApplication::CMyD3DApplication()
|
|
{
|
|
m_strWindowTitle = _T("Skinned Mesh");
|
|
m_bUseDepthBuffer = TRUE;
|
|
m_bShowCursorWhenFullscreen = TRUE;
|
|
|
|
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
|
|
|
|
m_pmcSelectedMesh = NULL;
|
|
m_pframeSelected = NULL;
|
|
m_pdeHead = NULL;
|
|
m_pdeSelected = NULL;
|
|
|
|
m_dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL | D3DFVF_TEX1;
|
|
|
|
m_method = D3DNONINDEXED;
|
|
|
|
m_pBoneMatrices = NULL;
|
|
m_maxBones = 0;
|
|
|
|
m_szPath[0] = '\0';
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ConfirmDevice()
|
|
// Desc: Called during device intialization, this code checks the device
|
|
// for some minimum set of capabilities
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
|
|
D3DFORMAT Format )
|
|
{
|
|
// This sample wants mixed vertex processing rather than hardware
|
|
// vertex processing so it can fallback to sw processing if the
|
|
// device supports fewer than three matrices when skinning.
|
|
if( dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING )
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: OneTimeSceneInit()
|
|
// Desc: Called during initial app startup, this function performs all the
|
|
// permanent initialization.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::OneTimeSceneInit()
|
|
{
|
|
// Set cursor to indicate that user can move the object with the mouse
|
|
#ifdef _WIN64
|
|
SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
|
|
#else
|
|
SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)LoadCursor( NULL, IDC_SIZEALL ) );
|
|
#endif
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: FrameMove()
|
|
// Desc: Called once per frame, the call is the entry point for animating
|
|
// the scene.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::FrameMove()
|
|
{
|
|
SDrawElement *pdeCur;
|
|
SFrame *pframeCur;
|
|
|
|
pdeCur = m_pdeHead;
|
|
while (pdeCur != NULL)
|
|
{
|
|
pdeCur->fCurTime += m_fElapsedTime * 4800;
|
|
if (pdeCur->fCurTime > 1.0e15f)
|
|
pdeCur->fCurTime = 0;
|
|
|
|
pframeCur = pdeCur->pframeAnimHead;
|
|
while (pframeCur != NULL)
|
|
{
|
|
pframeCur->SetTime(pdeCur->fCurTime);
|
|
pframeCur = pframeCur->pframeAnimNext;
|
|
}
|
|
|
|
pdeCur = pdeCur->pdeNext;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: Render()
|
|
// Desc: Called once per frame, the call is the entry point for 3d
|
|
// rendering. This function sets up render states, clears the
|
|
// viewport, and renders the scene.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::Render()
|
|
{
|
|
// Set up viewing postion from ArcBall
|
|
SDrawElement *pdeCur;
|
|
D3DXMATRIXA16 mat;
|
|
pdeCur = m_pdeHead;
|
|
while (pdeCur != NULL)
|
|
{
|
|
pdeCur->pframeRoot->matRot = *m_ArcBall.GetRotationMatrix();
|
|
pdeCur->pframeRoot->matTrans = *m_ArcBall.GetTranslationMatrix();
|
|
pdeCur = pdeCur->pdeNext;
|
|
}
|
|
|
|
// Clear the viewport
|
|
m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(89,135,179), 1.0f, 0 );
|
|
|
|
if (m_pdeHead == NULL)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// Begin the scene
|
|
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
|
|
{
|
|
UINT cTriangles = 0;
|
|
HRESULT hr;
|
|
SDrawElement *pdeCur;
|
|
D3DXMATRIXA16 mCur;
|
|
D3DXVECTOR3 vTemp;
|
|
|
|
D3DXMatrixTranslation(&m_mView, 0, 0, -m_pdeSelected->fRadius * 2.8f);
|
|
|
|
hr = m_pd3dDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&m_mView);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
pdeCur = m_pdeHead;
|
|
while (pdeCur != NULL)
|
|
{
|
|
D3DXMatrixIdentity(&mCur);
|
|
|
|
hr = UpdateFrames(pdeCur->pframeRoot, mCur);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
hr = DrawFrames(pdeCur->pframeRoot, cTriangles);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
pdeCur = pdeCur->pdeNext;
|
|
}
|
|
|
|
// Show frame rate
|
|
m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
|
|
m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
|
|
|
|
// End the scene.
|
|
m_pd3dDevice->EndScene();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: InitDeviceObjects()
|
|
// Desc: Initialize scene objects.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::InitDeviceObjects()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Restore the fonts
|
|
m_pFont->InitDeviceObjects( m_pd3dDevice );
|
|
|
|
// if no filename, use the default
|
|
if (m_szPath[0] == '\0')
|
|
{
|
|
DXUtil_FindMediaFile( m_szPath, _T("tiny.x") );
|
|
}
|
|
|
|
LoadMeshHierarchy();
|
|
|
|
if( m_pdeHead != NULL)
|
|
m_ArcBall.SetRadius( m_pdeHead->fRadius );
|
|
m_ArcBall.SetRightHanded( TRUE );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: RestoreDeviceObjects()
|
|
// Desc: Initialize scene objects.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::RestoreDeviceObjects()
|
|
{
|
|
// Restore the fonts
|
|
m_pFont->RestoreDeviceObjects();
|
|
|
|
HRESULT hr = S_OK;
|
|
D3DLIGHT8 light;
|
|
|
|
m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 2.0f );
|
|
|
|
if (m_pdeSelected != NULL)
|
|
SetProjectionMatrix();
|
|
|
|
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
|
|
|
|
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
|
|
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
|
|
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
|
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
|
|
|
m_pd3dDevice->SetRenderState( D3DRS_COLORVERTEX, FALSE );
|
|
|
|
// Create vertex shader for the indexed skinning
|
|
DWORD dwIndexedVertexDecl1[] =
|
|
{
|
|
D3DVSD_STREAM( 0 ),
|
|
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // Position of first mesh
|
|
D3DVSD_REG( 2, D3DVSDT_D3DCOLOR ), // Blend indices
|
|
// D3DVSD_REG( 2, D3DVSDT_UBYTE4 ), // Blend indices
|
|
D3DVSD_REG( 3, D3DVSDT_FLOAT3 ), // Normal
|
|
D3DVSD_REG( 4, D3DVSDT_FLOAT2 ), // Tex coords
|
|
D3DVSD_END()
|
|
};
|
|
|
|
DWORD dwIndexedVertexDecl2[] =
|
|
{
|
|
D3DVSD_STREAM( 0 ),
|
|
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // Position of first mesh
|
|
D3DVSD_REG( 1, D3DVSDT_FLOAT1 ), // Blend weights
|
|
D3DVSD_REG( 2, D3DVSDT_D3DCOLOR ), // Blend indices
|
|
// D3DVSD_REG( 2, D3DVSDT_UBYTE4 ), // Blend indices
|
|
D3DVSD_REG( 3, D3DVSDT_FLOAT3 ), // Normal
|
|
D3DVSD_REG( 4, D3DVSDT_FLOAT2 ), // Tex coords
|
|
D3DVSD_END()
|
|
};
|
|
|
|
DWORD dwIndexedVertexDecl3[] =
|
|
{
|
|
D3DVSD_STREAM( 0 ),
|
|
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // Position of first mesh
|
|
D3DVSD_REG( 1, D3DVSDT_FLOAT2 ), // Blend weights
|
|
D3DVSD_REG( 2, D3DVSDT_D3DCOLOR ), // Blend indices
|
|
// D3DVSD_REG( 2, D3DVSDT_UBYTE4 ), // Blend indices
|
|
D3DVSD_REG( 3, D3DVSDT_FLOAT3 ), // Normal
|
|
D3DVSD_REG( 4, D3DVSDT_FLOAT2 ), // Tex coords
|
|
D3DVSD_END()
|
|
};
|
|
|
|
DWORD dwIndexedVertexDecl4[] =
|
|
{
|
|
D3DVSD_STREAM( 0 ),
|
|
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // Position of first mesh
|
|
D3DVSD_REG( 1, D3DVSDT_FLOAT3 ), // Blend weights
|
|
D3DVSD_REG( 2, D3DVSDT_D3DCOLOR ), // Blend indices
|
|
// D3DVSD_REG( 2, D3DVSDT_UBYTE4 ), // Blend indices
|
|
D3DVSD_REG( 3, D3DVSDT_FLOAT3 ), // Normal
|
|
D3DVSD_REG( 4, D3DVSDT_FLOAT2 ), // Tex coords
|
|
D3DVSD_END()
|
|
};
|
|
|
|
DWORD* dwIndexedVertexDecl[] = {dwIndexedVertexDecl1, dwIndexedVertexDecl2, dwIndexedVertexDecl3, dwIndexedVertexDecl4};
|
|
|
|
LPD3DXBUFFER pCode;
|
|
|
|
DWORD bUseSW = D3DUSAGE_SOFTWAREPROCESSING;
|
|
if (m_d3dCaps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
|
|
{
|
|
bUseSW = 0;
|
|
}
|
|
|
|
for (DWORD i = 0; i < 4; ++i)
|
|
{
|
|
// Assemble the vertex shader file
|
|
if( FAILED( hr = D3DXAssembleShaderFromResource(NULL, MAKEINTRESOURCE(IDD_SHADER1 + i), 0, NULL, &pCode, NULL ) ) )
|
|
return hr;
|
|
|
|
// Create the vertex shader
|
|
if( FAILED( hr = m_pd3dDevice->CreateVertexShader( dwIndexedVertexDecl[i],
|
|
(DWORD*)pCode->GetBufferPointer(),
|
|
&(m_dwIndexedVertexShader[i]) , bUseSW ) ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
pCode->Release();
|
|
}
|
|
|
|
ZeroMemory( &light, sizeof(light) );
|
|
light.Type = D3DLIGHT_DIRECTIONAL;
|
|
|
|
light.Diffuse.r = 1.0;
|
|
light.Diffuse.g = 1.0;
|
|
light.Diffuse.b = 1.0;
|
|
light.Specular.r = 0;
|
|
light.Specular.g = 0;
|
|
light.Specular.b = 0;
|
|
light.Ambient.r = 0.25;
|
|
light.Ambient.g = 0.25;
|
|
light.Ambient.b = 0.25;
|
|
|
|
light.Direction = D3DXVECTOR3( 0.0f, 0.0f, -1.0f);
|
|
|
|
hr = m_pd3dDevice->SetLight(0, &light );
|
|
if (FAILED(hr))
|
|
return E_FAIL;
|
|
|
|
hr = m_pd3dDevice->LightEnable(0, TRUE);
|
|
if (FAILED(hr))
|
|
return E_FAIL;
|
|
|
|
// Set Light for vertex shader
|
|
D3DXVECTOR4 vLightDir( 0.0f, 0.0f, 1.0f, 0.0f );
|
|
m_pd3dDevice->SetVertexShaderConstant(1, &vLightDir, 1);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ReleaseDeviceDependentMeshes()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
void ReleaseDeviceDependentMeshes(SFrame* pframe)
|
|
{
|
|
if (pframe->pmcMesh != NULL)
|
|
{
|
|
for (SMeshContainer* pmcCurr = pframe->pmcMesh; pmcCurr != NULL; pmcCurr = pmcCurr->pmcNext)
|
|
{
|
|
if (pmcCurr->m_pSkinMesh != NULL)
|
|
{
|
|
GXRELEASE(pmcCurr->pMesh);
|
|
|
|
pmcCurr->m_Method = NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pframe->pframeFirstChild != NULL)
|
|
ReleaseDeviceDependentMeshes(pframe->pframeFirstChild);
|
|
|
|
if (pframe->pframeSibling != NULL)
|
|
ReleaseDeviceDependentMeshes(pframe->pframeSibling);
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: InvalidateDeviceObjects()
|
|
// Desc: Called when the app is exiting, or the device is being changed,
|
|
// this function deletes any device dependent objects.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
|
|
{
|
|
m_pFont->InvalidateDeviceObjects();
|
|
|
|
|
|
for (SDrawElement* pdeCurr = m_pdeHead; pdeCurr != NULL; pdeCurr = pdeCurr->pdeNext)
|
|
{
|
|
ReleaseDeviceDependentMeshes(pdeCurr->pframeRoot);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: DeleteDeviceObjects()
|
|
// Desc: Called when the app is exiting, or the device is being changed,
|
|
// this function deletes any device dependent objects.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::DeleteDeviceObjects()
|
|
{
|
|
m_pFont->DeleteDeviceObjects();
|
|
|
|
if( m_pdeSelected == m_pdeHead )
|
|
m_pdeSelected = NULL;
|
|
|
|
delete m_pdeHead;
|
|
m_pdeHead = NULL;
|
|
|
|
delete [] m_pBoneMatrices;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: FinalCleanup()
|
|
// Desc: Called before the app exits, this function gives the app the chance
|
|
// to cleanup after itself.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::FinalCleanup()
|
|
{
|
|
SAFE_DELETE( m_pFont );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: MsgProc()
|
|
// Desc: Message proc function to handle key and menu input
|
|
//-----------------------------------------------------------------------------
|
|
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam )
|
|
{
|
|
// Pass mouse messages to the ArcBall so it can build internal matrices
|
|
m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
|
|
|
|
switch( uMsg )
|
|
{
|
|
case WM_COMMAND:
|
|
if ( 0 == HIWORD(wParam) )
|
|
{
|
|
switch ( LOWORD(wParam) )
|
|
{
|
|
case ID_FILE_OPENMESHHEIRARCHY:
|
|
{
|
|
OPENFILENAME ofn;
|
|
memset( &ofn, 0, sizeof(ofn) );
|
|
static TCHAR file[256];
|
|
static TCHAR szFilepath[256];
|
|
static TCHAR fileTitle[256];
|
|
static TCHAR filter[] =
|
|
TEXT("X files (*.x)\0*.x\0")
|
|
TEXT("All Files (*.*)\0*.*\0");
|
|
_tcscpy( file, TEXT(""));
|
|
_tcscpy( fileTitle, TEXT(""));
|
|
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = m_hWnd;
|
|
ofn.hInstance = NULL;//m_hInstance;
|
|
ofn.lpstrFilter = filter;
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nMaxCustFilter = 0L;
|
|
ofn.nFilterIndex = 1L;
|
|
ofn.lpstrFile = file;
|
|
ofn.nMaxFile = sizeof(file);
|
|
ofn.lpstrFileTitle = fileTitle;
|
|
ofn.nMaxFileTitle = sizeof(fileTitle);
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.nFileOffset = 0;
|
|
ofn.nFileExtension = 0;
|
|
ofn.lpstrDefExt = TEXT("*.x");
|
|
ofn.lCustData = 0;
|
|
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
|
if ( ! GetOpenFileName( &ofn) )
|
|
{
|
|
TCHAR s[40];
|
|
DWORD dwErr = CommDlgExtendedError();
|
|
if ( 0 != dwErr )
|
|
{
|
|
wsprintf( s, "GetOpenFileName failed with %x", dwErr );
|
|
MessageBox( m_hWnd, s, "TexWin", MB_OK | MB_SYSTEMMODAL );
|
|
}
|
|
return 0;
|
|
}
|
|
lstrcpy(m_szPath, ofn.lpstrFile);
|
|
HRESULT hr = LoadMeshHierarchy();
|
|
if (FAILED(hr))
|
|
MessageBox(NULL, "Could not open file or incorrect file type", "Error loading file", MB_OK);
|
|
|
|
return 0;
|
|
}
|
|
case ID_OPTIONS_D3DINDEXED:
|
|
{
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXED, MF_CHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DNONINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_SOFTWARESKINNING, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXEDVS, MF_UNCHECKED);
|
|
m_method = D3DINDEXED;
|
|
break;
|
|
}
|
|
case ID_OPTIONS_D3DINDEXEDVS:
|
|
{
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DNONINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_SOFTWARESKINNING, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXEDVS, MF_CHECKED);
|
|
m_method = D3DINDEXEDVS;
|
|
break;
|
|
}
|
|
case ID_OPTIONS_D3DNONINDEXED:
|
|
{
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DNONINDEXED, MF_CHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_SOFTWARESKINNING, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXEDVS, MF_UNCHECKED);
|
|
m_method = D3DNONINDEXED;
|
|
break;
|
|
}
|
|
case ID_OPTIONS_SOFTWARESKINNING:
|
|
{
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DNONINDEXED, MF_UNCHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_SOFTWARESKINNING, MF_CHECKED);
|
|
CheckMenuItem(GetMenu(hWnd), ID_OPTIONS_D3DINDEXEDVS, MF_UNCHECKED);
|
|
m_method = SOFTWARE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: SetProjectionMatrix()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CMyD3DApplication::SetProjectionMatrix()
|
|
{
|
|
D3DXMATRIX mat;
|
|
|
|
if (m_pdeHead == NULL)
|
|
return S_OK;
|
|
|
|
FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
|
|
D3DXMatrixPerspectiveFovRH(&mat, 0.25f*3.141592654f, fAspect, m_pdeSelected->fRadius / 64, m_pdeSelected->fRadius * 200);
|
|
HRESULT hr = m_pd3dDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)&mat );
|
|
if (FAILED(hr))
|
|
return hr;
|
|
// Set Projection Matrix for vertex shader
|
|
D3DXMatrixTranspose(&mat, &mat);
|
|
return m_pd3dDevice->SetVertexShaderConstant(2, &mat, 4);
|
|
}
|