Browse Source

dx : fullscreen, vsync, resize ok

Nicolas Cannasse 8 years ago
parent
commit
cdc3b562b8
4 changed files with 180 additions and 163 deletions
  1. 16 16
      libs/directx/directx.cpp
  2. 25 12
      libs/directx/dx/Driver.hx
  3. 22 19
      libs/directx/dx/Window.hx
  4. 117 116
      libs/directx/window.c

+ 16 - 16
libs/directx/directx.cpp

@@ -39,7 +39,7 @@ static IDXGIFactory *GetDXGI() {
 	return factory;
 }
 
-HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags ) {
+HL_PRIM dx_driver *HL_NAME(create)( HWND window, int format, int flags ) {
 	DWORD result;
 	static D3D_FEATURE_LEVEL levels[] = {
 		D3D_FEATURE_LEVEL_11_1,
@@ -67,7 +67,7 @@ HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags ) {
 	ZeroMemory(&desc,sizeof(desc));
 	desc.BufferDesc.Width = r.right;
 	desc.BufferDesc.Height = r.bottom;
-	desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+	desc.BufferDesc.Format = (DXGI_FORMAT)format;
 	desc.SampleDesc.Count = 1; // NO AA for now
 	desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
 	desc.BufferCount = 1;
@@ -87,6 +87,10 @@ HL_PRIM dx_resource *HL_NAME(get_back_buffer)() {
 	return backBuffer;
 }
 
+HL_PRIM bool HL_NAME(resize)( int width, int height, int format ) {
+	return driver->swapchain->ResizeBuffers(1,width,height,(DXGI_FORMAT)format,0) == S_OK;
+}
+
 HL_PRIM dx_pointer *HL_NAME(create_render_target_view)( dx_resource *r, dx_struct<D3D11_RENDER_TARGET_VIEW_DESC> *desc ) {
 	ID3D11RenderTargetView *rt;
 	if( driver->device->CreateRenderTargetView(r, desc ? &desc->value : NULL, &rt) != S_OK )
@@ -113,6 +117,10 @@ HL_PRIM void HL_NAME(rs_set_viewports)( int count, vbyte *data ) {
 	driver->context->RSSetViewports(count,(D3D11_VIEWPORT*)data);
 }
 
+HL_PRIM void HL_NAME(rs_set_scissor_rects)( int count, vbyte *data ) {
+	driver->context->RSSetScissorRects(count,(D3D11_RECT*)data);
+}
+
 HL_PRIM void HL_NAME(clear_color)( dx_pointer *rt, double r, double g, double b, double a ) {
 	float color[4];
 	color[0] = (float)r;
@@ -122,16 +130,8 @@ HL_PRIM void HL_NAME(clear_color)( dx_pointer *rt, double r, double g, double b,
 	driver->context->ClearRenderTargetView((ID3D11RenderTargetView*)rt,color);
 }
 
-HL_PRIM void HL_NAME(present)() {
-	driver->swapchain->Present(0,0);
-}
-
-HL_PRIM int HL_NAME(get_screen_width)() {
-	return GetSystemMetrics(SM_CXSCREEN);
-}
-
-HL_PRIM int HL_NAME(get_screen_height)() {
-	return GetSystemMetrics(SM_CYSCREEN);
+HL_PRIM void HL_NAME(present)( int interval, int flags ) {
+	driver->swapchain->Present(interval,flags);
 }
 
 HL_PRIM const uchar *HL_NAME(get_device_name)() {
@@ -367,17 +367,17 @@ HL_PRIM void HL_NAME(vs_set_shader_resources)( int start, int count, dx_pointer
 #define _POINTER _ABSTRACT(dx_pointer)
 #define _RESOURCE _ABSTRACT(dx_resource)
 
-DEFINE_PRIM(_DRIVER, create, _ABSTRACT(dx_window) _I32);
+DEFINE_PRIM(_DRIVER, create, _ABSTRACT(dx_window) _I32 _I32);
+DEFINE_PRIM(_BOOL, resize, _I32 _I32 _I32);
 DEFINE_PRIM(_RESOURCE, get_back_buffer, _NO_ARG);
 DEFINE_PRIM(_POINTER, create_render_target_view, _RESOURCE _DYN);
 DEFINE_PRIM(_VOID, om_set_render_targets, _I32 _REF(_POINTER) _POINTER);
 DEFINE_PRIM(_POINTER, create_rasterizer_state, _DYN);
 DEFINE_PRIM(_VOID, rs_set_state, _POINTER);
 DEFINE_PRIM(_VOID, rs_set_viewports, _I32 _BYTES);
+DEFINE_PRIM(_VOID, rs_set_scissor_rects, _I32 _BYTES);
 DEFINE_PRIM(_VOID, clear_color, _POINTER _F64 _F64 _F64 _F64);
-DEFINE_PRIM(_VOID, present, _NO_ARG);
-DEFINE_PRIM(_I32, get_screen_width, _NO_ARG);
-DEFINE_PRIM(_I32, get_screen_height, _NO_ARG);
+DEFINE_PRIM(_VOID, present, _I32 _I32);
 DEFINE_PRIM(_BYTES, get_device_name, _NO_ARG);
 DEFINE_PRIM(_F64, get_supported_version, _NO_ARG);
 DEFINE_PRIM(_RESOURCE, create_buffer, _I32 _I32 _I32 _I32 _I32 _I32 _BYTES);

+ 25 - 12
libs/directx/dx/Driver.hx

@@ -439,11 +439,29 @@ class ShaderResourceViewDesc {
 	}
 }
 
+@:enum abstract PresentFlags(Int) {
+	var None = 0;
+	var Test = 1;
+	var DoNotSequence = 2;
+	var Restart = 4;
+	var DoNotWait = 8;
+	var RestrictToOutput = 0x10;
+	var StereoPreferRight = 0x20;
+	var StereoTemporaryMono = 0x40;
+	var UseDuration = 0x100;
+	var AllowTearing = 0x200;
+	@:op(a | b) static function or(a:PresentFlags, b:PresentFlags) : PresentFlags;
+}
+
 @:hlNative("directx")
 class Driver {
 
-	public static function create( win : Window, flags : DriverInitFlags = None ) {
-		return dxCreate(@:privateAccess win.win, flags);
+	public static function create( win : Window, format : Format, flags : DriverInitFlags = None ) {
+		return dxCreate(@:privateAccess win.win, format, flags);
+	}
+
+	public static function resize( width : Int, height : Int, format : Format ) : Bool {
+		return false;
 	}
 
 	public static function getBackBuffer() : Resource {
@@ -467,24 +485,19 @@ class Driver {
 	public static function rsSetViewports( count : Int, bytes : hl.BytesAccess<hl.F32> ) {
 	}
 
+	public static function rsSetScissorRects( count : Int, rects : hl.BytesAccess<Int> ) {
+	}
+
 	public static function clearColor( rt : RenderTargetView, r : Float, g : Float, b : Float, a : Float ) {
 	}
 
-	public static function present() {
+	public static function present( intervals : Int, flags : PresentFlags ) {
 	}
 
 	public static function getDeviceName() {
 		return @:privateAccess String.fromUCS2(dxGetDeviceName());
 	}
 
-	public static function getScreenWidth() {
-		return 0;
-	}
-
-	public static function getScreenHeight() {
-		return 0;
-	}
-
 	public static function getSupportedVersion() : Float {
 		return 0.;
 	}
@@ -612,7 +625,7 @@ class Driver {
 	}
 
 	@:hlNative("directx","create")
-	static function dxCreate( win : hl.Abstract < "dx_window" > , flags : DriverInitFlags ) : DriverInstance { return null; }
+	static function dxCreate( win : hl.Abstract<"dx_window">, format : Format, flags : DriverInitFlags ) : DriverInstance { return null; }
 
 	@:hlNative("directx","get_device_name")
 	static function dxGetDeviceName() : hl.Bytes { return null; }

+ 22 - 19
libs/directx/dx/Window.hx

@@ -19,11 +19,12 @@ class Window {
 	static var windows : Array<Window> = [];
 
 	var win : WinPtr;
+	var savedSize : { width : Int, height : Int };
 	public var title(default, set) : String;
-	public var vsync(default, set) : Bool;
 	public var width(get, never) : Int;
 	public var height(get, never) : Int;
 	public var displayMode(default, set) : DisplayMode;
+	public var vsync : Bool;
 
 	public function new( title : String, width : Int, height : Int ) {
 		win = winCreate(width, height);
@@ -40,9 +41,19 @@ class Window {
 	function set_displayMode(mode) {
 		if( mode == displayMode )
 			return mode;
-		if( winSetFullscreen(win, cast mode) )
-			displayMode = mode;
-		return displayMode;
+		displayMode = mode;
+		var fs = mode != Windowed;
+		if( savedSize == null ) {
+			if( !fs ) return mode;
+			savedSize = { width : width, height : height };
+			winSetFullscreen(win,true);
+		} else {
+			if( fs ) return mode;
+			winSetFullscreen(win, false);
+			resize(savedSize.width, savedSize.height);
+			savedSize = null;
+		}
+		return mode;
 	}
 
 	public function resize( width : Int, height : Int ) {
@@ -61,15 +72,6 @@ class Window {
 		return h;
 	}
 
-	function set_vsync(v) {
-		winSetVsync(win,v);
-		return vsync = v;
-	}
-
-	public function present() {
-		winSwapWindow(win);
-	}
-
 	public function destroy() {
 		winDestroy(win);
 		win = null;
@@ -95,11 +97,7 @@ class Window {
 	static function winSetTitle( win : WinPtr, title : hl.Bytes ) {
 	}
 
-	static function winSwapWindow( win : WinPtr ) {
-	}
-
-	static function winSetFullscreen( win : WinPtr, mode : DisplayMode ) {
-		return false;
+	static function winSetFullscreen( win : WinPtr, fs : Bool ) {
 	}
 
 	static function winSetSize( win : WinPtr, width : Int, height : Int ) {
@@ -114,7 +112,12 @@ class Window {
 	static function winDestroy( win : WinPtr ) {
 	}
 
-	static function winSetVsync( win : WinPtr, b : Bool ) {
+	public static function getScreenWidth() {
+		return 0;
+	}
+
+	public static function getScreenHeight() {
+		return 0;
 	}
 
 }

+ 117 - 116
libs/directx/window.c

@@ -1,116 +1,117 @@
-#define HL_NAME(n) directx_##n
-#include <hl.h>
-
-typedef struct HWND__ dx_window;
-
-static LRESULT CALLBACK WndProc( HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam ) {
-	switch(umsg) {
-	case WM_DESTROY:
-		PostQuitMessage(0);
-		return 0;
-	default:
-		return DefWindowProc(hwnd, umsg, wparam, lparam);
-	}
-}
-
-HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
-	static bool wnd_class_reg = false;
-	if( !wnd_class_reg ) {
-		WNDCLASSEX wc;
-		wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-		wc.lpfnWndProc   = WndProc;
-		wc.cbClsExtra    = 0;
-		wc.cbWndExtra    = 0;
-		wc.hInstance     = GetModuleHandle(NULL);
-		wc.hIcon		 = LoadIcon(NULL, IDI_WINLOGO);
-		wc.hIconSm       = wc.hIcon;
-		wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
-		wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
-		wc.lpszMenuName  = NULL;
-		wc.lpszClassName = USTR("HL_WIN");
-		wc.cbSize        = sizeof(WNDCLASSEX);
-		RegisterClassEx(&wc);
-	}
-
-	RECT r;
-	DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
-	r.left = r.top = 0;
-	r.right = width;
-	r.bottom = height;
-	AdjustWindowRect(&r,style,false);
-	dx_window *win = CreateWindowEx(WS_EX_APPWINDOW, USTR("HL_WIN"), USTR(""), style, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, GetModuleHandle(NULL), NULL);
-	ShowWindow(win, SW_SHOW);
-	SetForegroundWindow(win);
-	SetFocus(win);
-	return win;
-}
-
-HL_PRIM void HL_NAME(win_set_title)(dx_window *win, vbyte *title) {
-	SetWindowText(win,(LPCWSTR)title);
-}
-
-HL_PRIM void HL_NAME(win_set_size)(dx_window *win, int width, int height) {
-	RECT r;
-	GetWindowRect(win,&r);
-	r.left = r.top = 0;
-	r.right = width;
-	r.bottom = height;
-	AdjustWindowRectEx(&r,GetWindowLong(win,GWL_STYLE),GetMenu(win) != NULL,GetWindowLong(win,GWL_EXSTYLE));
-	SetWindowPos(win,NULL,0,0,r.right - r.left,r.bottom - r.top,SWP_NOMOVE|SWP_NOOWNERZORDER);
-}
-
-HL_PRIM void HL_NAME(win_get_size)(dx_window *win, int *width, int *height) {
-	RECT r;
-	GetClientRect(win,&r);
-	if( width ) *width = r.right;
-	if( height ) *height = r.bottom;
-}
-
-HL_PRIM void HL_NAME(win_resize)(dx_window *win, int mode) {
-	switch( mode ) {
-	case 0:
-		ShowWindow(win, SW_MAXIMIZE);
-		break;
-	case 1:
-		ShowWindow(win, SW_MINIMIZE);
-		break;
-	case 2:
-		ShowWindow(win, SW_RESTORE);
-		break;
-	default:
-		break;
-	}
-}
-
-
-HL_PRIM bool HL_NAME(win_set_fullscreen)(dx_window *win, int mode) {
-	switch( mode ) {
-	case 0: // WINDOWED
-	case 1: // FULLSCREEN
-	case 2: // BORDERLESS
-		;
-	}
-	return false;
-}
-
-HL_PRIM void HL_NAME(win_swap_window)(dx_window *win) {
-}
-
-HL_PRIM void HL_NAME(win_destroy)(dx_window *win) {
-	DestroyWindow(win);
-}
-
-HL_PRIM void HL_NAME(win_set_vsync)(dx_window *win, bool vsync) {
-}
-
-#define TWIN _ABSTRACT(dx_window)
-DEFINE_PRIM(TWIN, win_create, _I32 _I32);
-DEFINE_PRIM(_BOOL, win_set_fullscreen, TWIN _I32);
-DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
-DEFINE_PRIM(_VOID, win_set_title, TWIN _BYTES);
-DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
-DEFINE_PRIM(_VOID, win_get_size, TWIN _REF(_I32) _REF(_I32));
-DEFINE_PRIM(_VOID, win_swap_window, TWIN);
-DEFINE_PRIM(_VOID, win_destroy, TWIN);
-DEFINE_PRIM(_VOID, win_set_vsync, TWIN _BOOL);
-
+#define HL_NAME(n) directx_##n
+#include <hl.h>
+
+typedef struct HWND__ dx_window;
+
+static LRESULT CALLBACK WndProc( HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam ) {
+	switch(umsg) {
+	case WM_DESTROY:
+		PostQuitMessage(0);
+		return 0;
+	default:
+		return DefWindowProc(hwnd, umsg, wparam, lparam);
+	}
+}
+
+HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
+	static bool wnd_class_reg = false;
+	if( !wnd_class_reg ) {
+		WNDCLASSEX wc;
+		wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+		wc.lpfnWndProc   = WndProc;
+		wc.cbClsExtra    = 0;
+		wc.cbWndExtra    = 0;
+		wc.hInstance     = GetModuleHandle(NULL);
+		wc.hIcon		 = LoadIcon(NULL, IDI_WINLOGO);
+		wc.hIconSm       = wc.hIcon;
+		wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
+		wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+		wc.lpszMenuName  = NULL;
+		wc.lpszClassName = USTR("HL_WIN");
+		wc.cbSize        = sizeof(WNDCLASSEX);
+		RegisterClassEx(&wc);
+	}
+
+	RECT r;
+	DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+	r.left = r.top = 0;
+	r.right = width;
+	r.bottom = height;
+	AdjustWindowRect(&r,style,false);
+	dx_window *win = CreateWindowEx(WS_EX_APPWINDOW, USTR("HL_WIN"), USTR(""), style, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, GetModuleHandle(NULL), NULL);
+	ShowWindow(win, SW_SHOW);
+	SetForegroundWindow(win);
+	SetFocus(win);
+	return win;
+}
+
+HL_PRIM void HL_NAME(win_set_title)(dx_window *win, vbyte *title) {
+	SetWindowText(win,(LPCWSTR)title);
+}
+
+HL_PRIM void HL_NAME(win_set_size)(dx_window *win, int width, int height) {
+	RECT r;
+	GetWindowRect(win,&r);
+	r.left = r.top = 0;
+	r.right = width;
+	r.bottom = height;
+	AdjustWindowRectEx(&r,GetWindowLong(win,GWL_STYLE),GetMenu(win) != NULL,GetWindowLong(win,GWL_EXSTYLE));
+	SetWindowPos(win,NULL,0,0,r.right - r.left,r.bottom - r.top,SWP_NOMOVE|SWP_NOOWNERZORDER);
+}
+
+HL_PRIM void HL_NAME(win_get_size)(dx_window *win, int *width, int *height) {
+	RECT r;
+	GetClientRect(win,&r);
+	if( width ) *width = r.right;
+	if( height ) *height = r.bottom;
+}
+
+HL_PRIM void HL_NAME(win_resize)(dx_window *win, int mode) {
+	switch( mode ) {
+	case 0:
+		ShowWindow(win, SW_MAXIMIZE);
+		break;
+	case 1:
+		ShowWindow(win, SW_MINIMIZE);
+		break;
+	case 2:
+		ShowWindow(win, SW_RESTORE);
+		break;
+	default:
+		break;
+	}
+}
+
+
+HL_PRIM void HL_NAME(win_set_fullscreen)(dx_window *win, bool fs) {
+	if( fs ) {
+		SetWindowLong(win,GWL_STYLE,WS_POPUPWINDOW);
+		SetWindowPos(win,NULL,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SWP_NOOWNERZORDER);
+	} else {
+		SetWindowLong(win,GWL_STYLE,WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
+	}
+}
+
+HL_PRIM void HL_NAME(win_destroy)(dx_window *win) {
+	DestroyWindow(win);
+}
+
+HL_PRIM int HL_NAME(get_screen_width)() {
+	return GetSystemMetrics(SM_CXSCREEN);
+}
+
+HL_PRIM int HL_NAME(get_screen_height)() {
+	return GetSystemMetrics(SM_CYSCREEN);
+}
+
+#define TWIN _ABSTRACT(dx_window)
+DEFINE_PRIM(TWIN, win_create, _I32 _I32);
+DEFINE_PRIM(_VOID, win_set_fullscreen, TWIN _BOOL);
+DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
+DEFINE_PRIM(_VOID, win_set_title, TWIN _BYTES);
+DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
+DEFINE_PRIM(_VOID, win_get_size, TWIN _REF(_I32) _REF(_I32));
+DEFINE_PRIM(_VOID, win_destroy, TWIN);
+
+DEFINE_PRIM(_I32, get_screen_width, _NO_ARG);
+DEFINE_PRIM(_I32, get_screen_height, _NO_ARG);