#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")
struct CUSTOM_VERTEX
{
float X, Y, Z;
DWORD Color;
};
#define CUSTOM_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE)
const float PI = 3.141592654f;
const float FOV = PI / 4.0f;
const float ASPECT_RATIO = 4.0f / 3.0f;
const float NEAR_Z = 1.0f;
const float FAR_Z = 10000.0f;
HWND hWnd;
MSG msg;
HINSTANCE hInstance;
int Width;
int Height;
LPDIRECT3D9 D3D;
LPDIRECT3DDEVICE9 Device;
D3DDISPLAYMODE Display_Mode;
D3DPRESENT_PARAMETERS Screen;
LPDIRECTINPUT8 DI;
LPDIRECTINPUTDEVICE8 Mouse_Device;
DIMOUSESTATE Mouse_State;
D3DXVECTOR2 Mouse;
LPDIRECTINPUTDEVICE8 Keyboard_Device;
BYTE Keyboard_State[256];
CUSTOM_VERTEX Vertex_List[4];
D3DXMATRIX View_Matrix;
D3DXMATRIX Projection_Matrix;
D3DVECTOR Camera_Position;
D3DVECTOR Camera_Angle;
bool Fullscreen_Enabled;
bool Running;
void DirectX_Initialize(void);
void DirectInput_Initialize(void);
void DirectInput_Initialize_Mouse(void);
void Mouse_Controls(void);
void DirectInput_Initialize_Keyboard(void);
bool DirectInput_Key_State(void);
void Keyboard_Controls(void);
void Settings(void);
D3DXVECTOR3 Create_Vertex(void);
CUSTOM_VERTEX Create_Custom_Vertex(void);
void Setup_Matrices(void);
void Camera_Control(void);
void Create_Polygon(void);
void Draw_Polygon(void);
void Create_Platform(void);
void Render(void);
void Game_Loop(void);
void Main(void);
void Shutdown(void);
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void DirectX_Initialize()
{
D3D = Direct3DCreate9(D3D_SDK_VERSION);
memset(&Screen, 0, sizeof(D3DPRESENT_PARAMETERS));
if (Fullscreen_Enabled == true)
{
Display_Mode.Width = 800;
Display_Mode.Height = 600;
Display_Mode.Format = D3DFMT_R5G6B5;
Screen.Windowed = FALSE;
Screen.BackBufferCount = 1;
Screen.BackBufferWidth = Display_Mode.Width;
Screen.BackBufferHeight = Display_Mode.Height;
Screen.hDeviceWindow = hWnd;
}
else
{
D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Display_Mode);
Screen.Windowed = TRUE;
}
Screen.SwapEffect = D3DSWAPEFFECT_DISCARD;
Screen.BackBufferFormat = D3DFMT_R5G6B5;
Screen.EnableAutoDepthStencil = TRUE;
Screen.AutoDepthStencilFormat = D3DFMT_D16;
D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &Screen, &Device);
}
void DirectInput_Initialize()
{
DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DI, NULL);
}
void DirectInput_Initialize_Mouse()
{
DI->CreateDevice(GUID_SysMouse, &Mouse_Device, NULL);
Mouse_Device->SetDataFormat(&c_dfDIMouse);
Mouse_Device->SetCooperativeLevel(hWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
Mouse_Device->Acquire();
}
void Mouse_Controls()
{
Mouse_Device->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&Mouse_State);
Mouse.x += Mouse_State.lX;
Mouse.y += Mouse_State.lY;
if (Mouse.x > Width) Mouse.x = (float)Width;
if (Mouse.y < 0) Mouse.x = 0;
if (Mouse.x > Height) Mouse.y = (float)Height;
if (Mouse.y < 0) Mouse.y = 0;
Camera_Angle.x += Mouse_State.lY;
Camera_Angle.y += Mouse_State.lX;
if (Camera_Angle.x >= 90) Camera_Angle.x = 90;
if (Camera_Angle.x <= -90) Camera_Angle.x = -90;
}
void DirectInput_Initialize_Keyboard()
{
DI->CreateDevice(GUID_SysKeyboard, &Keyboard_Device, NULL);
Keyboard_Device->SetDataFormat(&c_dfDIKeyboard);
Keyboard_Device->SetCooperativeLevel(hWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
Keyboard_Device->Acquire();
}
bool DirectInput_Key_State(int Key_Code)
{
Keyboard_Device->GetDeviceState(256, (LPVOID)Keyboard_State);
return Keyboard_State[Key_Code] && 0x80;
}
void Keyboard_Controls()
{
const int Camera_Speed = 5;
if (DirectInput_Key_State(DIK_W))
{
Camera_Position.x -= (float)sin(Camera_Angle.y * PI / 180) * Camera_Speed;
Camera_Position.z -= (float)cos(Camera_Angle.y * PI / 180) * Camera_Speed;
}
if (DirectInput_Key_State(DIK_S))
{
Camera_Position.x += (float)sin(Camera_Angle.y * PI / 180) * Camera_Speed;
Camera_Position.z += (float)cos(Camera_Angle.y * PI / 180) * Camera_Speed;
}
if (DirectInput_Key_State(DIK_A))
{
Camera_Position.x += (float)cos(Camera_Angle.y * PI / 180) * Camera_Speed;
Camera_Position.z -= (float)sin(Camera_Angle.y * PI / 180) * Camera_Speed;
}
if (DirectInput_Key_State(DIK_D))
{
Camera_Position.x -= (float)cos(Camera_Angle.y * PI / 180) * Camera_Speed;
Camera_Position.z += (float)sin(Camera_Angle.y * PI / 180) * Camera_Speed;
}
if (DirectInput_Key_State(DIK_Q))
{
Camera_Angle.y -= 1;
}
if (DirectInput_Key_State(DIK_E))
{
Camera_Angle.y += 1;
}
if (DirectInput_Key_State(DIK_R))
{
Camera_Angle.x -= 1;
}
if (DirectInput_Key_State(DIK_F))
{
Camera_Angle.x += 1;
}
if (DirectInput_Key_State(DIK_C))
{
Camera_Position.y -= Camera_Speed;
}
if (DirectInput_Key_State(DIK_Z))
{
Camera_Position.y += Camera_Speed;
}
}
void Settings()
{
Device->SetRenderState(D3DRS_ZENABLE, TRUE);
Device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
Device->SetRenderState(D3DRS_LIGHTING, FALSE);
}
D3DXVECTOR3 Create_Vertex(float X, float Y, float Z)
{
D3DXVECTOR3 Vertex;
Vertex.x = X;
Vertex.y = Y;
Vertex.z = Z;
return Vertex;
}
CUSTOM_VERTEX Create_Custom_Vertex(float X, float Y, float Z, DWORD Color)
{
CUSTOM_VERTEX Vertex;
Vertex.X = X;
Vertex.Y = Y;
Vertex.Z = Z;
Vertex.Color = Color;
return Vertex;
}
void Setup_Matrices()
{
D3DXMatrixLookAtRH(&View_Matrix, &Create_Vertex(Camera_Position.x, Camera_Position.y, Camera_Position.z), &Create_Vertex(0, 0, 0), &Create_Vertex(0.0f, 1.0f, 0.0f));
Device->SetTransform(D3DTS_VIEW, &View_Matrix);
D3DXMatrixPerspectiveFovRH(&Projection_Matrix, FOV, ASPECT_RATIO, NEAR_Z, FAR_Z);
Device->SetTransform(D3DTS_PROJECTION, &Projection_Matrix);
}
void Camera_Control()
{
D3DXMATRIX Camera_Translation_Matrix;
D3DXMATRIX Camera_Angle_Matrix_X;
D3DXMATRIX Camera_Angle_Matrix_Y;
D3DXMatrixIdentity(&View_Matrix);
D3DXMatrixIdentity(&Camera_Translation_Matrix);
D3DXMatrixTranslation(&Camera_Translation_Matrix, Camera_Position.x, Camera_Position.y, -Camera_Position.z);
D3DXMatrixMultiply(&View_Matrix, &View_Matrix, &Camera_Translation_Matrix);
D3DXMatrixRotationY(&Camera_Angle_Matrix_Y, (PI * Camera_Angle.y) / 180);
D3DXMatrixMultiply(&View_Matrix, &View_Matrix, &Camera_Angle_Matrix_Y);
D3DXMatrixRotationX(&Camera_Angle_Matrix_X, (PI * Camera_Angle.x) / 180);
D3DXMatrixMultiply(&View_Matrix, &View_Matrix, &Camera_Angle_Matrix_X);
Device->SetTransform(D3DTS_VIEW, &View_Matrix);
}
void Create_Polygon()
{
Vertex_List[0] = Create_Custom_Vertex(-50.0f, 100.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255));
Vertex_List[1] = Create_Custom_Vertex(50.0f, 100.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255));
Vertex_List[2] = Create_Custom_Vertex(-50.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255));
Vertex_List[3] = Create_Custom_Vertex(50.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255));
}
void Draw_Polygon()
{
Device->SetFVF(CUSTOM_VERTEX_FORMAT);
Device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, Vertex_List, sizeof(CUSTOM_VERTEX));
}
void Create_Platform()
{
Vertex_List[0] = Create_Custom_Vertex(-1000.0f, 0.0f, -1000.0f, D3DCOLOR_XRGB(255, 0, 0));
Vertex_List[1] = Create_Custom_Vertex(1000.0f, 0.0f, -1000.0f, D3DCOLOR_XRGB(0, 255, 0));
Vertex_List[2] = Create_Custom_Vertex(-1000.0f, 0.0f, 1000.0f, D3DCOLOR_XRGB(0, 0, 255));
Vertex_List[3] = Create_Custom_Vertex(1000.0f, 0.0f, 1000.0f, D3DCOLOR_XRGB(255, 0, 255));
}
void Render()
{
Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
Device->BeginScene();
//Rendering code goes here
Create_Polygon();
Draw_Polygon();
Create_Platform();
Draw_Polygon();
Device->EndScene();
Device->Present(NULL, NULL, NULL, NULL);
}
void Game_Loop()
{
while (Running == true)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE) > 0)
{
if (WM_QUIT == msg.message) break;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
else
{
Mouse_Controls();
Keyboard_Controls();
Camera_Control();
Render();
if (DirectInput_Key_State(DIK_ESCAPE)) DestroyWindow(hWnd);
}
}
}
void Main()
{
Camera_Position.x = 0.0f;
Camera_Position.y = -50.0f;
Camera_Position.z = 250.0f;
DirectX_Initialize();
DirectInput_Initialize();
DirectInput_Initialize_Mouse();
DirectInput_Initialize_Keyboard();
Settings();
Setup_Matrices();
Running = true;
}
void Shutdown()
{
if (Running == true)
{
Running = false;
Mouse_Device->Unacquire();
Mouse_Device->Release();
Keyboard_Device->Unacquire();
Keyboard_Device->Release();
Device->Release();
D3D->Release();
PostQuitMessage (0);
HANDLE Process;
Process = OpenProcess(PROCESS_ALL_ACCESS , true , GetCurrentProcessId());
TerminateProcess(Process , 0);
}
}
int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC, WindowProcedure, 0, 0, hinstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "DX_TUT", NULL};
RegisterClassEx(&wc);
if (MessageBox(hWnd, "Click Yes to go to fullscreen (Recommended)", "", MB_ICONQUESTION | MB_YESNO) == IDYES)
Fullscreen_Enabled = true;
if (Fullscreen_Enabled == true)
hWnd = CreateWindowEx (0, "DX_TUT", "DirectX Tutorial", WS_VISIBLE | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 330, 250, HWND_DESKTOP, NULL, hinstance, NULL);
else
hWnd = CreateWindowEx (0, "DX_TUT", "DirectX Tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 330, 250, HWND_DESKTOP, NULL, hinstance, NULL);
hInstance = hinstance;
ShowWindow (hWnd, nCmdShow);
if (Fullscreen_Enabled == true)
{
Width = 800;
Height = 600;
}
else
{
Width = 330;
Height = 250;
}
Main();
Game_Loop();
return msg.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
Shutdown();
break;
default:
return DefWindowProc (hWnd, msg, wParam, lParam);
}
return 0;
}