[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36470] trunk/blender: Patch [#26799] 2. 5x blenderplayer (BGE) anti-aliasing & embedding by Sebastian Korczak ( with some small tweaks) + adding GHOST_PRINTF

Dalai Felinto dfelinto at gmail.com
Wed May 4 03:50:19 CEST 2011


Revision: 36470
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36470
Author:   dfelinto
Date:     2011-05-04 01:50:17 +0000 (Wed, 04 May 2011)
Log Message:
-----------
Patch [#26799] 2.5x blenderplayer (BGE) anti-aliasing & embedding by Sebastian Korczak (with some small tweaks) + adding GHOST_PRINTF
The patch can also be found in http://codereview.appspot.com/4431072/

##############
This patch fix anti-aliasing (multisampling) implementation for win32 platform. It also gives opportunity to embed blenderplayer inside parent window.

Usage:
blenderplayer.exe -i 123456 -m 16 file.blend

where:
123456 - parent window handler (integer, default: 0)
16 - multisample level (integer, default: 0, max: 16. Put there maximum level you want. If not supported, player will automatically try 15,14,13,...,3,2,1)
##############

This patch was originally created as part of the Burster (aka webplugin) project but benefit any one embedding the bge in a custom OpenGL context. By the way, to embed the BGE in a .Net application is really straightforward now =)
The Multisampling work for blenderplayer as a whole.

Missing functionalities:
- to expose the multisampling to the ui (so far it only works in console)
- window focus and keyboard messages for embedded blenderplayer (supported in their previous patch for 2.49, yet to be ported over)
- handle resizing (to be investigated, indeed the changes in getState() in GHOST_WindowWin32.cpp are going to get in the way of that if I'm not mistaken. To be addressed together.

Doxygen documentation to be added whenever I sort out how to do so. Sorry Nathan too many stuff to deal with at the same time. The sooner this patch gets in, the sooner the missing functionalities can be patched on top of that.

Modified Paths:
--------------
    trunk/blender/intern/ghost/intern/GHOST_Debug.h
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.h
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
    trunk/blender/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp

Modified: trunk/blender/intern/ghost/intern/GHOST_Debug.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_Debug.h	2011-05-03 18:47:16 UTC (rev 36469)
+++ trunk/blender/intern/ghost/intern/GHOST_Debug.h	2011-05-04 01:50:17 UTC (rev 36470)
@@ -53,10 +53,10 @@
 
 #ifdef GHOST_DEBUG
 	#define GHOST_PRINT(x) { std::cout << x; }
-	//#define GHOST_PRINTF(x) { printf(x); }
+	#define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); }
 #else  // GHOST_DEBUG
 	#define GHOST_PRINT(x)
-	//#define GHOST_PRINTF(x)
+	#define GHOST_PRINTF(x, ...)
 #endif // GHOST_DEBUG
 
 

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-05-03 18:47:16 UTC (rev 36469)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-05-04 01:50:17 UTC (rev 36470)
@@ -238,7 +238,7 @@
 	bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
 {
 	GHOST_Window* window = 0;
-	window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples);
+	window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples, parentWindow);
 	if (window) {
 		if (window->getValid()) {
 			// Store the pointer to the window
@@ -247,6 +247,14 @@
 //			}
 		}
 		else {
+
+			// Invalid parent window hwnd
+			if (((GHOST_WindowWin32*)window)->getNextWindow() == NULL) {
+				delete window;
+				window = 0;
+				return window;
+			}
+
 			// An invalid window could be one that was used to test for AA
 			window = ((GHOST_WindowWin32*)window)->getNextWindow();
 			

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2011-05-03 18:47:16 UTC (rev 36469)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2011-05-04 01:50:17 UTC (rev 36470)
@@ -132,6 +132,7 @@
 	GHOST_TDrawingContextType type,
 	const bool stereoVisual,
 	const GHOST_TUns16 numOfAASamples,
+	GHOST_TEmbedderWindowID parentwindowhwnd,
 	GHOST_TSuccess msEnabled,
 	int msPixelFormat)
 :
@@ -149,6 +150,7 @@
 	m_tablet(0),
 	m_maxPressure(0),
 	m_multisample(numOfAASamples),
+	m_parentWindowHwnd(parentwindowhwnd),
 	m_multisampleEnabled(msEnabled),
 	m_msPixelFormat(msPixelFormat),
 	//For recreation
@@ -223,15 +225,26 @@
 		else if(top < monitor.rcWork.top)
 			top = monitor.rcWork.top;
 
+		int wintype = WS_OVERLAPPEDWINDOW;
+		if (m_parentWindowHwnd != 0)
+		{
+			wintype = WS_CHILD;
+			GetWindowRect((HWND)m_parentWindowHwnd, &rect);
+			left = 0;
+			top = 0;
+			width = rect.right - rect.left;
+			height = rect.bottom - rect.top;
+		}
+		
 		m_hWnd = ::CreateWindow(
 			s_windowClassName,			// pointer to registered class name
 			title,						// pointer to window name
-			WS_OVERLAPPEDWINDOW,		// window style
+			wintype,					// window style
 			left,					// horizontal position of window
 			top,					// vertical position of window
 			width,						// window width
 			height,						// window height
-			HWND_DESKTOP,				// handle to parent or owner window
+			(HWND) m_parentWindowHwnd,	// handle to parent or owner window
 			0,							// handle to menu or child-window identifier
 			::GetModuleHandle(0),		// handle to application instance
 			0);							// pointer to window-creation data
@@ -452,6 +465,11 @@
 			bounds.m_l = rect.left + sm_cysizeframe;
 			bounds.m_r = rect.right - sm_cysizeframe;
 			bounds.m_t = rect.top;
+		} else if (state == GHOST_kWindowStateEmbedded) {
+			bounds.m_b = rect.bottom;
+			bounds.m_l = rect.left;
+			bounds.m_r = rect.right;
+			bounds.m_t = rect.top;
 		} else {
 			bounds.m_b = rect.bottom-GetSystemMetrics(SM_CYCAPTION)-sm_cysizeframe*2;
 			bounds.m_l = rect.left;
@@ -459,7 +477,6 @@
 			bounds.m_t = rect.top;
 		}
 	} else {
-		::GetWindowRect(m_hWnd, &rect);
 		bounds.m_b = rect.bottom;
 		bounds.m_l = rect.left;
 		bounds.m_r = rect.right;
@@ -528,6 +545,15 @@
 GHOST_TWindowState GHOST_WindowWin32::getState() const
 {
 	GHOST_TWindowState state;
+
+	// XXX 27.04.2011
+	// we need to find a way to combine parented windows + resizing if we simply set the
+	// state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else.
+	// It's also strange that in Windows is the only platform we need to make this separation.
+	if (m_parentWindowHwnd != 0) {
+		state = GHOST_kWindowStateEmbedded;
+		return state;
+	}
 	if (::IsIconic(m_hWnd)) {
 		state = GHOST_kWindowStateMinimized;
 	}
@@ -589,6 +615,9 @@
 		wp.ptMaxPosition.y = 0;
 		SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_POPUP | WS_MAXIMIZE);
 		break;
+	case GHOST_kWindowStateEmbedded:
+		SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD);
+		break;
 	case GHOST_kWindowStateNormal:
 	default:
 		ShowWindow(m_hWnd, SW_HIDE);
