VioletaBabel
DirectX - 1 본문
DirectX
GDI를 통하지 않고 그래픽카드로 바로 메세지를 꽂아주기 위해 만들어진 것이 DirectX.
Window 운영체제에서 Window Handle[HWND]이라는 창을 만든다.
HINSTANCE도 들어가 있다.
제일 처음엔 WinMain이란 함수가 불리고, 안에는 메세지 프로시저가 들어가있고, 무한 루프가 돌면서 기존은 Idle로 있다가 메세지가 오면 처리하는 방식으로 한다.
DirectXTest라는 프로젝트를 만들고, 윈도우 데스크탑 응용 프로그램으로 만든다.
그리고 해당 프로젝트의 리소스 폴더의 DirectXTest.rc 파일을 연다.
Accelerator 폴더 : 단축키
String Table 폴더 : 문자열 (타이틀 등)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | // 181126_DirectXTest.cpp : 응용 프로그램에 대한 진입점을 정의합니다. // #include "stdafx.h" #include "181126_DirectXTest.h" #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); 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); // 윈도우에서 IDS_APP_TITLE이라는 아이디를 가진 문자열을 szTitle에 넣어라. (rc파일의 String Table에 지정되어있음) LoadStringW(hInstance, IDC_MY181126DIRECTXTEST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 여기까지가 윈도우를 만들어 등록하는 과정. // 응용 프로그램 초기화를 수행합니다: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY181126DIRECTXTEST)); MSG msg; // 기본 메시지 루프입니다: while (GetMessage(&msg, nullptr, 0, 0)) // 디스트로이가 오면 메세지가 Null이 되어 루프가 끝이 난다. //while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // 겟 메세지는 메세지가 오지 않으면 슬립이 된다. 그래서 게임은 계속 돌아가야 하므로 PeekMessage로 바꿔준다 { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 함수: MyRegisterClass() // // 용도: 창 클래스를 등록합니다. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; // WND는 윈도우, EX는 확장, W는 리바이트 문자열을 뜻함. 구조체를 만들었. 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_MY181126DIRECTXTEST)); // 윈도우에 있는 아이콘을 불러와줌 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // 커서는 기본 화살표 커서 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 윈도우의 백그라운드 컬러 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_MY181126DIRECTXTEST); // 메뉴의 이름. 역시 아까 String Table에서 설정한 바로 나옴 wcex.lpszClassName = szWindowClass; // 클래스 이름. 역시 string table. 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; } 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) // 윈도우에서 호출해주면 받는 콜백 함수. 리턴은 주소. {//핸들, 메세지, 파라미터 2개를 받음 switch (message) { case WM_COMMAND: {//일반적인 명령은 다 여기 int wmId = LOWORD(wParam); // 메뉴 선택을 구문 분석합니다: switch (wmId) { case IDM_ABOUT: //해당 ID에 따라 처리하는 일이 달라짐. 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_DESTROY://종-료 PostQuitMessage(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; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #include "stdafx.h" #include <windows.h> #include <windowsx.h> #include <d3d11.h> // Direct에 쓰이는 기본적인 것들. 그래픽 카드와 통신하는 부분. #include <d3dx11.h> // 수학이나 계산 등과, (비교적) 편리하게 쓸 수 있도록 만든 것들을 모아둔 곳. #include <d3dx10.h> // include the Direct3D Library file #pragma comment (lib, "d3d11.lib") // lib와 dll의 차이. dll은 dynamic linked library. 정적 라이브러리와 동적 라이브러리의 차이이다. #pragma comment (lib, "d3dx11.lib") // lib는 전체 코드를 포함하는 바이너리이다. exe 파일 자체가 커지는 단점이 있으나 속도가 빠르고 이식성이 좋으며 안정적. #pragma comment (lib, "d3dx10.lib") // dll은 함수명(함수 정보)를 제공한다. 메모리 절약, 소스 외부 유출이 방지. 허나 이식성이 어렵고 속도 저하가 생김. // global declarations IDXGISwapChain *swapchain; // the pointer to the swap chain interface // 화면에 하드웨어적으로 출력되는 프론트 버퍼와 렌더가 일어나는 백 버퍼들이 순차적으로 연결된 프레임 버퍼들의 집합 ID3D11Device *dev; // the pointer to our Direct3D device interface ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context // function prototypes void InitD3D(HWND hWnd); // sets up and initializes Direct3D void CleanD3D(void); // closes Direct3D and releases memory // the WindowProc function prototype LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the entry point for any Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = L"WindowClass"; RegisterClassEx(&wc); RECT wr = { 0, 0, 800, 600 }; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our First Direct3D Program", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); // set up and initialize Direct3D InitD3D(hWnd); // enter the main loop: MSG msg; while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (msg.message == WM_QUIT) break; } else { // Run game code here // ... // ... } } // clean up DirectX and COM CleanD3D(); return msg.wParam; } // this is the main message handler for the program LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; } return DefWindowProc(hWnd, message, wParam, lParam); } // this function initializes and prepares Direct3D for use void InitD3D(HWND hWnd) { // create a struct to hold information about the swap chain DXGI_SWAP_CHAIN_DESC scd; // 스왑체인 만든다 // clear out the struct for use ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // 크기 잡는다 // fill the swap chain description struct scd.BufferCount = 1; // one back buffer scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color // 색상 scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used scd.OutputWindow = hWnd; // the window to be used scd.SampleDesc.Count = 4; // how many multisamples // 스왑체인 몇 개 할거냐 scd.Windowed = TRUE; // windowed/full-screen mode // create a device, device context and swap chain using the information in the scd struct D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon); } // this is the function that cleans up Direct3D and COM void CleanD3D(void) { // close and release all existing COM objects swapchain->Release(); dev->Release(); devcon->Release(); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | // include the basic windows header files and the Direct3D header files #include <windows.h> #include <windowsx.h> #include <d3d11.h> #include <d3dx11.h> #include <d3dx10.h> // include the Direct3D Library file #pragma comment (lib, "d3d11.lib") #pragma comment (lib, "d3dx11.lib") #pragma comment (lib, "d3dx10.lib") // global declarations IDXGISwapChain *swapchain; // the pointer to the swap chain interface ID3D11Device *dev; // the pointer to our Direct3D device interface ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer // function prototypes void InitD3D(HWND hWnd); // sets up and initializes Direct3D void RenderFrame(void); // renders a single frame void CleanD3D(void); // closes Direct3D and releases memory // the WindowProc function prototype LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the entry point for any Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = L"WindowClass"; RegisterClassEx(&wc); RECT wr = { 0, 0, 800, 600 }; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our First Direct3D Program", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); // set up and initialize Direct3D InitD3D(hWnd); // enter the main loop: MSG msg; while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (msg.message == WM_QUIT) break; } RenderFrame(); } // clean up DirectX and COM CleanD3D(); return msg.wParam; } // this is the main message handler for the program LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; } return DefWindowProc(hWnd, message, wParam, lParam); } // this function initializes and prepares Direct3D for use void InitD3D(HWND hWnd) { // create a struct to hold information about the swap chain DXGI_SWAP_CHAIN_DESC scd; // clear out the struct for use ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // fill the swap chain description struct scd.BufferCount = 1; // one back buffer scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used scd.OutputWindow = hWnd; // the window to be used scd.SampleDesc.Count = 1; // how many multisamples scd.SampleDesc.Quality = 0; // multisample quality level scd.Windowed = TRUE; // windowed/full-screen mode // create a device, device context and swap chain using the information in the scd struct D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon); // get the address of the back buffer ID3D11Texture2D *pBackBuffer; swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); // 그래픽 카드의 메모리를 얻어오는 곳. // use the back buffer address to create the render target dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer); pBackBuffer->Release(); // set the render target as the back buffer devcon->OMSetRenderTargets(1, &backbuffer, NULL); // 메모리를 날려 줌. // Set the viewport D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); // 메모리를 초기화 viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = 800; //뷰포트를 800x600으로 잡음 viewport.Height = 600; devcon->RSSetViewports(1, &viewport); } // this is the function used to render a single frame void RenderFrame(void) { // clear the back buffer to a deep blue devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f)); // 백버퍼로 초기화, 그리고 칼라를 넣어줌. // do 3D rendering on the back buffer here // switch the back buffer and the front buffer swapchain->Present(0, 0); } // this is the function that cleans up Direct3D and COM void CleanD3D(void) { // close and release all existing COM objects swapchain->Release(); backbuffer->Release(); dev->Release(); devcon->Release(); // 프로그램 종료가 아닌, 릴리즈를 불러줘야 메모리에서 사라짐 } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | // include the basic windows header files and the Direct3D header files #include "stdafx.h" #include <windows.h> #include <windowsx.h> #include <d3d11.h> #include <d3dx11.h> #include <d3dx10.h> // include the Direct3D Library file #pragma comment (lib, "d3d11.lib") #pragma comment (lib, "d3dx11.lib") #pragma comment (lib, "d3dx10.lib") // define the screen resolution #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 // global declarations IDXGISwapChain *swapchain; // the pointer to the swap chain interface ID3D11Device *dev; // the pointer to our Direct3D device interface ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer ID3D11InputLayout *pLayout; // the pointer to the input layout ID3D11VertexShader *pVS; // the pointer to the vertex shader ID3D11PixelShader *pPS; // the pointer to the pixel shader ID3D11Buffer *pVBuffer; // the pointer to the vertex buffer // a struct to define a single vertex struct VERTEX { FLOAT X, Y, Z; D3DXCOLOR Color; }; // function prototypes void InitD3D(HWND hWnd); // sets up and initializes Direct3D void RenderFrame(void); // renders a single frame void CleanD3D(void); // closes Direct3D and releases memory void InitGraphics(void); // creates the shape to render void InitPipeline(void); // loads and prepares the shaders // the WindowProc function prototype LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the entry point for any Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = L"WindowClass"; RegisterClassEx(&wc); RECT wr = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our First Direct3D Program", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); // set up and initialize Direct3D InitD3D(hWnd); // enter the main loop: MSG msg; while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (msg.message == WM_QUIT) break; } RenderFrame(); // 매 프레임마다 렌더프레임을 불러줌. } // clean up DirectX and COM CleanD3D(); return msg.wParam; } // this is the main message handler for the program LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; } return DefWindowProc(hWnd, message, wParam, lParam); } // this function initializes and prepares Direct3D for use void InitD3D(HWND hWnd) { // create a struct to hold information about the swap chain DXGI_SWAP_CHAIN_DESC scd; // clear out the struct for use ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // fill the swap chain description struct scd.BufferCount = 1; // one back buffer scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color scd.BufferDesc.Width = SCREEN_WIDTH; // set the back buffer width scd.BufferDesc.Height = SCREEN_HEIGHT; // set the back buffer height scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used scd.OutputWindow = hWnd; // the window to be used scd.SampleDesc.Count = 4; // how many multisamples scd.Windowed = TRUE; // windowed/full-screen mode scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching // create a device, device context and swap chain using the information in the scd struct D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon); // get the address of the back buffer ID3D11Texture2D *pBackBuffer; swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); // use the back buffer address to create the render target dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer); pBackBuffer->Release(); // set the render target as the back buffer devcon->OMSetRenderTargets(1, &backbuffer, NULL); // Set the viewport D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = SCREEN_WIDTH; viewport.Height = SCREEN_HEIGHT; devcon->RSSetViewports(1, &viewport); InitPipeline(); // 파이프라인을 초기화 InitGraphics(); // 그래픽 초기화 } // this is the function used to render a single frame void RenderFrame(void) { // clear the back buffer to a deep blue devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f)); // select which vertex buffer to display UINT stride = sizeof(VERTEX); UINT offset = 0; devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset); // 버텍스를 넣어준다 // select which primtive type we are using devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 일반적인 삼각형을 그림 // draw the vertex buffer to the back buffer devcon->Draw(3, 0); // 점 3개를 그림 // switch the back buffer and the front buffer swapchain->Present(0, 0); // 프론트 버퍼랑 셋 버퍼 } // this is the function that cleans up Direct3D and COM void CleanD3D(void) { swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode // close and release all existing COM objects pLayout->Release(); pVS->Release(); pPS->Release(); pVBuffer->Release(); swapchain->Release(); backbuffer->Release(); dev->Release(); devcon->Release(); } // this is the function that creates the shape to render void InitGraphics() { // create a triangle using the VERTEX struct VERTEX OurVertices[] = { {0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, {0.45f, -0.5, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)}, {-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)} }; // create the vertex buffer // 버텍스 버퍼를 만듦. 셰이더에 집어넣어줌 D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU bd.ByteWidth = sizeof(VERTEX) * 3; // size is the VERTEX struct * 3 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer // 버텍스 버퍼랑 바인드 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer // CPU에 쓰겠다 dev->CreateBuffer(&bd, NULL, &pVBuffer); // create the buffer // copy the vertices into the buffer D3D11_MAPPED_SUBRESOURCE ms; devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer // 그래픽 카드의 메모리를 잠근다. memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data // 만든 버텍스 버퍼를 넣는다. devcon->Unmap(pVBuffer, NULL); // unmap the buffer //메모리 잠근 것을 풀어준다. } // this function loads and prepares the shaders void InitPipeline() { // load and compile the two shaders ID3D10Blob *VS, *PS; D3DX11CompileFromFile(L"shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, 0, 0); // 문자열에 L이 붙는 건 유니코드 D3DX11CompileFromFile(L"shaders.shader", 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, 0, 0); // encapsulate both shaders into shader objects dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS); dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS); // set the shader objects devcon->VSSetShader(pVS, 0, 0); // vShader를 0번째부터 0번 ID에 넣겠다 devcon->PSSetShader(pPS, 0, 0); // create the input layout object D3D11_INPUT_ELEMENT_DESC ied[] = { // 구조체의 내용과 그릴 내용(포지션, 컬러)을 일치 시킴 {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout); devcon->IASetInputLayout(pLayout); } | cs |
'기본개념 > 분류가 애매한거' 카테고리의 다른 글
버니 킹덤 점수 계산기 (미완) (0) | 2018.12.22 |
---|---|
[강연] 혼자서 성장하기 (0) | 2018.12.04 |
콘솔창에 색 넣기 (0) | 2018.02.09 |
Comments