d3dut

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