//
#include "stdafx.h"
#include "DirectX1.h"
#include <d3d9.h>
#include <d3dx9.h>
#include <Windows.h>
#include "Cuboid.h"
#include "Terrain.h"
#include "Sphere.h"
#include "Panel.h"
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertextBuffer = NULL;
LPD3DXMESH g_pMesh = NULL;
D3DMATERIAL9 g_material;
CCuboid* g_pCube = NULL;
CTerrain* g_pTerrain = NULL;
CSphere* g_pSphere = NULL;
LPD3DXFONT g_pFont = NULL;
CPanel* g_pPanel = NULL;
float zoom = 0;
char text[256] = {};
DWORD dwTime = 0;
DWORD dwCount = 0;
DWORD dwPreCount = 0;
//BYTE, WORD, DWORD
struct MY_VERTEX
{
float x, y, z, rhw;
DWORD color;
};
#define D3DFVF_MYVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
HWND g_HWnd = NULL;
#define MAX_LOADSTRING 100
// 전역 변수:
HINSTANCE hInst; // 현재 인스턴스입니다.
WCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.
// 이 코드 모듈에 들어 있는 함수의 정방향 선언입니다.
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
HRESULT InitVertextBuffer()
{
g_pPanel = new CPanel(g_pD3DDevice, 256, 64, 800, 600);
g_pPanel->SetTexture("EnergyBar.bmp", D3DCOLOR_XRGB(0,0,0));
//HFONT hFont = CreateFont(FW_NORMAL, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, L"Arial");
D3DXCreateFont(g_pD3DDevice, 60, 0, FW_NORMAL, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, VARIABLE_PITCH, L"Arial", &g_pFont);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(32, 32, 32));
D3DLIGHT9 light;
memset(&light, 0, sizeof(light));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 0.7f;
light.Diffuse.g = 0.7f;
light.Diffuse.b = 0.7f;
light.Diffuse.a = 0.7f;
light.Ambient.r = 0.2f;
light.Ambient.g = 0.2f;
light.Ambient.b = 0.2f;
light.Specular.r = 1.0f;
light.Specular.g = 0.0f;
light.Specular.b = 0.0f;
light.Direction.x = 0;
light.Direction.y = -0.8f;
light.Direction.z = 0.8f;
light.Position.x = 0;
light.Position.y = 10.0f;
light.Position.z = -10.0f;
light.Phi = D3DX_PI * 2.0f;
light.Theta = D3DX_PI / 4.0f;
light.Falloff = D3DX_PI;
light.Attenuation0 = 1.0f;
light.Range = 100.0f;
g_pD3DDevice->SetLight(0, &light);
g_pD3DDevice->LightEnable(0, TRUE);
D3DCOLORVALUE dif = { 1.0f,1.0f,1.0f,0.0f };
D3DCOLORVALUE amb = { 1.0f,1.0f,1.0f,0.0f };
D3DCOLORVALUE spe = { 1.0f,1.0f,1.0f,1.0f };
D3DCOLORVALUE emi = { 0,0,0,0 };
g_material.Diffuse = dif;
g_material.Ambient = amb;
g_material.Emissive = emi;
g_material.Specular = spe;
g_material.Power = 0;
//return D3DXCreateSphere(g_pD3DDevice, 2,100,100, &g_pMesh, NULL);
g_pCube = new CCuboid(g_pD3DDevice);
//g_pCube->SetSize(2, 2, 2);
g_pCube->SetTexture("1.bmp");
g_pTerrain = new CTerrain(g_pD3DDevice, 20, 20, 10.0f, 15.0f);
g_pTerrain->SetTexture("Grass.bmp");
g_pSphere = new CSphere(g_pD3DDevice, 20.0f, 20.0f);
g_pSphere->SetTexture("2.jpg");
return 1;
//return D3DXCreateTeapot(g_pD3DDevice, &g_pMesh, NULL);
}
void makeCamera()
{
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0, zoom, zoom),
&D3DXVECTOR3(0, 0, 0),
&D3DXVECTOR3(0, 1, 0));
if (zoom <= 0)
zoom = 10;
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f, 2.0f, 1.0f, 5000.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
void Setup2DCamera() {
D3DXMATRIX matOrtho;
D3DXMATRIX matIdentity;
D3DXMatrixOrthoLH(&matOrtho, 1024, 768, 0, 1.0f);
D3DXMatrixIdentity(&matIdentity);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matIdentity);
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matIdentity);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
}
void Render()
{
if (g_pD3DDevice == NULL)
return;
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
g_pD3DDevice->BeginScene();
makeCamera();
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &mat);
g_pSphere->Render();
RECT rect;
rect.left = 100;
rect.top = 100;
rect.right = 1000;
rect.bottom = 1000;
DWORD dwNowTime = GetTickCount(); // 현재시간을 가져온다
float temp = (float)(dwNowTime - dwTime) / 1000.0f; // 1초마다 계산
temp = 1.0f / temp;
dwTime = GetTickCount();
char text[256] = {};
sprintf_s(text, "%.2f", temp);
g_pFont->DrawTextA(NULL, text, -1, &rect, DT_LEFT, D3DCOLOR_XRGB(255,255,255,255));
Setup2DCamera();
g_pPanel->MoveTo(600,50);
g_pPanel->Render();
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(0, 0, 0, 0);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 여기에 코드를 입력합니다.
// 전역 문자열을 초기화합니다.
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_DIRECTX1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 응용 프로그램 초기화를 수행합니다.
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));
//ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pD3DDevice);
InitVertextBuffer();
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DIRECTX1));
MSG msg;
msg.message = 0;
BOOL fMessage = FALSE;
// 기본 메시지 루프입니다.
while (msg.message != WM_QUIT)
{
fMessage = PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE);
if (fMessage)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
return (int) msg.wParam;
}
//
// 함수: MyRegisterClass()
//
// 목적: 창 클래스를 등록합니다.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DIRECTX1));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_DIRECTX1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// 함수: InitInstance(HINSTANCE, int)
//
// 목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
// 설명:
//
// 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
// 주 프로그램 창을 만든 다음 표시합니다.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
g_HWnd = hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 목적: 주 창의 메시지를 처리합니다.
//
// WM_COMMAND - 응용 프로그램 메뉴를 처리합니다.
// WM_PAINT - 주 창을 그립니다.
// WM_DESTROY - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 메뉴 선택을 구문 분석합니다.
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다.
EndPaint(hWnd, &ps);
}
break;
case WM_MOUSEWHEEL: // 휠올리면 멀어지고 내리면 가까워지고
{
((short)HIWORD(wParam)<0) ? zoom -= 20 : zoom += 20;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYUP:
{
switch (wParam)
{
case VK_ESCAPE:
DestroyWindow(hWnd);
return 0;
}
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 정보 대화 상자의 메시지 처리기입니다.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}