@@ -651,10 +680,11 @@
 GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
 {
 	int pixelFormat;
-	bool success;
+	bool success = FALSE;
 	UINT numFormats;
 	HDC hDC = GetDC(getHWND());
 	float fAttributes[] = {0, 0};
+	UINT nMaxFormats = 1;
 
 	// The attributes to look for
 	int iAttributes[] = {
@@ -679,36 +709,24 @@
 		return GHOST_kFailure;
 	}
 
-	// See if the format is valid
-	success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
+	// iAttributes[17] is the initial multisample. If not valid try to use the closest valid value under it.
+	while (iAttributes[17] > 0) {
+		// See if the format is valid
+		success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, nMaxFormats, &pixelFormat, &numFormats);
+		GHOST_PRINTF("WGL_SAMPLES_ARB = %i --> success = %i, %i formats\n", iAttributes[17], success, numFormats);
 
-	if (success && numFormats >= 1)
-	{
-		m_multisampleEnabled = GHOST_kSuccess;
-		m_msPixelFormat = pixelFormat;
+		if (success && numFormats >= 1 && m_multisampleEnabled == GHOST_kFailure) {
+			GHOST_PRINTF("valid pixel format with %i multisamples\n", iAttributes[17]);
+			m_multisampleEnabled = GHOST_kSuccess;
+			m_msPixelFormat = pixelFormat;
+		}
+		iAttributes[17] -= 1;
+		success = GHOST_kFailure;
+	}
+	if (m_multisampleEnabled == GHOST_kSuccess)	{
 		return GHOST_kSuccess;
 	}
-	else
-	{
-		// See if any formats are supported
-		while (!success && iAttributes[19] != 0)
-		{
-			iAttributes[19] /= 2;
-
-			success = wglChoosePixelFormatARB(m_hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
-
-			if (success && numFormats >= 1)
-			{
-				m_multisampleEnabled = GHOST_kSuccess;
-				m_msPixelFormat = pixelFormat;
-				return GHOST_kSuccess;
-			}
-
-			success = GHOST_kFailure;
-		}
-	}
-
-	// No available pixel format...
+	GHOST_PRINT("no available pixel format\n");
 	return GHOST_kFailure;
 }
 
@@ -856,12 +874,17 @@
 													type,
 													m_stereo,
 													m_multisample,
+													m_parentWindowHwnd,
 													m_multisampleEnabled,
 													m_msPixelFormat);
 
 					// Return failure so we can trash this window.
 					success = GHOST_kFailure;
 					break;
