dx11test

view src/main.cc @ 3:aa1497adac80

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