[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25969] trunk/blender/intern/ghost: Patch [#20588] Adding multisample support to Win32 Ghost - by Mitchell Stokes ( Moguri)

Nathan Letwory jesterking at letwory.net
Wed Jan 13 20:02:14 CET 2010


Revision: 25969
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25969
Author:   jesterking
Date:     2010-01-13 20:02:13 +0100 (Wed, 13 Jan 2010)

Log Message:
-----------
Patch [#20588]  Adding multisample support to Win32 Ghost - by Mitchell Stokes (Moguri)

Note: AA is still disabled due to AA creating problems for selection tools. If you must, set AA to 2 or 4 in wm_window.c where the GHOST window is created (line 317).

Modified Paths:
--------------
    trunk/blender/intern/ghost/CMakeLists.txt
    trunk/blender/intern/ghost/SConscript
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h

Modified: trunk/blender/intern/ghost/CMakeLists.txt
===================================================================
--- trunk/blender/intern/ghost/CMakeLists.txt	2010-01-13 19:00:18 UTC (rev 25968)
+++ trunk/blender/intern/ghost/CMakeLists.txt	2010-01-13 19:02:13 UTC (rev 25969)
@@ -24,7 +24,7 @@
 #
 # ***** END GPL LICENSE BLOCK *****
 
-SET(INC . ../string)
+SET(INC . ../string ../../extern/glew/include)
 
 FILE(GLOB SRC intern/*.cpp intern/*.mm)
 

Modified: trunk/blender/intern/ghost/SConscript
===================================================================
--- trunk/blender/intern/ghost/SConscript	2010-01-13 19:00:18 UTC (rev 25968)
+++ trunk/blender/intern/ghost/SConscript	2010-01-13 19:02:13 UTC (rev 25969)
@@ -57,7 +57,7 @@
 if env['BF_GHOST_DEBUG']:
 	defs.append('BF_GHOST_DEBUG')
 	
-incs = '. ../string ' + env['BF_OPENGL_INC']
+incs = '. ../string #extern/glew/include ' + env['BF_OPENGL_INC']
 if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
 	incs = env['BF_WINTAB_INC'] + ' ' + incs
 env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] ) 

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2010-01-13 19:00:18 UTC (rev 25968)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2010-01-13 19:02:13 UTC (rev 25969)
@@ -193,7 +193,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);
+	window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples);
 	if (window) {
 		if (window->getValid()) {
 			// Store the pointer to the window
@@ -202,8 +202,18 @@
 //			}
 		}
 		else {
+			// An invalid window could be one that was used to test for AA
+			GHOST_Window *other_window = ((GHOST_WindowWin32*)window)->getNextWindow();
+
 			delete window;
 			window = 0;
+			
+			// If another window is found, let the wm know about that one, but not the old one
+			if (other_window)
+			{
+				m_windowManager->addWindow(other_window);
+				window = other_window;
+			}
 		}
 	}
 	return window;

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2010-01-13 19:00:18 UTC (rev 25968)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2010-01-13 19:02:13 UTC (rev 25969)
@@ -42,7 +42,10 @@
 #include "GHOST_WindowWin32.h"
 #include "GHOST_SystemWin32.h"
 #include "GHOST_DropTargetWin32.h"
-#include <GL/gl.h>
+
+// Need glew for some defines
+#include <GL/glew.h>
+#include <GL/wglew.h>
 #include <math.h>
 
 // MSVC6 still doesn't define M_PI
@@ -50,6 +53,10 @@
 #define M_PI 3.1415926536
 #endif
 
+// Some more multisample defines
+#define WGL_SAMPLE_BUFERS_ARB	0x2041
+#define	WGL_SAMPLES_ARB			0x2042
+
 // win64 doesn't define GWL_USERDATA
 #ifdef WIN32
 #ifndef GWL_USERDATA
@@ -106,7 +113,9 @@
 	GHOST_TWindowState state,
 	GHOST_TDrawingContextType type,
 	const bool stereoVisual,
-	const GHOST_TUns16 numOfAASamples)
+	const GHOST_TUns16 numOfAASamples,
+	GHOST_TSuccess msEnabled,
+	int msPixelFormat)
 :
 	GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone,
 	stereoVisual,numOfAASamples),
@@ -119,7 +128,18 @@
 	m_wintab(NULL),
 	m_tabletData(NULL),
 	m_tablet(0),
-	m_maxPressure(0)
+	m_maxPressure(0),
+	m_multisample(numOfAASamples),
+	m_multisampleEnabled(msEnabled),
+	m_msPixelFormat(msPixelFormat),
+	//For recreation
+	m_title(title),
+	m_left(left),
+	m_top(top),
+	m_width(width),
+	m_height(height),
+	m_stereo(stereoVisual),
+	m_nextWindow(NULL)
 {
 	if (state != GHOST_kWindowStateFullScreen) {
 		RECT rect;
@@ -195,10 +215,20 @@
 				nCmdShow = SW_SHOWNORMAL;
 				break;
 		}
-		setDrawingContextType(type);
-		::ShowWindow(m_hWnd, nCmdShow);
-		// Force an initial paint of the window
-		::UpdateWindow(m_hWnd);
+		GHOST_TSuccess success;
+		success = setDrawingContextType(type);
+
+		if (success)
+		{
+			::ShowWindow(m_hWnd, nCmdShow);
+			// Force an initial paint of the window
+			::UpdateWindow(m_hWnd);
+		}
+		else
+		{
+			//invalidate the window
+			m_hWnd = 0;
+		}
 	}
 
 	m_wintab = ::LoadLibrary("Wintab32.dll");
@@ -277,6 +307,8 @@
 		m_customCursor = NULL;
 	}
 
+	m_multisampleEnabled = GHOST_kFailure;
+	m_multisample = 0;
 	setDrawingContextType(GHOST_kDrawingContextTypeNone);
 	if (m_hDC) {
 		::ReleaseDC(m_hWnd, m_hDC);
@@ -289,6 +321,11 @@
 	}
 }
 
+GHOST_Window *GHOST_WindowWin32::getNextWindow()
+{
+	return m_nextWindow;
+}
+
 bool GHOST_WindowWin32::getValid() const
 {
 	return m_hWnd != 0;
@@ -516,44 +553,172 @@
 	return success;
 }
 
+GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
+{
+	int pixelFormat;
+	bool success;
+	UINT numFormats;
+	HDC hDC = GetDC(getHWND());
+	float fAttributes[] = {0, 0};
 
+	// The attributes to look for
+	int iAttributes[] = {
+		WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+		WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+		WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+		WGL_COLOR_BITS_ARB, pfd.cColorBits,
+		WGL_DEPTH_BITS_ARB, pfd.cDepthBits,
+		WGL_STENCIL_BITS_ARB, pfd.cStencilBits,
+		WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+		WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
+		WGL_SAMPLES_ARB, m_multisample,
+		0, 0
+	};
+
+	// Get the function
+	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");	
+
+	if (!wglChoosePixelFormatARB)
+	{
+		m_multisampleEnabled = GHOST_kFailure;
+		return GHOST_kFailure;
+	}
+
+	// See if the format is valid
+	success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
+
+	if (success && numFormats >= 1)
+	{
+		m_multisampleEnabled = GHOST_kSuccess;
+		m_msPixelFormat = pixelFormat;
+		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...
+	return GHOST_kFailure;
+}
+
 GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextType type)
 {
 	GHOST_TSuccess success;
 	switch (type) {
 	case GHOST_kDrawingContextTypeOpenGL:
 		{
-		if(m_stereoVisual)
-			sPreferredFormat.dwFlags |= PFD_STEREO;
+		// If this window has multisample enabled, use the supplied format
+		if (m_multisampleEnabled)
+		{
+			if (SetPixelFormat(m_hDC, m_msPixelFormat, &sPreferredFormat)==FALSE)
+			{
+				success = GHOST_kFailure;
+				break;
+			}
 
-		// Attempt to match device context pixel format to the preferred format
-		int iPixelFormat = EnumPixelFormats(m_hDC);
-		if (iPixelFormat == 0) {
-			success = GHOST_kFailure;
-			break;
+			// Create the context
+			m_hGlRc = ::wglCreateContext(m_hDC);
+			if (m_hGlRc) {
+				if (s_firsthGLRc) {
+					wglShareLists(s_firsthGLRc, m_hGlRc);
+				} else {
+					s_firsthGLRc = m_hGlRc;
+				}
+
+				success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+			}
+			else {
+				printf("Failed to get a context....\n");
+				success = GHOST_kFailure;
+			}
 		}
-		if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) {
-			success = GHOST_kFailure;
-			break;
-		}
-		// For debugging only: retrieve the pixel format chosen
-		PIXELFORMATDESCRIPTOR preferredFormat;
-		::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &preferredFormat);
-		// Create the context
-		m_hGlRc = ::wglCreateContext(m_hDC);
-		if (m_hGlRc) {
-			if (s_firsthGLRc) {
-				wglShareLists(s_firsthGLRc, m_hGlRc);
-			} else {
-				s_firsthGLRc = m_hGlRc;
+		else
+		{
+			if(m_stereoVisual)
+				sPreferredFormat.dwFlags |= PFD_STEREO;
+
+			// Attempt to match device context pixel format to the preferred format
+			int iPixelFormat = EnumPixelFormats(m_hDC);
+			if (iPixelFormat == 0) {
+				success = GHOST_kFailure;
+				break;
 			}
+			if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) {
+				success = GHOST_kFailure;
+				break;
+			}
+			// For debugging only: retrieve the pixel format chosen
+			PIXELFORMATDESCRIPTOR preferredFormat;
+			::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &preferredFormat);
 
-			success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+			// Create the context
+			m_hGlRc = ::wglCreateContext(m_hDC);
+			if (m_hGlRc) {
+				if (s_firsthGLRc) {
+					wglShareLists(s_firsthGLRc, m_hGlRc);
+				} else {
+					s_firsthGLRc = m_hGlRc;
+				}
+
+				success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+			}
+			else {
+				printf("Failed to get a context....\n");
+				success = GHOST_kFailure;
+			}
+					
+			// Attempt to enable multisample
+			if (m_multisample && WGL_ARB_multisample && !m_multisampleEnabled)
+			{
+				success = initMultisample(preferredFormat);
+
+				if (success)
+				{
+
+					// Make sure we don't screw up the context
+					m_drawingContextType = GHOST_kDrawingContextTypeOpenGL;
+					removeDrawingContext();
+
+					// Create a new window
+					GHOST_TWindowState new_state = getState();
+
+					m_nextWindow = new GHOST_WindowWin32((GHOST_SystemWin32*)GHOST_ISystem::getSystem(),
+													m_title,
+													m_left,
+													m_top,
+													m_width,
+													m_height,
+													new_state,
+													type,
+													m_stereo,
+													m_multisample,
+													m_multisampleEnabled,
+													m_msPixelFormat);
+
+					// Return failure so we can trash this window.
+					success = GHOST_kFailure;
+					break;
+				}
+			}
 		}
-		else {
-			success = GHOST_kFailure;
+
 		}
-		}
 		break;
 
 	case GHOST_kDrawingContextTypeNone:
@@ -566,7 +731,6 @@
 	return success;
 }
 
-
 GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
 {
 	GHOST_TSuccess success;

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list