for those interested, i've recently updated to Irrlicht 1.3 (svn rev 574) and therefore needed to update my patch-set. One of the patches i use deals with rendering to multiple output windows when using Open GL.
Please find the patch below:
Code: Select all
diff -uBb -x .cbp Irrlicht.svn/CNullDriver.cpp Irrlicht/CNullDriver.cpp
--- Irrlicht.svn/CNullDriver.cpp Tue Mar 27 12:00:41 2007
+++ Irrlicht/CNullDriver.cpp Sat Mar 31 09:50:29 2007
@@ -197,6 +197,11 @@
}
+bool CNullDriver::setRenderWindow(s32 windowId)
+{
+ return true;
+}
+
//! applications must call this method after performing any rendering. returns false if failed.
bool CNullDriver::endScene( s32 windowId, core::rect<s32>* sourceRect )
diff -uBb -x .cbp Irrlicht.svn/CNullDriver.h Irrlicht/CNullDriver.h
--- Irrlicht.svn/CNullDriver.h Tue Mar 27 12:00:37 2007
+++ Irrlicht/CNullDriver.h Sat Mar 31 09:50:03 2007
@@ -35,6 +35,8 @@
virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color);
+ virtual bool setRenderWindow(s32 windowId);
+
virtual bool endScene( s32 windowId = 0, core::rect<s32>* sourceRect=0 );
//! queries the features of the driver, returns true if feature is available
diff -uBb -x .cbp Irrlicht.svn/COpenGLDriver.cpp Irrlicht/COpenGLDriver.cpp
--- Irrlicht.svn/COpenGLDriver.cpp Tue Mar 27 12:00:40 2007
+++ Irrlicht/COpenGLDriver.cpp Sat Mar 31 10:11:20 2007
@@ -69,7 +69,28 @@
bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
HWND window, u32 bits, bool fullscreen, bool vsync)
{
- static PIXELFORMATDESCRIPTOR pfd = {
+ currentHDC = HDc = getGLContext(window, bits);
+ Window = window;
+ bpp = bits;
+
+ genericDriverInit(screenSize);
+
+ // set vsync
+ if (wglSwapIntervalEXT)
+ wglSwapIntervalEXT(vsync ? 1 : 0);
+
+ // set exposed data
+ ExposedData.OpenGLWin32.HDc = reinterpret_cast<s32>(HDc);
+ ExposedData.OpenGLWin32.HRc = reinterpret_cast<s32>(HRc);
+ ExposedData.OpenGLWin32.HWnd = reinterpret_cast<s32>(Window);
+
+ return true;
+}
+
+//! initializes a GL context for a given window ID
+HDC COpenGLDriver::getGLContext(HWND window, u32 bits)
+{
+ PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
@@ -90,87 +111,98 @@
0, 0, 0 // Layer Masks Ignored
};
+ if(glcontext.size() > 0 && window == Window)
+ {
+ if(currentHDC != HDc)
+ wglMakeCurrent(HDc, HRc);
+
+ return HDc;
+ }
+
+ struct SGLContext *glc = NULL;
+
+ for (u32 i=0; i<glcontext.size(); i++)
+ {
+ if(window == glcontext[i].hwnd)
+ {
+ glc = &glcontext[i];
+ wglMakeCurrent(glc->hdc, glc->ctx);
+ return glc->hdc;
+ }
+ }
+
+ glc = new SGLContext();
+ glc->hwnd = window;
+
for (int i=0; i<5; ++i)
{
if (i == 1)
{
- if (StencilBuffer)
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
StencilBuffer = false;
pfd.cStencilBits = 0;
- }
- else
- if (i == 2)
- {
+ }else if (i == 2){
pfd.cDepthBits = 24;
}
if (i == 3) // might be checked twice, but shouldn't matter
{
pfd.cDepthBits = 16;
}
- else
- if (i == 4)
+ else if (i == 2)
{
os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
- return false;
+ return 0;
}
// get hdc
- if (!(HDc=GetDC(window)))
+ if (!(glc->hdc=GetDC(window)))
{
os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
continue;
}
- GLuint PixelFormat;
-
// choose pixelformat
- if (!(PixelFormat = ChoosePixelFormat(HDc, &pfd)))
+ if(glcontext.size() == 0)
+ {
+ if (!(PixelFormat = ChoosePixelFormat(glc->hdc, &pfd)))
{
os::Printer::log("Cannot find a suitable pixelformat.", ELL_ERROR);
continue;
}
+ }
// set pixel format
- if(!SetPixelFormat(HDc, PixelFormat, &pfd))
+ if(!SetPixelFormat(glc->hdc, PixelFormat, &pfd))
{
os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
continue;
}
// create rendering context
- if (!(HRc=wglCreateContext(HDc)))
+ if(glcontext.size() == 0)
+ {
+ if (!(HRc=wglCreateContext(glc->hdc)))
{
os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR);
continue;
}
+ }
+
+ glc->ctx = HRc;
// activate rendering context
- if(!wglMakeCurrent(HDc, HRc))
+ if(!wglMakeCurrent(glc->hdc, glc->ctx))
{
os::Printer::log("Cannot activate GL rendering context", ELL_ERROR);
continue;
}
-
break;
}
-
- genericDriverInit(screenSize);
-
- // set vsync
- if (wglSwapIntervalEXT)
- wglSwapIntervalEXT(vsync ? 1 : 0);
-
- // set exposed data
- ExposedData.OpenGLWin32.HDc = reinterpret_cast<s32>(HDc);
- ExposedData.OpenGLWin32.HRc = reinterpret_cast<s32>(HRc);
- ExposedData.OpenGLWin32.HWnd = reinterpret_cast<s32>(Window);
-
- return true;
+ glcontext.push_back(*glc);
+ return glc->hdc;
}
-
//! win32 destructor
COpenGLDriver::~COpenGLDriver()
{
@@ -756,7 +788,23 @@
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &MaxIndices);
}
+bool COpenGLDriver::setRenderWindow(s32 windowId)
+{
+ RECT r;
+
+ if(!windowId)
+ {
+ currentHDC = getGLContext(Window, bpp);
+ GetClientRect((HWND) Window, &r);
+ }else{
+ currentHDC = getGLContext((HWND) windowId, bpp);
+ GetClientRect((HWND) windowId, &r);
+ }
+ OnResize(core::dimension2d<s32>(r.right, r.bottom));
+
+ return true;
+}
//! presents the rendered scene on the screen, returns false if failed
bool COpenGLDriver::endScene( s32 windowId, core::rect<s32>* sourceRect )
@@ -764,7 +812,7 @@
CNullDriver::endScene( windowId );
#ifdef _IRR_WINDOWS_
- return SwapBuffers(HDc) == TRUE;
+ return SwapBuffers(currentHDC) == TRUE;
#endif
#ifdef LINUX
@@ -2261,7 +2309,7 @@
void COpenGLDriver::OnResize(const core::dimension2d<s32>& size)
{
CNullDriver::OnResize(size);
- glViewport(0, 0, size.Width, size.Height);
+ setViewPort(core::rect<s32>(0, 0, size.Width, size.Height));
}
diff -uBb -x .cbp Irrlicht.svn/COpenGLDriver.h Irrlicht/COpenGLDriver.h
--- Irrlicht.svn/COpenGLDriver.h Tue Mar 27 12:00:39 2007
+++ Irrlicht/COpenGLDriver.h Sat Mar 31 10:15:59 2007
@@ -46,6 +46,20 @@
#endif
#endif
+struct SGLContext
+{
+ SGLContext() {}
+ ~SGLContext() {}
+
+#ifdef _IRR_WINDOWS_
+ HDC hdc;
+ HGLRC ctx;
+ HWND hwnd;
+#endif
+ int width;
+ int height;
+};
+
namespace irr
{
namespace video
@@ -64,6 +78,9 @@
//! inits the windows specific parts of the open gl driver
bool initDriver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool fullscreen, bool vsync);
+
+ //! initializes a GL context for a given window ID
+ HDC getGLContext(HWND window, u32 bits);
#endif
#ifdef LINUX
@@ -85,6 +102,8 @@
//! clears the zbuffer
virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color);
+ virtual bool setRenderWindow(s32 windowId);
+
//! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat);
@@ -433,10 +452,15 @@
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC pGlFramebufferRenderbufferEXT;
#endif
+ core::array<struct SGLContext> glcontext;
+ GLuint PixelFormat;
+
#ifdef _IRR_WINDOWS_
HDC HDc; // Private GDI Device Context
HWND Window;
HGLRC HRc; // Permanent Rendering Context
+ u32 bpp;
+ HDC currentHDC;
#elif defined(LINUX)
GLXDrawable XWindow;
Display* XDisplay;
Therefore i needed to do a tiny extension of the driver-API, to be used like this:
driver->setRenderWindow((s32)GetHandle());
driver->beginScene(true, true, SColor(100, 100, 100, 100));
// ...do some drawing here
driver->endScene();
It's only implemented for the win code path at the moment.
thx for commenting!
bye mrc