📄 main.cpp
字号:
//-----------------------------------------------------------------------------
// Name: D3D_MapEditorPlus
//
// Description: Example code showing how to save a tile-map.
//
// File Function: Main body of the program (main.cpp)
//
// Code:
// Copyright (c) 2002 LostLogic Corporation. All rights reserved.
//
// Libraries Required:
// d3d9.lib dxguid.lib d3dx9dt.lib d3dxof.lib comctl32.lib winmm.lib dinput8.lib
//
// Local Files Required:
// main.cpp
// main.h
//
// DX Files:
// Copyright (c) 1997-2001 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "main.h"
//--------------------------------------------------------------------------------------
//
// Main windows function, ie main()
//
//--------------------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASSEX wndclass;
RECT rcWindowClient;
DWORD dwInputTimer = 0;
int iResult = 0;
// Set up window class
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = fnMessageProcessor;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "Map Editor Plus Demo"; // Registered Class Name
wndclass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
// Register the window class
if( RegisterClassEx( &wndclass ) == NULL )
{
// The program failed, exit
exit(1);
}
// Create the window
hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,
"Map Editor Plus Demo", // Class Name
"D3D_MapEditorPlus", // Name Displayed on Title Bar
WS_OVERLAPPEDWINDOW,
0,
0,
g_iWindowWidth,
g_iWindowHeight,
NULL,
NULL,
hInstance,
NULL );
// Store window handle globally for access later
g_hWnd = hWnd;
// Display the window
ShowWindow( hWnd, iCmdShow );
// Set the global instance of the program
g_hInstance = hInstance;
// Figure out the client work area
GetClientRect( hWnd, &rcWindowClient );
// Calculate the rendering offsets based on the client size
g_iXOffset = (g_iWindowWidth-(rcWindowClient.right-rcWindowClient.left));
g_iYOffset = (g_iWindowHeight-(rcWindowClient.bottom-rcWindowClient.top));
// Resize the window to be truely the resolution desired
SetWindowPos(
hWnd,
NULL,
0, // X-Pos
0, // Y-Pos
g_iWindowWidth + g_iXOffset, // Width
g_iWindowHeight + g_iYOffset, // Height
NULL);
// Clear out message structure
ZeroMemory( &msg, sizeof(msg) );
// Initialize Direct Input
iResult = iInitDirectInput();
if( iResult != INPUTERROR_SUCCESS ) {
MessageBox( hWnd, "DirectInput Error", "Unable to initialize Direct Input.", MB_ICONERROR );
vCleanup();
exit( 1 );
}
// Initialize DI Keyboard
iResult = iInitKeyboard(hWnd);
if( iResult != INPUTERROR_SUCCESS ) {
MessageBox( hWnd, "DirectInput Error", "Unable to initialize Keyboard.", MB_ICONERROR );
vCleanup();
exit( 1 );
}
// Initialize Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) ) {
// Initialize the virtual buffer for the display quad
vInitInterfaceObjects();
// Initialize the tile map
vInitMap();
// Initialize the toolbar
vCreateToolbar( hWnd, hInstance );
// Enter the message loop
while( msg.message!=WM_QUIT ) {
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else {
// Check if it is ok to process mouse clicks
if( timeGetTime() > dwInputTimer ) {
// Check for input
vCheckInput();
dwInputTimer = timeGetTime()+50;
}
// Render the scene
vRender();
}
}
}
// Clean up everything and exit the app
vCleanup();
UnregisterClass( "Map Editor Plus Demo", wndclass.hInstance );
return 0;
}
//--------------------------------------------------------------------------------------
//
// Windows message processor
//
//--------------------------------------------------------------------------------------
LRESULT WINAPI fnMessageProcessor( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_LBUTTONDOWN:
g_iLeftButtonDown = 1;
vCheckMouse();
break;
case WM_LBUTTONUP:
g_iLeftButtonDown = 0;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
// Check toolbar controls
case ID_BUTTON_PREVTILE:
vPreviousTile();
break;
case ID_BUTTON_NEXTTILE:
vNextTile();
break;
case ID_BUTTON_SAVE:
vSaveMap();
break;
case ID_BUTTON_LOAD:
vLoadMap();
break;
default:
break;
}
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//--------------------------------------------------------------------------------------
//
// Function to initialize Direct 3D
//
//--------------------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
D3DPRESENT_PARAMETERS d3dpp;
D3DXMATRIX matproj, matview;
D3DDISPLAYMODE d3ddm;
// Create the D3D object
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// Get the current desktop display mode, so we can set up a back
// buffer of the same format
if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;
// Setup the back buffer and swap format
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = FALSE;
// Create the D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
//---------------------------------------------
// Setup 2D View and Rendering States
//---------------------------------------------
D3DXMatrixIdentity( &matview );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matview );
// Setup orthographic rendering, ie 2D in 3D
D3DXMatrixOrthoLH( &matproj, (float)g_iWindowWidth, (float)g_iWindowHeight, 0, 1 );
// Setup the projection matrix
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matproj );
// Turn off culling
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn off lighting
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
// Turn off z-buffer
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
return S_OK;
}
//--------------------------------------------------------------------------------------
//
// Function to cleanup allocated objects
//
//--------------------------------------------------------------------------------------
void vCleanup( void )
{
// Free the vertex buffer
if( g_pVBInterface != NULL )
g_pVBInterface->Release();
// Free the 3D device
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
// Free Direct 3D
if( g_pD3D != NULL )
g_pD3D->Release();
}
//--------------------------------------------------------------------------------------
//
// Function to draw the 3D scene
//
//--------------------------------------------------------------------------------------
void vRender( void )
{
RECT rectText;
int iX;
int iY;
int iCurTile;
int iBufferPos;
char szOutput[ 256 ];
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Begin the scene
g_pd3dDevice->BeginScene();
//---------------------
//
// RENDER THE TILES
//
//---------------------
// Top to bottom
for( iY = 0; iY < g_iTilesHigh; iY++ ) {
// Left to right
for( iX = 0; iX < g_iTilesWide; iX++ ) {
// Calculate buffer offset
iBufferPos = iX+g_iXPos+((iY+g_iYPos)*g_iMapWidth);
// Get the proper tile
iCurTile = g_iTileMap[ iBufferPos ];
// Display the tile
vDrawInterfaceObject( ( iX * g_iTileSize ),
( iY * g_iTileSize ),
(float)g_iTileSize,
(float)g_iTileSize,
iCurTile );
}
}
// Draw the text
rectText.bottom = 50;
rectText.left = 0;
rectText.right = 640;
rectText.top = 0;
sprintf( szOutput, "X: %d, Y: %d, CurTile: %d (%d)",
g_iXPos, g_iYPos, g_iCurTile, g_iCurTileSet );
pD3DXFont->DrawText( szOutput, -1, &rectText,
DT_LEFT,
D3DCOLOR_RGBA(255, 255, 255, 255));
// End the scene
g_pd3dDevice->EndScene();
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//--------------------------------------------------------------------------------------
//
// Function to initialize the global interface object vertex buffer
//
// Uses the following global variables:
//
// g_pd3dDevice The Direct3D Device
// g_pVBInterface The Vertex buffer for the interface objects
// CUSTOMVERTEX The Vertex structure
// D3DFVF_CUSTOMVERTEX The Vertex format
// g_pTexture The Texture array to hold textures
//
//--------------------------------------------------------------------------------------
void vInitInterfaceObjects( void )
{
CUSTOMVERTEX *pVertices;
char szTileName[ 32 ];
// Create the interface object buffer
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVBInterface, NULL ) ) )
{
return;
}
// Lock the buffer for editing
if( FAILED( g_pVBInterface->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
return;
//
// Create a quad made up of 3 vertices (triangle strips)
//
// 1 3
// X--------X
// |x |
// | x |
// | x |
// | x |
// | x |
// | x |
// | x |
// | x|
// X--------X
// 0 2
//
pVertices[0].position = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
pVertices[0].tu = 0.0f;
pVertices[0].tv = 1.0f;
pVertices[0].tu2 = 0.0f;
pVertices[0].tv2 = 1.0f;
pVertices[0].vecNorm = D3DXVECTOR3(0.0f,0.0f,1.0f);
pVertices[1].position = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
pVertices[1].tu = 0.0f;
pVertices[1].tv = 0.0f;
pVertices[1].tu2 = 0.0f;
pVertices[1].tv2 = 0.0f;
pVertices[1].vecNorm = D3DXVECTOR3(0.0f,0.0f,1.0f);
pVertices[2].position = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
pVertices[2].tu = 1.0f;
pVertices[2].tv = 1.0f;
pVertices[2].tu2 = 1.0f;
pVertices[2].tv2 = 1.0f;
pVertices[2].vecNorm = D3DXVECTOR3(0.0f,0.0f,1.0f);
pVertices[3].position = D3DXVECTOR3( 1.0f, 1.0f, 0.0f );
pVertices[3].tu = 1.0f;
pVertices[3].tv = 0.0f;
pVertices[3].tu2 = 1.0f;
pVertices[3].tv2 = 0.0f;
pVertices[3].vecNorm = D3DXVECTOR3(0.0f,0.0f,1.0f);
// Done editing, unlock the buffer
g_pVBInterface->Unlock();
//---------------------------------------------
// LOAD TEXTURES
//---------------------------------------------
// Load the tiles
for( int i = 0; i < 18; i++ ) {
// Set the name
sprintf( szTileName, "tile%d.tga", i );
// Load it
if( FAILED( D3DXCreateTextureFromFile(
g_pd3dDevice,
szTileName,
&g_pTexture[ i ] ) ) ) {
return;
}
}
// Load the tile overlay
if( FAILED( D3DXCreateTextureFromFile(
g_pd3dDevice,
"overlay.tga",
&g_pTexture[ 18 ] ) ) ) {
return;
}
// Text Font
hFont = CreateFont(
16, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, PROOF_QUALITY,
0, "fixedsys" );
// Create the Direct3D Font
D3DXCreateFont( g_pd3dDevice, hFont, &pD3DXFont );
};
//--------------------------------------------------------------------------------------
//
// Function to draw a 3D object in 2D space
//
// iXPos = x-position in screen-space of the top-left corner of the object
// iYPos = y-position in screen-space of the top-left corner of the object
// fXSize = Width of the object in screen-space (pixels)
// fYSize = Height of the object in screen-space (pixels)
// iTexture = Index into the texture array of object to draw
//
//--------------------------------------------------------------------------------------
void vDrawInterfaceObject( int iXPos, int iYPos, float fXSize, float fYSize, int iTexture )
{
D3DXMATRIX matWorld, matRotation, matTranslation, matScale;
float fXPos, fYPos;
// Set default position,scale,rotation
D3DXMatrixIdentity( &matTranslation );
// Scale the sprite
D3DXMatrixScaling( &matScale, fXSize, fYSize, 1.0f );
D3DXMatrixMultiply( &matTranslation, &matTranslation, &matScale );
// Rotate the sprite
D3DXMatrixRotationZ( &matRotation, 0.0f );
D3DXMatrixMultiply( &matWorld, &matTranslation, &matRotation );
// Calculate the position in screen-space
fXPos = (float)(-(g_iWindowWidth/2)+iXPos);
fYPos = (g_iWindowHeight/2)-fYSize-iYPos;
// Move the sprite
matWorld._41 = fXPos; // X
matWorld._42 = fYPos; // Y
// Set matrix
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->SetTexture( 0, g_pTexture[ iTexture ] );
g_pd3dDevice->SetStreamSource( 0, g_pVBInterface, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
// Dereference texture
g_pd3dDevice->SetTexture(0, NULL);
}
//--------------------------------------------------------------------------------------
//
// Function to initialize the map
//
//--------------------------------------------------------------------------------------
void vInitMap( void )
{
int i;
// Clear the map
for( i = 0; i < g_iMapWidth * g_iMapHeight; i++ ) {
g_iTileMap[ i ] = 1;
// Randomly place rocks
if( rand()%10 == 5 ) {
g_iTileMap[ i ] = 2;
}
}
}
//-----------------------------------------------------------------------------
//
// Initializes the DirectInput system
//
//-----------------------------------------------------------------------------
int iInitDirectInput(void)
{
HRESULT hReturn;
// Do not try to create Direct Input if already created
if( !pDI ) {
// Create a DInput object
if( FAILED( hReturn = DirectInput8Create(
g_hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&pDI, NULL ) ) ) {
return( INPUTERROR_NODI );
}
}
else {
return( INPUTERROR_KEYBOARDEXISTS );
}
return( INPUTERROR_SUCCESS );
}
//-----------------------------------------------------------------------------
//
// Reads the keyboard data buffer for input actions
//
//-----------------------------------------------------------------------------
int iInitKeyboard(HWND hWnd)
{
HRESULT hReturn = 0;
DIPROPDWORD dipdw;
// Don't try to create the keyboard twice
if( pKeyboard ) {
return( INPUTERROR_KEYBOARDEXISTS );
}
// Exit out if no Direct Input interface found
else if ( !pDI ) {
return( INPUTERROR_NODI );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -