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. @@
_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to