dx11test

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