d3dut

view src/win.cc @ 1:242535442d04

added license, readme, and gpl headers
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 22 Jun 2013 10:43:12 +0300
parents ecc040281dc9
children
line source
1 /*
2 D3DUT - Simple window creation and event handling for Direct3D 11 applications.
3 Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <dxgi.h>
19 #include "d3dut.h"
20 #include "win.h"
21 #include "logmsg.h"
23 std::vector<Window*> windows;
24 int active_win = -1;
26 int create_window(const char *title, int xsz, int ysz, unsigned int dmflags)
27 {
28 IDXGIDevice *dxgidev;
29 if(d3dut_dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgidev) != 0) {
30 fatal_error("failed to get IDXGIDevice interface\n");
31 return 0;
32 }
33 IDXGIAdapter *adapter;
34 if(dxgidev->GetParent(__uuidof(IDXGIAdapter), (void**)&adapter) != 0) {
35 fatal_error("failed to get IDXGIAdapter pointer\n");
36 return 0;
37 }
38 IDXGIFactory *dxgi_factory;
39 if(adapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgi_factory) != 0) {
40 fatal_error("failed to get IDXGIFactory pointer\n");
41 return 0;
42 }
43 adapter->Release();
44 dxgidev->Release();
46 Window *win = new Window;
47 memset(win, 0, sizeof *win);
48 win->must_redisplay = true;
49 win->changed_size = true;
50 win->width = xsz;
51 win->height = ysz;
53 int xpos = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2;
54 int ypos = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2;
55 win->win = CreateWindow(WINCLASSNAME, title, WS_OVERLAPPEDWINDOW, xpos, ypos, xsz, ysz, 0, 0, GetModuleHandle(0), 0);
56 if(!win->win) {
57 fprintf(stderr, "failed to create window: %s\n", title);
58 return 0;
59 }
60 ShowWindow(win->win, SW_SHOW);
62 unsigned int nsamples = 1;
63 unsigned int quality = 0;
64 if(dmflags & D3DUT_MULTISAMPLE) {
65 nsamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
66 d3dut_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nsamples, &quality);
67 }
69 DXGI_SWAP_CHAIN_DESC sd;
70 memset(&sd, 0, sizeof sd);
71 sd.OutputWindow = win->win;
72 sd.BufferDesc.Width = xsz;
73 sd.BufferDesc.Height = ysz;
74 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
75 //sd.Stereo = (dmflags & D3DUT_STEREO) ? 1 : 0;
76 sd.BufferDesc.RefreshRate.Numerator = 60;
77 sd.BufferDesc.RefreshRate.Denominator = 1;
78 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
79 sd.BufferCount = (dmflags & D3DUT_DOUBLE) ? 1 : 0;
80 sd.SampleDesc.Count = nsamples;
81 sd.SampleDesc.Quality = quality;
82 sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
83 sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
84 sd.Windowed = 1;
86 if(dxgi_factory->CreateSwapChain(d3dut_dev, &sd, &win->swap) != 0) {
87 warning("failed to create swap chain\n");
88 return 0;
89 }
90 dxgi_factory->Release();
92 ID3D11Texture2D *rtex;
93 if(win->swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) {
94 warning("failed to get default render target texture\n");
95 return 0;
96 }
97 if(d3dut_dev->CreateRenderTargetView(rtex, 0, &win->rtarg_view) != 0) {
98 warning("failed to create render target view\n");
99 rtex->Release();
100 return 0;
101 }
102 rtex->Release();
103 d3dut_ctx->OMSetRenderTargets(1, &win->rtarg_view, 0);
105 int idx = (int)windows.size();
106 windows.push_back(win);
107 set_active_win(idx);
108 return idx;
109 }
111 void destroy_window(int idx)
112 {
113 if(idx < 0 || idx >= (int)windows.size()) {
114 warning("destroy_window: invalid index: %d\n", idx);
115 return;
116 }
118 Window *win = windows[idx];
119 if(win) {
120 DestroyWindow(win->win);
121 win->rtarg_view->Release();
122 win->swap->Release();
123 delete win;
124 windows[idx] = 0;
125 }
126 }
128 void set_active_win(int idx)
129 {
130 if(idx < 0 || idx >= (int)windows.size()) {
131 warning("set_active_win: invalid window: %d\n", idx);
132 return;
133 }
134 d3dut_rtview = windows[idx]->rtarg_view;
135 active_win = idx;
136 }
138 int get_active_win()
139 {
140 return active_win;
141 }
143 Window *get_window(int idx)
144 {
145 if(idx < 0) {
146 idx = active_win;
147 }
148 if(idx < 0 || idx >= (int)windows.size()) {
149 return 0;
150 }
151 return windows[idx];
152 }
154 static int find_window(HWND syswin)
155 {
156 for(size_t i=0; i<windows.size(); i++) {
157 if(windows[i]->win == syswin) {
158 return i;
159 }
160 }
161 return -1;
162 }
164 static void mouse_handler(Window *win, int bn, bool pressed);
166 long CALLBACK win_handle_event(HWND syswin, unsigned int msg, unsigned int wparam, long lparam)
167 {
168 Window *win = 0;
169 int winid = find_window(syswin);
170 if(winid != -1) {
171 set_active_win(winid);
172 win = get_window();
173 }
175 switch(msg) {
176 case WM_PAINT:
177 win->must_redisplay = true;
178 ValidateRect(win->win, 0);
179 break;
181 case WM_CLOSE:
182 destroy_window(winid);
183 break;
185 case WM_SIZE:
186 win->width = LOWORD(lparam);
187 win->height = HIWORD(lparam);
188 win->changed_size = true;
189 break;
191 case WM_KEYDOWN:
192 if(wparam < 256) {
193 if(win->keyboard_func) {
194 win->keyboard_func(wparam, win->mousex, win->mousey);
195 }
196 } else {
197 if(win->special_func) {
198 win->special_func(wparam, win->mousex, win->mousey);
199 }
200 }
201 break;
203 case WM_KEYUP:
204 if(wparam < 256) {
205 if(win->keyboard_up_func) {
206 win->keyboard_up_func(wparam, win->mousex, win->mousey);
207 }
208 } else {
209 if(win->special_up_func) {
210 win->special_up_func(wparam, win->mousex, win->mousey);
211 }
212 }
213 break;
215 case WM_MOUSEMOVE:
216 win->mousex = LOWORD(lparam);
217 win->mousey = HIWORD(lparam);
219 if(wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
220 if(win->motion_func) {
221 win->motion_func(win->mousex, win->mousey);
222 }
223 } else {
224 if(win->passive_motion_func) {
225 win->passive_motion_func(win->mousex, win->mousey);
226 }
227 }
228 break;
230 case WM_LBUTTONDOWN:
231 mouse_handler(win, D3DUT_LEFT_BUTTON, true);
232 break;
233 case WM_RBUTTONDOWN:
234 mouse_handler(win, D3DUT_RIGHT_BUTTON, true);
235 break;
236 case WM_MBUTTONDOWN:
237 mouse_handler(win, D3DUT_MIDDLE_BUTTON, true);
238 break;
239 case WM_LBUTTONUP:
240 mouse_handler(win, D3DUT_LEFT_BUTTON, false);
241 break;
242 case WM_RBUTTONUP:
243 mouse_handler(win, D3DUT_RIGHT_BUTTON, false);
244 break;
245 case WM_MBUTTONUP:
246 mouse_handler(win, D3DUT_MIDDLE_BUTTON, false);
247 break;
249 case WM_MOUSEWHEEL:
250 {
251 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
252 mouse_handler(win, delta < 0 ? D3DUT_WHEELDOWN_BUTTON : D3DUT_WHEELUP_BUTTON, true);
253 }
254 break;
256 default:
257 return DefWindowProc(syswin, msg, wparam, lparam);
258 }
260 return 0;
261 }
263 static void mouse_handler(Window *win, int bn, bool pressed)
264 {
265 if(win->mouse_func) {
266 win->mouse_func(bn, pressed ? D3DUT_DOWN : D3DUT_UP, win->mousex, win->mousey);
267 }
268 }