d3dut

view src/win.cc @ 0:ecc040281dc9

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 22 Jun 2013 10:11:39 +0300
parents
children 242535442d04
line source
1 #include <dxgi.h>
2 #include "d3dut.h"
3 #include "win.h"
4 #include "logmsg.h"
6 std::vector<Window*> windows;
7 int active_win = -1;
9 int create_window(const char *title, int xsz, int ysz, unsigned int dmflags)
10 {
11 IDXGIDevice *dxgidev;
12 if(d3dut_dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgidev) != 0) {
13 fatal_error("failed to get IDXGIDevice interface\n");
14 return 0;
15 }
16 IDXGIAdapter *adapter;
17 if(dxgidev->GetParent(__uuidof(IDXGIAdapter), (void**)&adapter) != 0) {
18 fatal_error("failed to get IDXGIAdapter pointer\n");
19 return 0;
20 }
21 IDXGIFactory *dxgi_factory;
22 if(adapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgi_factory) != 0) {
23 fatal_error("failed to get IDXGIFactory pointer\n");
24 return 0;
25 }
26 adapter->Release();
27 dxgidev->Release();
29 Window *win = new Window;
30 memset(win, 0, sizeof *win);
31 win->must_redisplay = true;
32 win->changed_size = true;
33 win->width = xsz;
34 win->height = ysz;
36 int xpos = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2;
37 int ypos = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2;
38 win->win = CreateWindow(WINCLASSNAME, title, WS_OVERLAPPEDWINDOW, xpos, ypos, xsz, ysz, 0, 0, GetModuleHandle(0), 0);
39 if(!win->win) {
40 fprintf(stderr, "failed to create window: %s\n", title);
41 return 0;
42 }
43 ShowWindow(win->win, SW_SHOW);
45 unsigned int nsamples = 1;
46 unsigned int quality = 0;
47 if(dmflags & D3DUT_MULTISAMPLE) {
48 nsamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
49 d3dut_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nsamples, &quality);
50 }
52 DXGI_SWAP_CHAIN_DESC sd;
53 memset(&sd, 0, sizeof sd);
54 sd.OutputWindow = win->win;
55 sd.BufferDesc.Width = xsz;
56 sd.BufferDesc.Height = ysz;
57 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
58 //sd.Stereo = (dmflags & D3DUT_STEREO) ? 1 : 0;
59 sd.BufferDesc.RefreshRate.Numerator = 60;
60 sd.BufferDesc.RefreshRate.Denominator = 1;
61 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
62 sd.BufferCount = (dmflags & D3DUT_DOUBLE) ? 1 : 0;
63 sd.SampleDesc.Count = nsamples;
64 sd.SampleDesc.Quality = quality;
65 sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
66 sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
67 sd.Windowed = 1;
69 if(dxgi_factory->CreateSwapChain(d3dut_dev, &sd, &win->swap) != 0) {
70 warning("failed to create swap chain\n");
71 return 0;
72 }
73 dxgi_factory->Release();
75 ID3D11Texture2D *rtex;
76 if(win->swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) {
77 warning("failed to get default render target texture\n");
78 return 0;
79 }
80 if(d3dut_dev->CreateRenderTargetView(rtex, 0, &win->rtarg_view) != 0) {
81 warning("failed to create render target view\n");
82 rtex->Release();
83 return 0;
84 }
85 rtex->Release();
86 d3dut_ctx->OMSetRenderTargets(1, &win->rtarg_view, 0);
88 int idx = (int)windows.size();
89 windows.push_back(win);
90 set_active_win(idx);
91 return idx;
92 }
94 void destroy_window(int idx)
95 {
96 if(idx < 0 || idx >= (int)windows.size()) {
97 warning("destroy_window: invalid index: %d\n", idx);
98 return;
99 }
101 Window *win = windows[idx];
102 if(win) {
103 DestroyWindow(win->win);
104 win->rtarg_view->Release();
105 win->swap->Release();
106 delete win;
107 windows[idx] = 0;
108 }
109 }
111 void set_active_win(int idx)
112 {
113 if(idx < 0 || idx >= (int)windows.size()) {
114 warning("set_active_win: invalid window: %d\n", idx);
115 return;
116 }
117 d3dut_rtview = windows[idx]->rtarg_view;
118 active_win = idx;
119 }
121 int get_active_win()
122 {
123 return active_win;
124 }
126 Window *get_window(int idx)
127 {
128 if(idx < 0) {
129 idx = active_win;
130 }
131 if(idx < 0 || idx >= (int)windows.size()) {
132 return 0;
133 }
134 return windows[idx];
135 }
137 static int find_window(HWND syswin)
138 {
139 for(size_t i=0; i<windows.size(); i++) {
140 if(windows[i]->win == syswin) {
141 return i;
142 }
143 }
144 return -1;
145 }
147 static void mouse_handler(Window *win, int bn, bool pressed);
149 long CALLBACK win_handle_event(HWND syswin, unsigned int msg, unsigned int wparam, long lparam)
150 {
151 Window *win = 0;
152 int winid = find_window(syswin);
153 if(winid != -1) {
154 set_active_win(winid);
155 win = get_window();
156 }
158 switch(msg) {
159 case WM_PAINT:
160 win->must_redisplay = true;
161 ValidateRect(win->win, 0);
162 break;
164 case WM_CLOSE:
165 destroy_window(winid);
166 break;
168 case WM_SIZE:
169 win->width = LOWORD(lparam);
170 win->height = HIWORD(lparam);
171 win->changed_size = true;
172 break;
174 case WM_KEYDOWN:
175 if(wparam < 256) {
176 if(win->keyboard_func) {
177 win->keyboard_func(wparam, win->mousex, win->mousey);
178 }
179 } else {
180 if(win->special_func) {
181 win->special_func(wparam, win->mousex, win->mousey);
182 }
183 }
184 break;
186 case WM_KEYUP:
187 if(wparam < 256) {
188 if(win->keyboard_up_func) {
189 win->keyboard_up_func(wparam, win->mousex, win->mousey);
190 }
191 } else {
192 if(win->special_up_func) {
193 win->special_up_func(wparam, win->mousex, win->mousey);
194 }
195 }
196 break;
198 case WM_MOUSEMOVE:
199 win->mousex = LOWORD(lparam);
200 win->mousey = HIWORD(lparam);
202 if(wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
203 if(win->motion_func) {
204 win->motion_func(win->mousex, win->mousey);
205 }
206 } else {
207 if(win->passive_motion_func) {
208 win->passive_motion_func(win->mousex, win->mousey);
209 }
210 }
211 break;
213 case WM_LBUTTONDOWN:
214 mouse_handler(win, D3DUT_LEFT_BUTTON, true);
215 break;
216 case WM_RBUTTONDOWN:
217 mouse_handler(win, D3DUT_RIGHT_BUTTON, true);
218 break;
219 case WM_MBUTTONDOWN:
220 mouse_handler(win, D3DUT_MIDDLE_BUTTON, true);
221 break;
222 case WM_LBUTTONUP:
223 mouse_handler(win, D3DUT_LEFT_BUTTON, false);
224 break;
225 case WM_RBUTTONUP:
226 mouse_handler(win, D3DUT_RIGHT_BUTTON, false);
227 break;
228 case WM_MBUTTONUP:
229 mouse_handler(win, D3DUT_MIDDLE_BUTTON, false);
230 break;
232 case WM_MOUSEWHEEL:
233 {
234 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
235 mouse_handler(win, delta < 0 ? D3DUT_WHEELDOWN_BUTTON : D3DUT_WHEELUP_BUTTON, true);
236 }
237 break;
239 default:
240 return DefWindowProc(syswin, msg, wparam, lparam);
241 }
243 return 0;
244 }
246 static void mouse_handler(Window *win, int bn, bool pressed)
247 {
248 if(win->mouse_func) {
249 win->mouse_func(bn, pressed ? D3DUT_DOWN : D3DUT_UP, win->mousex, win->mousey);
250 }