diff options
author | Nathan Letwory <nathan@letworyinteractive.com> | 2010-01-13 22:02:13 +0300 |
---|---|---|
committer | Nathan Letwory <nathan@letworyinteractive.com> | 2010-01-13 22:02:13 +0300 |
commit | e594a8739bd6a2665e00491b15f59801cbb12a4e (patch) | |
tree | a673a9bcb0c8d804da273337a54431f21d876962 /intern | |
parent | ef5ab2b8e9d58ea5e54bb8cb5a852f6aa392bfd6 (diff) |
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).
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/ghost/SConscript | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 12 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.cpp | 230 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.h | 33 |
5 files changed, 241 insertions, 38 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 77afcc929aa..bf57da23c69 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -24,7 +24,7 @@ # # ***** END GPL LICENSE BLOCK ***** -SET(INC . ../string) +SET(INC . ../string ../../extern/glew/include) FILE(GLOB SRC intern/*.cpp intern/*.mm) diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 2a06a9d3c9e..ff98981a35e 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -57,7 +57,7 @@ else: 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] ) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index d7d657fb496..7d52ab55692 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -193,7 +193,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow( 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 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow( // } } 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; diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index e276f216fb7..16430c7c1b9 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -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_WindowWin32::GHOST_WindowWin32( 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 @@ GHOST_WindowWin32::GHOST_WindowWin32( 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 @@ GHOST_WindowWin32::GHOST_WindowWin32( 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 @@ GHOST_WindowWin32::~GHOST_WindowWin32() 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_WindowWin32::~GHOST_WindowWin32() } } +GHOST_Window *GHOST_WindowWin32::getNextWindow() +{ + return m_nextWindow; +} + bool GHOST_WindowWin32::getValid() const { return m_hWnd != 0; @@ -516,6 +553,69 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate() 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) { @@ -523,36 +623,101 @@ GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextTyp 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; - } - if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) { - 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; + } } - // 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); + + // 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 { - success = GHOST_kFailure; + 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; + } + } } + } break; @@ -566,7 +731,6 @@ GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextTyp return success; } - GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext() { GHOST_TSuccess success; diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 954546f3d82..fb561127a2e 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -87,7 +87,9 @@ public: GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, - const GHOST_TUns16 numOfAASamples = 0 + const GHOST_TUns16 numOfAASamples = 0, + GHOST_TSuccess msEnabled = GHOST_kFailure, + int msPixelFormat = 0 ); /** @@ -97,6 +99,13 @@ public: virtual ~GHOST_WindowWin32(); /** + * Returns the window to replace this one if it's getting replaced + * @return The window replacing this one. + */ + + GHOST_Window *getNextWindow(); + + /** * Returns indication as to whether the window is valid. * @return The validity of the window. */ @@ -243,6 +252,8 @@ public: void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); protected: + GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd); + /** * Tries to install a rendering context in this window. * @param type The type of rendering context installed. @@ -325,7 +336,25 @@ protected: LONG m_maxPressure; LONG m_maxAzimuth, m_maxAltitude; + /** Preferred number of samples */ + GHOST_TUns16 m_multisample; + + /** Check if multisample is supported */ + GHOST_TSuccess m_multisampleEnabled; + + /** The pixelFormat to use for multisample */ + int m_msPixelFormat; + + /** We need to following to recreate the window */ + const STR_String& m_title; + GHOST_TInt32 m_left; + GHOST_TInt32 m_top; + GHOST_TUns32 m_width; + GHOST_TUns32 m_height; + bool m_stereo; + + /** The GHOST_System passes this to wm if this window is being replaced */ + GHOST_Window *m_nextWindow; }; #endif // _GHOST_WINDOW_WIN32_H_ - |