nuclear@1: /* nuclear@1: D3DUT - Simple window creation and event handling for Direct3D 11 applications. nuclear@1: Copyright (C) 2013 John Tsiombikas nuclear@1: nuclear@1: This program is free software: you can redistribute it and/or modify nuclear@1: it under the terms of the GNU Lesser General Public License as published by nuclear@1: the Free Software Foundation, either version 3 of the License, or nuclear@1: (at your option) any later version. nuclear@1: nuclear@1: This program is distributed in the hope that it will be useful, nuclear@1: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@1: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@1: GNU Lesser General Public License for more details. nuclear@1: nuclear@1: You should have received a copy of the GNU Lesser General Public License nuclear@1: along with this program. If not, see . nuclear@1: */ nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "d3dut.h" nuclear@0: #include "win.h" nuclear@0: #include "logmsg.h" nuclear@0: nuclear@0: static void d3dut_cleanup(); nuclear@0: nuclear@0: D3DUTAPI ID3D11Device *d3dut_dev; nuclear@0: D3DUTAPI ID3D11DeviceContext *d3dut_ctx; nuclear@0: D3DUTAPI ID3D11RenderTargetView *d3dut_rtview; nuclear@0: nuclear@0: static int init_xsz = 640; nuclear@0: static int init_ysz = 480; nuclear@0: static int init_dmflags = 0; nuclear@0: nuclear@0: static long init_time = -1; nuclear@0: nuclear@0: static D3DUT_IdleFunc idle_func; nuclear@0: nuclear@0: void D3DUTAPI d3dut_init(int *argc, char **argv) nuclear@0: { nuclear@0: if(init_time >= 0) { nuclear@0: warning("already initialized!\n"); nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: WNDCLASS wclass; nuclear@0: memset(&wclass, 0, sizeof wclass); nuclear@0: wclass.hInstance = GetModuleHandle(0); nuclear@0: wclass.lpfnWndProc = win_handle_event; nuclear@0: wclass.lpszClassName = WINCLASSNAME; nuclear@0: wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; nuclear@0: wclass.hIcon = LoadIcon(0, IDI_APPLICATION); nuclear@0: wclass.hCursor = LoadCursor(0, IDC_ARROW); nuclear@0: wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); nuclear@0: RegisterClass(&wclass); nuclear@0: nuclear@0: // create D3D device nuclear@0: D3D_FEATURE_LEVEL feature_level[] = { nuclear@0: D3D_FEATURE_LEVEL_11_0, nuclear@0: D3D_FEATURE_LEVEL_10_1, nuclear@0: D3D_FEATURE_LEVEL_10_0 nuclear@0: }; nuclear@0: if(D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, feature_level, 3, D3D11_SDK_VERSION, nuclear@0: &d3dut_dev, 0, &d3dut_ctx) != 0) { nuclear@0: fatal_error("failed to create D3D11 device\n"); nuclear@0: } nuclear@0: atexit(d3dut_cleanup); nuclear@0: nuclear@0: init_time = timeGetTime(); nuclear@0: } nuclear@0: nuclear@0: static void d3dut_cleanup() nuclear@0: { nuclear@0: for(size_t i=0; iRelease(); nuclear@0: d3dut_dev = 0; nuclear@0: } nuclear@0: if(d3dut_ctx) { nuclear@0: d3dut_ctx->Release(); nuclear@0: d3dut_ctx = 0; nuclear@0: } nuclear@0: d3dut_rtview = 0; nuclear@0: nuclear@0: UnregisterClass(WINCLASSNAME, GetModuleHandle(0)); nuclear@0: init_time = -1; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_init_display_mode(unsigned int dmflags) nuclear@0: { nuclear@0: init_dmflags = dmflags; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_init_window_size(int xsz, int ysz) nuclear@0: { nuclear@0: init_xsz = xsz; nuclear@0: init_ysz = ysz; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: int D3DUTAPI d3dut_create_window(const char *title) nuclear@0: { nuclear@0: return create_window(title, init_xsz, init_ysz, init_dmflags); nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_destroy_window(int win) nuclear@0: { nuclear@0: destroy_window(win); nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_set_window(int idx) nuclear@0: { nuclear@0: set_active_win(idx); nuclear@0: } nuclear@0: nuclear@0: int D3DUTAPI d3dut_get_window() nuclear@0: { nuclear@0: return get_active_win(); nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_display_func(D3DUT_DisplayFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->display_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_idle_func(D3DUT_IdleFunc func) nuclear@0: { nuclear@0: idle_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_reshape_func(D3DUT_ReshapeFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->reshape_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_keyboard_func(D3DUT_KeyboardFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->keyboard_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_keyboard_up_func(D3DUT_KeyboardUpFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->keyboard_up_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_special_func(D3DUT_SpecialFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->special_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_special_up_func(D3DUT_SpecialUpFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->special_up_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_mouse_func(D3DUT_MouseFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->mouse_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_motion_func(D3DUT_MotionFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->motion_func = func; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_passive_motion_func(D3DUT_PassiveMotionFunc func) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->passive_motion_func = func; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void D3DUTAPI d3dut_post_redisplay() nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->must_redisplay = true; nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_swap_buffers() nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: win->swap->Present(0, 0); nuclear@0: } nuclear@0: nuclear@0: void D3DUTAPI d3dut_main_loop() nuclear@0: { nuclear@0: MSG msg; nuclear@0: nuclear@0: for(;;) { nuclear@0: bool must_redisplay = false; nuclear@0: for(size_t i=0; ichanged_size && win->reshape_func) { nuclear@0: win->changed_size = false; nuclear@0: set_active_win(i); nuclear@0: win->reshape_func(win->width, win->height); nuclear@0: } nuclear@0: if(win->must_redisplay) { nuclear@0: must_redisplay = true; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(idle_func || must_redisplay) { nuclear@0: while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { nuclear@0: TranslateMessage(&msg); nuclear@0: DispatchMessage(&msg); nuclear@0: if(msg.message == WM_QUIT) { nuclear@0: return; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(idle_func) { // checking again because a handler might have set this to 0 nuclear@0: idle_func(); nuclear@0: } nuclear@0: } else { nuclear@0: if(!GetMessage(&msg, 0, 0, 0)) { nuclear@0: return; nuclear@0: } nuclear@0: TranslateMessage(&msg); nuclear@0: DispatchMessage(&msg); nuclear@0: } nuclear@0: nuclear@0: for(size_t i=0; imust_redisplay && win->display_func) { nuclear@0: win->must_redisplay = false; nuclear@0: set_active_win(i); nuclear@0: win->display_func(); nuclear@0: ValidateRect(win->win, 0); nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: nuclear@0: int D3DUTAPI d3dut_get(unsigned int what) nuclear@0: { nuclear@0: Window *win = get_window(); nuclear@0: nuclear@0: switch(what) { nuclear@0: case D3DUT_WINDOW_WIDTH: nuclear@0: return win->width; nuclear@0: case D3DUT_WINDOW_HEIGHT: nuclear@0: return win->height; nuclear@0: nuclear@0: case D3DUT_ELAPSED_TIME: nuclear@0: return (long)timeGetTime() - init_time; nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void D3DUTAPI d3dut_solid_sphere(double radius, int slices, int stacks) nuclear@0: { nuclear@0: }