d3dut
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win.cc Sat Jun 22 10:11:39 2013 +0300 1.3 @@ -0,0 +1,251 @@ 1.4 +#include <dxgi.h> 1.5 +#include "d3dut.h" 1.6 +#include "win.h" 1.7 +#include "logmsg.h" 1.8 + 1.9 +std::vector<Window*> windows; 1.10 +int active_win = -1; 1.11 + 1.12 +int create_window(const char *title, int xsz, int ysz, unsigned int dmflags) 1.13 +{ 1.14 + IDXGIDevice *dxgidev; 1.15 + if(d3dut_dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgidev) != 0) { 1.16 + fatal_error("failed to get IDXGIDevice interface\n"); 1.17 + return 0; 1.18 + } 1.19 + IDXGIAdapter *adapter; 1.20 + if(dxgidev->GetParent(__uuidof(IDXGIAdapter), (void**)&adapter) != 0) { 1.21 + fatal_error("failed to get IDXGIAdapter pointer\n"); 1.22 + return 0; 1.23 + } 1.24 + IDXGIFactory *dxgi_factory; 1.25 + if(adapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgi_factory) != 0) { 1.26 + fatal_error("failed to get IDXGIFactory pointer\n"); 1.27 + return 0; 1.28 + } 1.29 + adapter->Release(); 1.30 + dxgidev->Release(); 1.31 + 1.32 + Window *win = new Window; 1.33 + memset(win, 0, sizeof *win); 1.34 + win->must_redisplay = true; 1.35 + win->changed_size = true; 1.36 + win->width = xsz; 1.37 + win->height = ysz; 1.38 + 1.39 + int xpos = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2; 1.40 + int ypos = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2; 1.41 + win->win = CreateWindow(WINCLASSNAME, title, WS_OVERLAPPEDWINDOW, xpos, ypos, xsz, ysz, 0, 0, GetModuleHandle(0), 0); 1.42 + if(!win->win) { 1.43 + fprintf(stderr, "failed to create window: %s\n", title); 1.44 + return 0; 1.45 + } 1.46 + ShowWindow(win->win, SW_SHOW); 1.47 + 1.48 + unsigned int nsamples = 1; 1.49 + unsigned int quality = 0; 1.50 + if(dmflags & D3DUT_MULTISAMPLE) { 1.51 + nsamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; 1.52 + d3dut_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nsamples, &quality); 1.53 + } 1.54 + 1.55 + DXGI_SWAP_CHAIN_DESC sd; 1.56 + memset(&sd, 0, sizeof sd); 1.57 + sd.OutputWindow = win->win; 1.58 + sd.BufferDesc.Width = xsz; 1.59 + sd.BufferDesc.Height = ysz; 1.60 + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 1.61 + //sd.Stereo = (dmflags & D3DUT_STEREO) ? 1 : 0; 1.62 + sd.BufferDesc.RefreshRate.Numerator = 60; 1.63 + sd.BufferDesc.RefreshRate.Denominator = 1; 1.64 + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 1.65 + sd.BufferCount = (dmflags & D3DUT_DOUBLE) ? 1 : 0; 1.66 + sd.SampleDesc.Count = nsamples; 1.67 + sd.SampleDesc.Quality = quality; 1.68 + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 1.69 + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 1.70 + sd.Windowed = 1; 1.71 + 1.72 + if(dxgi_factory->CreateSwapChain(d3dut_dev, &sd, &win->swap) != 0) { 1.73 + warning("failed to create swap chain\n"); 1.74 + return 0; 1.75 + } 1.76 + dxgi_factory->Release(); 1.77 + 1.78 + ID3D11Texture2D *rtex; 1.79 + if(win->swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) { 1.80 + warning("failed to get default render target texture\n"); 1.81 + return 0; 1.82 + } 1.83 + if(d3dut_dev->CreateRenderTargetView(rtex, 0, &win->rtarg_view) != 0) { 1.84 + warning("failed to create render target view\n"); 1.85 + rtex->Release(); 1.86 + return 0; 1.87 + } 1.88 + rtex->Release(); 1.89 + d3dut_ctx->OMSetRenderTargets(1, &win->rtarg_view, 0); 1.90 + 1.91 + int idx = (int)windows.size(); 1.92 + windows.push_back(win); 1.93 + set_active_win(idx); 1.94 + return idx; 1.95 +} 1.96 + 1.97 +void destroy_window(int idx) 1.98 +{ 1.99 + if(idx < 0 || idx >= (int)windows.size()) { 1.100 + warning("destroy_window: invalid index: %d\n", idx); 1.101 + return; 1.102 + } 1.103 + 1.104 + Window *win = windows[idx]; 1.105 + if(win) { 1.106 + DestroyWindow(win->win); 1.107 + win->rtarg_view->Release(); 1.108 + win->swap->Release(); 1.109 + delete win; 1.110 + windows[idx] = 0; 1.111 + } 1.112 +} 1.113 + 1.114 +void set_active_win(int idx) 1.115 +{ 1.116 + if(idx < 0 || idx >= (int)windows.size()) { 1.117 + warning("set_active_win: invalid window: %d\n", idx); 1.118 + return; 1.119 + } 1.120 + d3dut_rtview = windows[idx]->rtarg_view; 1.121 + active_win = idx; 1.122 +} 1.123 + 1.124 +int get_active_win() 1.125 +{ 1.126 + return active_win; 1.127 +} 1.128 + 1.129 +Window *get_window(int idx) 1.130 +{ 1.131 + if(idx < 0) { 1.132 + idx = active_win; 1.133 + } 1.134 + if(idx < 0 || idx >= (int)windows.size()) { 1.135 + return 0; 1.136 + } 1.137 + return windows[idx]; 1.138 +} 1.139 + 1.140 +static int find_window(HWND syswin) 1.141 +{ 1.142 + for(size_t i=0; i<windows.size(); i++) { 1.143 + if(windows[i]->win == syswin) { 1.144 + return i; 1.145 + } 1.146 + } 1.147 + return -1; 1.148 +} 1.149 + 1.150 +static void mouse_handler(Window *win, int bn, bool pressed); 1.151 + 1.152 +long CALLBACK win_handle_event(HWND syswin, unsigned int msg, unsigned int wparam, long lparam) 1.153 +{ 1.154 + Window *win = 0; 1.155 + int winid = find_window(syswin); 1.156 + if(winid != -1) { 1.157 + set_active_win(winid); 1.158 + win = get_window(); 1.159 + } 1.160 + 1.161 + switch(msg) { 1.162 + case WM_PAINT: 1.163 + win->must_redisplay = true; 1.164 + ValidateRect(win->win, 0); 1.165 + break; 1.166 + 1.167 + case WM_CLOSE: 1.168 + destroy_window(winid); 1.169 + break; 1.170 + 1.171 + case WM_SIZE: 1.172 + win->width = LOWORD(lparam); 1.173 + win->height = HIWORD(lparam); 1.174 + win->changed_size = true; 1.175 + break; 1.176 + 1.177 + case WM_KEYDOWN: 1.178 + if(wparam < 256) { 1.179 + if(win->keyboard_func) { 1.180 + win->keyboard_func(wparam, win->mousex, win->mousey); 1.181 + } 1.182 + } else { 1.183 + if(win->special_func) { 1.184 + win->special_func(wparam, win->mousex, win->mousey); 1.185 + } 1.186 + } 1.187 + break; 1.188 + 1.189 + case WM_KEYUP: 1.190 + if(wparam < 256) { 1.191 + if(win->keyboard_up_func) { 1.192 + win->keyboard_up_func(wparam, win->mousex, win->mousey); 1.193 + } 1.194 + } else { 1.195 + if(win->special_up_func) { 1.196 + win->special_up_func(wparam, win->mousex, win->mousey); 1.197 + } 1.198 + } 1.199 + break; 1.200 + 1.201 + case WM_MOUSEMOVE: 1.202 + win->mousex = LOWORD(lparam); 1.203 + win->mousey = HIWORD(lparam); 1.204 + 1.205 + if(wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { 1.206 + if(win->motion_func) { 1.207 + win->motion_func(win->mousex, win->mousey); 1.208 + } 1.209 + } else { 1.210 + if(win->passive_motion_func) { 1.211 + win->passive_motion_func(win->mousex, win->mousey); 1.212 + } 1.213 + } 1.214 + break; 1.215 + 1.216 + case WM_LBUTTONDOWN: 1.217 + mouse_handler(win, D3DUT_LEFT_BUTTON, true); 1.218 + break; 1.219 + case WM_RBUTTONDOWN: 1.220 + mouse_handler(win, D3DUT_RIGHT_BUTTON, true); 1.221 + break; 1.222 + case WM_MBUTTONDOWN: 1.223 + mouse_handler(win, D3DUT_MIDDLE_BUTTON, true); 1.224 + break; 1.225 + case WM_LBUTTONUP: 1.226 + mouse_handler(win, D3DUT_LEFT_BUTTON, false); 1.227 + break; 1.228 + case WM_RBUTTONUP: 1.229 + mouse_handler(win, D3DUT_RIGHT_BUTTON, false); 1.230 + break; 1.231 + case WM_MBUTTONUP: 1.232 + mouse_handler(win, D3DUT_MIDDLE_BUTTON, false); 1.233 + break; 1.234 + 1.235 + case WM_MOUSEWHEEL: 1.236 + { 1.237 + int delta = GET_WHEEL_DELTA_WPARAM(wparam); 1.238 + mouse_handler(win, delta < 0 ? D3DUT_WHEELDOWN_BUTTON : D3DUT_WHEELUP_BUTTON, true); 1.239 + } 1.240 + break; 1.241 + 1.242 + default: 1.243 + return DefWindowProc(syswin, msg, wparam, lparam); 1.244 + } 1.245 + 1.246 + return 0; 1.247 +} 1.248 + 1.249 +static void mouse_handler(Window *win, int bn, bool pressed) 1.250 +{ 1.251 + if(win->mouse_func) { 1.252 + win->mouse_func(bn, pressed ? D3DUT_DOWN : D3DUT_UP, win->mousex, win->mousey); 1.253 + } 1.254 +} 1.255 \ No newline at end of file