dx11test

diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/main.cc	Fri Jun 21 07:33:06 2013 +0300
     1.3 @@ -0,0 +1,342 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <math.h>
     1.7 +#include <stddef.h>
     1.8 +#include <d3d11.h>
     1.9 +#include <d3dx11.h>
    1.10 +#include "vec.h"
    1.11 +
    1.12 +struct Vertex {
    1.13 +	float pos[3];
    1.14 +	float color[4];
    1.15 +};
    1.16 +
    1.17 +struct RenderState {
    1.18 +	float modelview[16];
    1.19 +	float projection[16];
    1.20 +};
    1.21 +
    1.22 +static bool init();
    1.23 +static void cleanup();
    1.24 +static void display();
    1.25 +static void reshape(int x, int y);
    1.26 +static void keyb(int key, bool pressed);
    1.27 +static HWND create_window(int xsz, int ysz);
    1.28 +static void destroy_window(HWND win);
    1.29 +static void main_loop();
    1.30 +static long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam);
    1.31 +
    1.32 +static int width, height;
    1.33 +
    1.34 +static HWND win;
    1.35 +static IDXGISwapChain *swap;
    1.36 +static ID3D11Device *dev;
    1.37 +static ID3D11DeviceContext *ctx;
    1.38 +static ID3D11RenderTargetView *rtarg_view;
    1.39 +static ID3D11InputLayout *vertex_layout;
    1.40 +static ID3D11VertexShader *vsdr;
    1.41 +static ID3D11PixelShader *psdr;
    1.42 +static ID3D11Buffer *vbuf;
    1.43 +static ID3D11Buffer *rstate_buf;
    1.44 +
    1.45 +static RenderState rstate;
    1.46 +
    1.47 +int main()
    1.48 +{
    1.49 +	if(!init()) {
    1.50 +		return 1;
    1.51 +	}
    1.52 +	atexit(cleanup);
    1.53 +
    1.54 +	main_loop();
    1.55 +	return 0;
    1.56 +}
    1.57 +
    1.58 +static bool init()
    1.59 +{
    1.60 +	if(!(win = create_window(800, 600))) {
    1.61 +		return false;
    1.62 +	}
    1.63 +
    1.64 +	unsigned int sdrflags = 0;//D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG;
    1.65 +
    1.66 +	ID3DBlob *vsbuf, *psbuf, *msgblob;
    1.67 +	if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "vertex_main", "vs_4_0", sdrflags, 0, 0, &vsbuf, &msgblob, 0) != 0) {
    1.68 +		fprintf(stderr, "failed to load vertex shader\n");
    1.69 +		if(msgblob->GetBufferSize() > 0) {
    1.70 +			fprintf(stderr, "Vertex Shader:\n%s\n", (char*)msgblob->GetBufferPointer());
    1.71 +		}
    1.72 +		return false;
    1.73 +	}
    1.74 +	if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "pixel_main", "ps_4_0", sdrflags, 0, 0, &psbuf, &msgblob, 0) != 0) {
    1.75 +		fprintf(stderr, "failed to load pixel shader\n");
    1.76 +		if(msgblob->GetBufferSize() > 0) {
    1.77 +			fprintf(stderr, "Pixel Shader:\n%s\n", (char*)msgblob->GetBufferPointer());
    1.78 +		}
    1.79 +		return false;
    1.80 +	}
    1.81 +
    1.82 +	if(dev->CreateVertexShader(vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), 0, &vsdr) != 0) {
    1.83 +		fprintf(stderr, "failed to create vertex shader\n");
    1.84 +		return false;
    1.85 +	}
    1.86 +	if(dev->CreatePixelShader(psbuf->GetBufferPointer(), psbuf->GetBufferSize(), 0, &psdr) != 0) {
    1.87 +		fprintf(stderr, "failed to create pixel shader\n");
    1.88 +		return false;
    1.89 +	}
    1.90 +
    1.91 +	D3D11_INPUT_ELEMENT_DESC elem_desc[2];
    1.92 +	elem_desc[0].SemanticName = "position";
    1.93 +	elem_desc[0].SemanticIndex = 0;
    1.94 +	elem_desc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
    1.95 +	elem_desc[0].InputSlot = 0;
    1.96 +	elem_desc[0].AlignedByteOffset = 0;
    1.97 +	elem_desc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    1.98 +	elem_desc[0].InstanceDataStepRate = 0;
    1.99 +
   1.100 +	elem_desc[1].SemanticName = "color";
   1.101 +	elem_desc[1].SemanticIndex = 0;
   1.102 +	elem_desc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
   1.103 +	elem_desc[1].InputSlot = 0;
   1.104 +	elem_desc[1].AlignedByteOffset = offsetof(Vertex, color);
   1.105 +	elem_desc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
   1.106 +	elem_desc[1].InstanceDataStepRate = 0;
   1.107 +
   1.108 +	if(dev->CreateInputLayout(elem_desc, 2, vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), &vertex_layout) != 0) {
   1.109 +		fprintf(stderr, "failed to create vertex layout\n");
   1.110 +		return 0;
   1.111 +	}
   1.112 +	vsbuf->Release();
   1.113 +	psbuf->Release();
   1.114 +
   1.115 +	// --- create vertex buffer ---
   1.116 +	Vertex varr[] = {
   1.117 +		{{-0.6, -0.4, 0}, {1, 0, 0, 1}},
   1.118 +		{{0.0, 0.6, 0}, {0, 1, 0, 1}},
   1.119 +		{{0.6, -0.4, 0}, {0, 0, 1, 1}}
   1.120 +	};
   1.121 +
   1.122 +	D3D11_BUFFER_DESC buf_desc;
   1.123 +	memset(&buf_desc, 0, sizeof buf_desc);
   1.124 +	buf_desc.Usage = D3D11_USAGE_DEFAULT;
   1.125 +	buf_desc.ByteWidth = sizeof varr;
   1.126 +	buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
   1.127 +
   1.128 +	D3D11_SUBRESOURCE_DATA subdata;
   1.129 +	memset(&subdata, 0, sizeof subdata);
   1.130 +	subdata.pSysMem = varr;
   1.131 +	if(dev->CreateBuffer(&buf_desc, &subdata, &vbuf) != 0) {
   1.132 +		fprintf(stderr, "failed to create vertex buffer\n");
   1.133 +		return false;
   1.134 +	}
   1.135 +
   1.136 +	// render state buffer
   1.137 +	memset(&buf_desc, 0, sizeof buf_desc);
   1.138 +	buf_desc.Usage = D3D11_USAGE_DEFAULT;
   1.139 +	buf_desc.ByteWidth = sizeof(RenderState);
   1.140 +	buf_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
   1.141 +
   1.142 +	memset(&subdata, 0, sizeof subdata);
   1.143 +	subdata.pSysMem = &rstate;
   1.144 +	if(dev->CreateBuffer(&buf_desc, &subdata, &rstate_buf) != 0) {
   1.145 +		fprintf(stderr, "failed to create render state buffer\n");
   1.146 +		return false;
   1.147 +	}
   1.148 +
   1.149 +	return true;
   1.150 +}
   1.151 +
   1.152 +static void cleanup()
   1.153 +{
   1.154 +	vbuf->Release();
   1.155 +	rstate_buf->Release();
   1.156 +	vsdr->Release();
   1.157 +	psdr->Release();
   1.158 +	vertex_layout->Release();
   1.159 +	destroy_window(win);
   1.160 +}
   1.161 +
   1.162 +static void set_identity(float *mat)
   1.163 +{
   1.164 +	mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
   1.165 +	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;
   1.166 +}
   1.167 +
   1.168 +static void set_rotation_z(float *mat, float angle)
   1.169 +{
   1.170 +	set_identity(mat);
   1.171 +
   1.172 +	mat[0] = cos(angle);
   1.173 +	mat[1] = -sin(angle);
   1.174 +	mat[4] = sin(angle);
   1.175 +	mat[5] = cos(angle);
   1.176 +}
   1.177 +
   1.178 +static void set_ortho(float *mat, float aspect)
   1.179 +{
   1.180 +	set_identity(mat);
   1.181 +	mat[0] = 1.0 / aspect;
   1.182 +}
   1.183 +
   1.184 +static void display()
   1.185 +{
   1.186 +	unsigned int msec = timeGetTime();
   1.187 +
   1.188 +	float fbcolor[] = {0.2f, 0.2f, 0.2f, 1.0f};
   1.189 +	ctx->ClearRenderTargetView(rtarg_view, fbcolor);
   1.190 +
   1.191 +	// set render state constant buffer data
   1.192 +	set_ortho(rstate.projection, (float)width / (float)height);
   1.193 +	set_rotation_z(rstate.modelview, msec / 1000.0);
   1.194 +
   1.195 +	ctx->UpdateSubresource(rstate_buf, 0, 0, &rstate, 0, 0);
   1.196 +	ctx->VSSetConstantBuffers(0, 1, &rstate_buf);
   1.197 +
   1.198 +
   1.199 +	unsigned int stride = sizeof(Vertex);
   1.200 +	unsigned int offset = 0;
   1.201 +	ctx->IASetVertexBuffers(0, 1, &vbuf, &stride, &offset);
   1.202 +	ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
   1.203 +	ctx->IASetInputLayout(vertex_layout);
   1.204 +
   1.205 +	ctx->VSSetShader(vsdr, 0, 0);
   1.206 +	ctx->PSSetShader(psdr, 0, 0);
   1.207 +
   1.208 +	ctx->Draw(3, 0);
   1.209 +
   1.210 +	swap->Present(0, 0);
   1.211 +}
   1.212 +
   1.213 +static void reshape(int x, int y)
   1.214 +{
   1.215 +	width = x;
   1.216 +	height = y;
   1.217 +
   1.218 +	D3D11_VIEWPORT vp;
   1.219 +	vp.Width = (float)x;
   1.220 +	vp.Height = (float)y;
   1.221 +	vp.MinDepth = 0;
   1.222 +	vp.MaxDepth = 1;
   1.223 +	vp.TopLeftX = 0;
   1.224 +	vp.TopLeftY = 0;
   1.225 +	ctx->RSSetViewports(1, &vp);
   1.226 +
   1.227 +	// TODO probably we also need to resize render targets or whatever...
   1.228 +}
   1.229 +
   1.230 +static void keyb(int key, bool pressed)
   1.231 +{
   1.232 +	if(key == 27) {
   1.233 +		exit(0);
   1.234 +	}
   1.235 +}
   1.236 +
   1.237 +// ---- system crap ----
   1.238 +
   1.239 +static HWND create_window(int xsz, int ysz)
   1.240 +{
   1.241 +	HINSTANCE app_inst = GetModuleHandle(0);
   1.242 +
   1.243 +	WNDCLASS wclass;
   1.244 +	memset(&wclass, 0, sizeof wclass);
   1.245 +	wclass.hInstance = app_inst;
   1.246 +	wclass.lpfnWndProc = win_proc;
   1.247 +	wclass.lpszClassName = "mutantstargoatwin";
   1.248 +	wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
   1.249 +	wclass.hIcon = LoadIcon(0, IDI_APPLICATION);
   1.250 +	wclass.hCursor = LoadCursor(0, IDC_ARROW);
   1.251 +	wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
   1.252 +	RegisterClass(&wclass);
   1.253 +
   1.254 +	int posx = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2;
   1.255 +	int posy = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2;
   1.256 +
   1.257 +	HWND win = CreateWindow("mutantstargoatwin", "DX11 Test", WS_OVERLAPPEDWINDOW, posx, posy,
   1.258 +		xsz, ysz, 0, 0, app_inst, 0);
   1.259 +	ShowWindow(win, SW_SHOW);
   1.260 +
   1.261 +	// initialize D3D device
   1.262 +	DXGI_SWAP_CHAIN_DESC swap_desc;
   1.263 +	memset(&swap_desc, 0, sizeof swap_desc);
   1.264 +	swap_desc.BufferCount = 1;
   1.265 +	swap_desc.BufferDesc.Width = xsz;
   1.266 +	swap_desc.BufferDesc.Height = ysz;
   1.267 +	swap_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
   1.268 +	swap_desc.BufferDesc.RefreshRate.Numerator = 60;
   1.269 +	swap_desc.BufferDesc.RefreshRate.Denominator = 1;
   1.270 +	swap_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   1.271 +	swap_desc.OutputWindow = win;
   1.272 +	swap_desc.SampleDesc.Count = 1;
   1.273 +	swap_desc.SampleDesc.Quality = 0;
   1.274 +	swap_desc.Windowed = 1;
   1.275 +
   1.276 +	D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_11_0;
   1.277 +
   1.278 +	if(D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, &feature_level, 1,
   1.279 +			D3D11_SDK_VERSION, &swap_desc, &swap, &dev, 0, &ctx) != 0) {
   1.280 +		fprintf(stderr, "Failed to create d3d device and swap chain\n");
   1.281 +		return 0;
   1.282 +	}
   1.283 +
   1.284 +	ID3D11Texture2D *rtex;
   1.285 +	if(swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) {
   1.286 +		fprintf(stderr, "Failed to get default render target texture\n");
   1.287 +		return 0;
   1.288 +	}
   1.289 +	if(dev->CreateRenderTargetView(rtex, 0, &rtarg_view) != 0) {
   1.290 +		fprintf(stderr, "Failed to create render target view\n");
   1.291 +		rtex->Release();
   1.292 +		return 0;
   1.293 +	}
   1.294 +	rtex->Release();
   1.295 +	ctx->OMSetRenderTargets(1, &rtarg_view, 0);
   1.296 +
   1.297 +	reshape(xsz, ysz);
   1.298 +	return win;
   1.299 +}
   1.300 +
   1.301 +static void destroy_window(HWND win)
   1.302 +{
   1.303 +	CloseWindow(win);
   1.304 +	UnregisterClass("mutantstargoatwin", GetModuleHandle(0));
   1.305 +
   1.306 +	rtarg_view->Release();
   1.307 +	ctx->Release();
   1.308 +	dev->Release();
   1.309 +	swap->Release();
   1.310 +}
   1.311 +
   1.312 +static void main_loop()
   1.313 +{
   1.314 +	MSG msg;
   1.315 +
   1.316 +	for(;;) {
   1.317 +		while(PeekMessage(&msg, win, 0, 0, PM_REMOVE)) {
   1.318 +			TranslateMessage(&msg);
   1.319 +			DispatchMessage(&msg);
   1.320 +		
   1.321 +			if(msg.message == WM_QUIT) {
   1.322 +				return;
   1.323 +			}
   1.324 +		}
   1.325 +
   1.326 +		display();
   1.327 +	}
   1.328 +}
   1.329 +
   1.330 +static long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam)
   1.331 +{
   1.332 +	switch(msg) {
   1.333 +	case WM_KEYDOWN:
   1.334 +		keyb(wparam, true);
   1.335 +		break;
   1.336 +
   1.337 +	case WM_KEYUP:
   1.338 +		keyb(wparam, false);
   1.339 +		break;
   1.340 +
   1.341 +	default:
   1.342 +		return DefWindowProc(win, msg, wparam, lparam);
   1.343 +	}
   1.344 +	return 0;
   1.345 +}
   1.346 \ No newline at end of file