+				} else {
+					m_multisampleEnabled = GHOST_kSuccess;
+					printf("Multisample failed to initialized\n");
+					success = GHOST_kSuccess;
 				}
 			}
 		}

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h	2011-05-03 18:47:16 UTC (rev 36469)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h	2011-05-04 01:50:17 UTC (rev 36470)
@@ -100,6 +100,7 @@
 		GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
 		const bool stereoVisual = false,
 		const GHOST_TUns16 numOfAASamples = 0,
+		GHOST_TEmbedderWindowID parentWindowHwnd=0,
 		GHOST_TSuccess msEnabled = GHOST_kFailure,
 		int msPixelFormat = 0
 	);
@@ -391,6 +392,9 @@
 
 	/** The GHOST_System passes this to wm if this window is being replaced */
 	GHOST_Window *m_nextWindow;
+
+	/** Hwnd to parent window */
+	GHOST_TEmbedderWindowID m_parentWindowHwnd;
 };
 
 #endif // _GHOST_WINDOW_WIN32_H_

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2011-05-03 18:47:16 UTC (rev 36469)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2011-05-04 01:50:17 UTC (rev 36470)
@@ -233,7 +233,8 @@
 bool GPG_Application::startScreenSaverPreview(
 	HWND parentWindow,
 	const bool stereoVisual,
-	const int stereoMode)
+	const int stereoMode,
+	const GHOST_TUns16 samples)
 {
 	bool success = false;
 
@@ -245,7 +246,7 @@
 		STR_String title = "";
 							
 		m_mainWindow = fSystem->createWindow(title, 0, 0, windowWidth, windowHeight, GHOST_kWindowStateMinimized,
-			GHOST_kDrawingContextTypeOpenGL, stereoVisual);
+			GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
 		if (!m_mainWindow) {
 			printf("error: could not create main window\n");
 			exit(-1);
@@ -287,9 +288,10 @@
 		int height,
 		int bpp,int frequency,
 		const bool stereoVisual,
-		const int stereoMode)
+		const int stereoMode,
+		const GHOST_TUns16 samples)
 {
-	bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode);
+	bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode, samples);
 	if (ret)
 	{
 		HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow);
@@ -311,13 +313,14 @@
 	int windowWidth,
 	int windowHeight,
 	const bool stereoVisual,
-	const int stereoMode)
+	const int stereoMode,
+	const GHOST_TUns16 samples)
 {
 	bool success;
 	// Create the main window
 	//STR_String title ("Blender Player - GHOST");
 	m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
-		GHOST_kDrawingContextTypeOpenGL, stereoVisual);
+		GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
 	if (!m_mainWindow) {
 		printf("error: could not create main window\n");
 		exit(-1);
@@ -339,11 +342,14 @@
 bool GPG_Application::startEmbeddedWindow(STR_String& title,
 	const GHOST_TEmbedderWindowID parentWindow, 
 	const bool stereoVisual, 
-	const int stereoMode) {
+	const int stereoMode,
+	const GHOST_TUns16 samples) {
+	GHOST_TWindowState state = GHOST_kWindowStateNormal;
+	if (parentWindow != 0)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list