dx11test

view main.cc @ 0:647ba0689512

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 21 Jun 2013 07:33:06 +0300
parents
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <stddef.h>
5 #include <d3d11.h>
6 #include <d3dx11.h>
7 #include "vec.h"
9 struct Vertex {
10 float pos[3];
11 float color[4];
12 };
14 struct RenderState {
15 float modelview[16];
16 float projection[16];
17 };
19 static bool init();
20 static void cleanup();
21 static void display();
22 static void reshape(int x, int y);
23 static void keyb(int key, bool pressed);
24 static HWND create_window(int xsz, int ysz);
25 static void destroy_window(HWND win);
26 static void main_loop();
27 static long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam);
29 static int width, height;
31 static HWND win;
32 static IDXGISwapChain *swap;
33 static ID3D11Device *dev;
34 static ID3D11DeviceContext *ctx;
35 static ID3D11RenderTargetView *rtarg_view;
36 static ID3D11InputLayout *vertex_layout;
37 static ID3D11VertexShader *vsdr;
38 static ID3D11PixelShader *psdr;
39 static ID3D11Buffer *vbuf;
40 static ID3D11Buffer *rstate_buf;
42 static RenderState rstate;
44 int main()
45 {
46 if(!init()) {
47 return 1;
48 }
49 atexit(cleanup);
51 main_loop();
52 return 0;
53 }
55 static bool init()
56 {
57 if(!(win = create_window(800, 600))) {
58 return false;
59 }
61 unsigned int sdrflags = 0;//D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG;
63 ID3DBlob *vsbuf, *psbuf, *msgblob;
64 if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "vertex_main", "vs_4_0", sdrflags, 0, 0, &vsbuf, &msgblob, 0) != 0) {
65 fprintf(stderr, "failed to load vertex shader\n");
66 if(msgblob->GetBufferSize() > 0) {
67 fprintf(stderr, "Vertex Shader:\n%s\n", (char*)msgblob->GetBufferPointer());
68 }
69 return false;
70 }
71 if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "pixel_main", "ps_4_0", sdrflags, 0, 0, &psbuf, &msgblob, 0) != 0) {
72 fprintf(stderr, "failed to load pixel shader\n");
73 if(msgblob->GetBufferSize() > 0) {
74 fprintf(stderr, "Pixel Shader:\n%s\n", (char*)msgblob->GetBufferPointer());
75 }
76 return false;
77 }
79 if(dev->CreateVertexShader(vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), 0, &vsdr) != 0) {
80 fprintf(stderr, "failed to create vertex shader\n");
81 return false;
82 }
83 if(dev->CreatePixelShader(psbuf->GetBufferPointer(), psbuf->GetBufferSize(), 0, &psdr) != 0) {
84 fprintf(stderr, "failed to create pixel shader\n");
85 return false;
86 }
88 D3D11_INPUT_ELEMENT_DESC elem_desc[2];
89 elem_desc[0].SemanticName = "position";
90 elem_desc[0].SemanticIndex = 0;
91 elem_desc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
92 elem_desc[0].InputSlot = 0;
93 elem_desc[0].AlignedByteOffset = 0;
94 elem_desc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
95 elem_desc[0].InstanceDataStepRate = 0;
97 elem_desc[1].SemanticName = "color";
98 elem_desc[1].SemanticIndex = 0;
99 elem_desc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
100 elem_desc[1].InputSlot = 0;
101 elem_desc[1].AlignedByteOffset = offsetof(Vertex, color);
102 elem_desc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
103 elem_desc[1].InstanceDataStepRate = 0;
105 if(dev->CreateInputLayout(elem_desc, 2, vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), &vertex_layout) != 0) {
106 fprintf(stderr, "failed to create vertex layout\n");
107 return 0;
108 }
109 vsbuf->Release();
110 psbuf->Release();
112 // --- create vertex buffer ---
113 Vertex varr[] = {
114 {{-0.6, -0.4, 0}, {1, 0, 0, 1}},
115 {{0.0, 0.6, 0}, {0, 1, 0, 1}},
116 {{0.6, -0.4, 0}, {0, 0, 1, 1}}
117 };
119 D3D11_BUFFER_DESC buf_desc;
120 memset(&buf_desc, 0, sizeof buf_desc);
121 buf_desc.Usage = D3D11_USAGE_DEFAULT;
122 buf_desc.ByteWidth = sizeof varr;
123 buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
125 D3D11_SUBRESOURCE_DATA subdata;
126 memset(&subdata, 0, sizeof subdata);
127 subdata.pSysMem = varr;
128 if(dev->CreateBuffer(&buf_desc, &subdata, &vbuf) != 0) {
129 fprintf(stderr, "failed to create vertex buffer\n");
130 return false;
131 }
133 // render state buffer
134 memset(&buf_desc, 0, sizeof buf_desc);
135 buf_desc.Usage = D3D11_USAGE_DEFAULT;
136 buf_desc.ByteWidth = sizeof(RenderState);
137 buf_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
139 memset(&subdata, 0, sizeof subdata);
140 subdata.pSysMem = &rstate;
141 if(dev->CreateBuffer(&buf_desc, &subdata, &rstate_buf) != 0) {
142 fprintf(stderr, "failed to create render state buffer\n");
143 return false;
144 }
146 return true;
147 }
149 static void cleanup()
150 {
151 vbuf->Release();
152 rstate_buf->Release();
153 vsdr->Release();
154 psdr->Release();
155 vertex_layout->Release();
156 destroy_window(win);
157 }
159 static void set_identity(float *mat)
160 {
161 mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
162 mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0.0;
163 }
165 static void set_rotation_z(float *mat, float angle)
166 {
167 set_identity(mat);
169 mat[0] = cos(angle);
170 mat[1] = -sin(angle);
171 mat[4] = sin(angle);
172 mat[5] = cos(angle);
173 }
175 static void set_ortho(float *mat, float aspect)
176 {
177 set_identity(mat);
178 mat[0] = 1.0 / aspect;
179 }
181 static void display()
182 {
183 unsigned int msec = timeGetTime();
185 float fbcolor[] = {0.2f, 0.2f, 0.2f, 1.0f};
186 ctx->ClearRenderTargetView(rtarg_view, fbcolor);
188 // set render state constant buffer data
189 set_ortho(rstate.projection, (float)width / (float)height);
190 set_rotation_z(rstate.modelview, msec / 1000.0);
192 ctx->UpdateSubresource(rstate_buf, 0, 0, &rstate, 0, 0);
193 ctx->VSSetConstantBuffers(0, 1, &rstate_buf);
196 unsigned int stride = sizeof(Vertex);
197 unsigned int offset = 0;
198 ctx->IASetVertexBuffers(0, 1, &vbuf, &stride, &offset);
199 ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
200 ctx->IASetInputLayout(vertex_layout);
202 ctx->VSSetShader(vsdr, 0, 0);
203 ctx->PSSetShader(psdr, 0, 0);
205 ctx->Draw(3, 0);
207 swap->Present(0, 0);
208 }
210 static void reshape(int x, int y)
211 {
212 width = x;
213 height = y;
215 D3D11_VIEWPORT vp;
216 vp.Width = (float)x;
217 vp.Height = (float)y;
218 vp.MinDepth = 0;
219 vp.MaxDepth = 1;
220 vp.TopLeftX = 0;
221 vp.TopLeftY = 0;
222 ctx->RSSetViewports(1, &vp);
224 // TODO probably we also need to resize render targets or whatever...
225 }
227 static void keyb(int key, bool pressed)
228 {
229 if(key == 27) {
230 exit(0);
231 }
232 }
234 // ---- system crap ----
236 static HWND create_window(int xsz, int ysz)
237 {
238 HINSTANCE app_inst = GetModuleHandle(0);
240 WNDCLASS wclass;
241 memset(&wclass, 0, sizeof wclass);
242 wclass.hInstance = app_inst;
243 wclass.lpfnWndProc = win_proc;
244 wclass.lpszClassName = "mutantstargoatwin";
245 wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
246 wclass.hIcon = LoadIcon(0, IDI_APPLICATION);
247 wclass.hCursor = LoadCursor(0, IDC_ARROW);
248 wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
249 RegisterClass(&wclass);
251 int posx = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2;
252 int posy = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2;
254 HWND win = CreateWindow("mutantstargoatwin", "DX11 Test", WS_OVERLAPPEDWINDOW, posx, posy,
255 xsz, ysz, 0, 0, app_inst, 0);
256 ShowWindow(win, SW_SHOW);
258 // initialize D3D device
259 DXGI_SWAP_CHAIN_DESC swap_desc;
260 memset(&swap_desc, 0, sizeof swap_desc);
261 swap_desc.BufferCount = 1;
262 swap_desc.BufferDesc.Width = xsz;
263 swap_desc.BufferDesc.Height = ysz;
264 swap_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
265 swap_desc.BufferDesc.RefreshRate.Numerator = 60;
266 swap_desc.BufferDesc.RefreshRate.Denominator = 1;
267 swap_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
268 swap_desc.OutputWindow = win;
269 swap_desc.SampleDesc.Count = 1;
270 swap_desc.SampleDesc.Quality = 0;
271 swap_desc.Windowed = 1;
273 D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_11_0;
275 if(D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, &feature_level, 1,
276 D3D11_SDK_VERSION, &swap_desc, &swap, &dev, 0, &ctx) != 0) {
277 fprintf(stderr, "Failed to create d3d device and swap chain\n");
278 return 0;
279 }
281 ID3D11Texture2D *rtex;
282 if(swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) {
283 fprintf(stderr, "Failed to get default render target texture\n");
284 return 0;
285 }
286 if(dev->CreateRenderTargetView(rtex, 0, &rtarg_view) != 0) {
287 fprintf(stderr, "Failed to create render target view\n");
288 rtex->Release();
289 return 0;
290 }
291 rtex->Release();
292 ctx->OMSetRenderTargets(1, &rtarg_view, 0);
294 reshape(xsz, ysz);
295 return win;
296 }
298 static void destroy_window(HWND win)
299 {
300 CloseWindow(win);
301 UnregisterClass("mutantstargoatwin", GetModuleHandle(0));
303 rtarg_view->Release();
304 ctx->Release();
305 dev->Release();
306 swap->Release();
307 }
309 static void main_loop()
310 {
311 MSG msg;
313 for(;;) {
314 while(PeekMessage(&msg, win, 0, 0, PM_REMOVE)) {
315 TranslateMessage(&msg);
316 DispatchMessage(&msg);
318 if(msg.message == WM_QUIT) {
319 return;
320 }
321 }
323 display();
324 }
325 }
327 static long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam)
328 {
329 switch(msg) {
330 case WM_KEYDOWN:
331 keyb(wparam, true);
332 break;
334 case WM_KEYUP:
335 keyb(wparam, false);
336 break;
338 default:
339 return DefWindowProc(win, msg, wparam, lparam);
340 }
341 return 0;