forked from bartvdbraak/blender
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).
This commit is contained in:
parent
ef5ab2b8e9
commit
e594a8739b
@ -24,7 +24,7 @@
|
|||||||
#
|
#
|
||||||
# ***** END GPL LICENSE BLOCK *****
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
|
||||||
SET(INC . ../string)
|
SET(INC . ../string ../../extern/glew/include)
|
||||||
|
|
||||||
FILE(GLOB SRC intern/*.cpp intern/*.mm)
|
FILE(GLOB SRC intern/*.cpp intern/*.mm)
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ else:
|
|||||||
if env['BF_GHOST_DEBUG']:
|
if env['BF_GHOST_DEBUG']:
|
||||||
defs.append('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'):
|
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||||
env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||||
|
@ -193,7 +193,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
|
|||||||
bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
|
bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
|
||||||
{
|
{
|
||||||
GHOST_Window* window = 0;
|
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) {
|
||||||
if (window->getValid()) {
|
if (window->getValid()) {
|
||||||
// Store the pointer to the window
|
// Store the pointer to the window
|
||||||
@ -202,8 +202,18 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// An invalid window could be one that was used to test for AA
|
||||||
|
GHOST_Window *other_window = ((GHOST_WindowWin32*)window)->getNextWindow();
|
||||||
|
|
||||||
delete window;
|
delete window;
|
||||||
window = 0;
|
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;
|
return window;
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
#include "GHOST_WindowWin32.h"
|
#include "GHOST_WindowWin32.h"
|
||||||
#include "GHOST_SystemWin32.h"
|
#include "GHOST_SystemWin32.h"
|
||||||
#include "GHOST_DropTargetWin32.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>
|
#include <math.h>
|
||||||
|
|
||||||
// MSVC6 still doesn't define M_PI
|
// MSVC6 still doesn't define M_PI
|
||||||
@ -50,6 +53,10 @@
|
|||||||
#define M_PI 3.1415926536
|
#define M_PI 3.1415926536
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Some more multisample defines
|
||||||
|
#define WGL_SAMPLE_BUFERS_ARB 0x2041
|
||||||
|
#define WGL_SAMPLES_ARB 0x2042
|
||||||
|
|
||||||
// win64 doesn't define GWL_USERDATA
|
// win64 doesn't define GWL_USERDATA
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifndef GWL_USERDATA
|
#ifndef GWL_USERDATA
|
||||||
@ -106,7 +113,9 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
|||||||
GHOST_TWindowState state,
|
GHOST_TWindowState state,
|
||||||
GHOST_TDrawingContextType type,
|
GHOST_TDrawingContextType type,
|
||||||
const bool stereoVisual,
|
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,
|
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone,
|
||||||
stereoVisual,numOfAASamples),
|
stereoVisual,numOfAASamples),
|
||||||
@ -119,7 +128,18 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
|||||||
m_wintab(NULL),
|
m_wintab(NULL),
|
||||||
m_tabletData(NULL),
|
m_tabletData(NULL),
|
||||||
m_tablet(0),
|
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) {
|
if (state != GHOST_kWindowStateFullScreen) {
|
||||||
RECT rect;
|
RECT rect;
|
||||||
@ -195,10 +215,20 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
|||||||
nCmdShow = SW_SHOWNORMAL;
|
nCmdShow = SW_SHOWNORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setDrawingContextType(type);
|
GHOST_TSuccess success;
|
||||||
::ShowWindow(m_hWnd, nCmdShow);
|
success = setDrawingContextType(type);
|
||||||
// Force an initial paint of the window
|
|
||||||
::UpdateWindow(m_hWnd);
|
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");
|
m_wintab = ::LoadLibrary("Wintab32.dll");
|
||||||
@ -277,6 +307,8 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
|||||||
m_customCursor = NULL;
|
m_customCursor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_multisampleEnabled = GHOST_kFailure;
|
||||||
|
m_multisample = 0;
|
||||||
setDrawingContextType(GHOST_kDrawingContextTypeNone);
|
setDrawingContextType(GHOST_kDrawingContextTypeNone);
|
||||||
if (m_hDC) {
|
if (m_hDC) {
|
||||||
::ReleaseDC(m_hWnd, 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
|
bool GHOST_WindowWin32::getValid() const
|
||||||
{
|
{
|
||||||
return m_hWnd != 0;
|
return m_hWnd != 0;
|
||||||
@ -516,6 +553,69 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
|
|||||||
return success;
|
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 GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextType type)
|
||||||
{
|
{
|
||||||
@ -523,36 +623,101 @@ GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextTyp
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case GHOST_kDrawingContextTypeOpenGL:
|
case GHOST_kDrawingContextTypeOpenGL:
|
||||||
{
|
{
|
||||||
if(m_stereoVisual)
|
// If this window has multisample enabled, use the supplied format
|
||||||
sPreferredFormat.dwFlags |= PFD_STEREO;
|
if (m_multisampleEnabled)
|
||||||
|
{
|
||||||
// Attempt to match device context pixel format to the preferred format
|
if (SetPixelFormat(m_hDC, m_msPixelFormat, &sPreferredFormat)==FALSE)
|
||||||
int iPixelFormat = EnumPixelFormats(m_hDC);
|
{
|
||||||
if (iPixelFormat == 0) {
|
success = GHOST_kFailure;
|
||||||
success = GHOST_kFailure;
|
break;
|
||||||
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;
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
success = GHOST_kFailure;
|
{
|
||||||
|
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 {
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
@ -566,7 +731,6 @@ GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextTyp
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
|
GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
|
||||||
{
|
{
|
||||||
GHOST_TSuccess success;
|
GHOST_TSuccess success;
|
||||||
|
@ -87,7 +87,9 @@ public:
|
|||||||
GHOST_TWindowState state,
|
GHOST_TWindowState state,
|
||||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||||
const bool stereoVisual = false,
|
const bool stereoVisual = false,
|
||||||
const GHOST_TUns16 numOfAASamples = 0
|
const GHOST_TUns16 numOfAASamples = 0,
|
||||||
|
GHOST_TSuccess msEnabled = GHOST_kFailure,
|
||||||
|
int msPixelFormat = 0
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,6 +98,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ~GHOST_WindowWin32();
|
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.
|
* Returns indication as to whether the window is valid.
|
||||||
* @return The validity of the window.
|
* @return The validity of the window.
|
||||||
@ -243,6 +252,8 @@ public:
|
|||||||
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
|
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to install a rendering context in this window.
|
* Tries to install a rendering context in this window.
|
||||||
* @param type The type of rendering context installed.
|
* @param type The type of rendering context installed.
|
||||||
@ -325,7 +336,25 @@ protected:
|
|||||||
LONG m_maxPressure;
|
LONG m_maxPressure;
|
||||||
LONG m_maxAzimuth, m_maxAltitude;
|
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_
|
#endif // _GHOST_WINDOW_WIN32_H_
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user