Browse Source

Updated sample shell library with provisions for allowing the shell windows to resize, handle resize events, or lock to one size

David Wimsey 11 years ago
parent
commit
9d815185de

+ 4 - 0
Build/cmake/SampleFileList.cmake

@@ -5,6 +5,7 @@ set(shell_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Samples/shell/include/Shell.h
     ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellFileInterface.h
     ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellOpenGL.h
+    ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellRenderInterfaceExtensions.h
     ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellRenderInterfaceOpenGL.h
     ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellSystemInterface.h
 )
@@ -261,6 +262,7 @@ if(WIN32)
        list(APPEND shell_SRC_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/ShellWin32.cpp
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/InputWin32.cpp
+               ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/ShellRenderInterfaceExtensionsOpenGL_Win32.cpp
        )
        list(APPEND shell_HDR_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/include/win32/InputWin32.h
@@ -269,6 +271,7 @@ elseif(APPLE)
        list(APPEND shell_SRC_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/ShellMacOSX.cpp
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/InputMacOSX.cpp
+               ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp
        )
        list(APPEND shell_HDR_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/include/macosx/InputMacOSX.h
@@ -277,6 +280,7 @@ else()
        list(APPEND shell_SRC_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/ShellX11.cpp
                ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/InputX11.cpp
+               ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/ShellRenderInterfaceExtensionsOpenGL_X11.cpp
        )
        list(APPEND shell_HDR_FILES
                ${PROJECT_SOURCE_DIR}/Samples/shell/include/x11/InputX11.h

+ 3 - 0
Build/cmake/gen_samplelists.sh

@@ -38,6 +38,7 @@ echo 'if(WIN32)' >> $file
 echo '       list(APPEND shell_SRC_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/ShellWin32.cpp' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/InputWin32.cpp' >> $file
+echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/win32/ShellRenderInterfaceExtensionsOpenGL_Win32.cpp' >> $file
 echo '       )' >> $file
 echo '       list(APPEND shell_HDR_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/include/win32/InputWin32.h' >> $file
@@ -46,6 +47,7 @@ echo 'elseif(APPLE)' >> $file
 echo '       list(APPEND shell_SRC_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/ShellMacOSX.cpp' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/InputMacOSX.cpp' >> $file
+echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp' >> $file
 echo '       )' >> $file
 echo '       list(APPEND shell_HDR_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/include/macosx/InputMacOSX.h' >> $file
@@ -54,6 +56,7 @@ echo 'else()' >> $file
 echo '       list(APPEND shell_SRC_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/ShellX11.cpp' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/InputX11.cpp' >> $file
+echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/src/x11/ShellRenderInterfaceExtensionsOpenGL_X11.cpp' >> $file
 echo '       )' >> $file
 echo '       list(APPEND shell_HDR_FILES' >> $file
 echo '               ${PROJECT_SOURCE_DIR}/Samples/shell/include/x11/InputX11.h' >> $file

+ 10 - 7
Samples/basic/customlog/src/main.cpp

@@ -33,14 +33,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -60,18 +61,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/basic/customlog/") ||
-		!Shell::OpenWindow("Custom File Handler Sample", true))
+		!Shell::OpenWindow("Custom File Handler Sample", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024,768);
+	opengl_renderer.SetViewport(1024,768);
 
 
 	// Initialise our system interface to write the log messages to file.

+ 10 - 7
Samples/basic/drag/src/main.cpp

@@ -33,14 +33,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -60,18 +61,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/basic/drag/") ||
-		!Shell::OpenWindow("Drag Sample", true))
+		!Shell::OpenWindow("Drag Sample", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024,768);
+	opengl_renderer.SetViewport(1024,768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 7
Samples/basic/loaddocument/src/main.cpp

@@ -32,14 +32,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -59,18 +60,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/basic/loaddocument/") ||
-		!Shell::OpenWindow("Load Document Sample", true))
+		!Shell::OpenWindow("Load Document Sample", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024,768);
+	shell_renderer->SetViewport(1024,768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 8
Samples/basic/treeview/src/main.cpp

@@ -35,14 +35,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -62,18 +63,19 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/basic/treeview/") ||
-		!Shell::OpenWindow("Tree View Sample", true))
+		!Shell::OpenWindow("Tree View Sample", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
-    opengl_renderer.SetViewport(1024,768);
-
+	opengl_renderer.SetViewport(1024,768);
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
 
 	ShellSystemInterface system_interface;

+ 9 - 5
Samples/invaders/src/main.cpp

@@ -44,13 +44,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
 	context->Update();
 
-	glClear(GL_COLOR_BUFFER_BIT);
+	shell_renderer->PrepareRenderBuffer();
 	context->Render();
-	Shell::FlipBuffers();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -60,18 +62,20 @@ int APIENTRY WinMain(HINSTANCE, HINSTANCE, char*, int)
 int main(int, char**)
 #endif
 {
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/invaders/") ||
-		!Shell::OpenWindow("Rocket Invaders from Mars", true))
+		!Shell::OpenWindow("Rocket Invaders from Mars", shell_renderer, 1024, 768, false))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024,768);
+	opengl_renderer.SetViewport(1024,768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 8 - 4
Samples/luainvaders/src/main.cpp

@@ -44,13 +44,15 @@ Rocket::Core::Context* context = NULL;
 
 void DoAllocConsole();
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
 	context->Update();
 
-	glClear(GL_COLOR_BUFFER_BIT);
+	shell_renderer->PrepareRenderBuffer();
 	context->Render();
-	Shell::FlipBuffers();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -72,16 +74,18 @@ int main(int, char**)
 	DoAllocConsole();
 	#endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/luainvaders/") ||
-		!Shell::OpenWindow("Rocket Invaders from Mars (Lua Powered)", true))
+		!Shell::OpenWindow("Rocket Invaders from Mars (Lua Powered)", shell_renderer, 1024, 768, false))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
 	opengl_renderer.SetViewport(1024,768);
 

+ 9 - 4
Samples/pyinvaders/src/main.cpp

@@ -42,13 +42,15 @@ Rocket::Core::Context* context = NULL;
 
 void DoAllocConsole();
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
 	context->Update();
 
-	glClear(GL_COLOR_BUFFER_BIT);
+	shell_renderer->PrepareRenderBuffer();
 	context->Render();
-	Shell::FlipBuffers();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -80,17 +82,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	DoAllocConsole();
 	#endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/pyinvaders/") ||
-		!Shell::OpenWindow("Rocket Invaders from Mars (Python Powered)", true))
+		!Shell::OpenWindow("Rocket Invaders from Mars (Python Powered)", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
+	opengl_renderer.SetViewport(1024,768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 6
Samples/shell/include/Shell.h

@@ -29,7 +29,9 @@
 #define ROCKETSHELL_H
 
 #include <Rocket/Core/Types.h>
+#include <Rocket/Core/Context.h>
 #include <Rocket/Core/SystemInterface.h>
+#include <ShellRenderInterfaceExtensions.h>
 
 #ifdef ROCKET_PLATFORM_WIN32
 #define PATH_SEPARATOR	";"
@@ -59,17 +61,14 @@ public:
 
 	/// Open a platform specific window, optionally initialising an OpenGL context on it.
 	/// @param[in] title Title of the window.
-	/// @param[in] attach_opengl Attach and opengl context to the window.
-	static bool OpenWindow(const char* title, bool attach_opengl);
+	/// @param[in] srie Provides the interface for attaching a renderer to the window and performing related bits of interface.
+	static bool OpenWindow(const char* title, ShellRenderInterfaceExtensions *_shell_renderer, unsigned int width, unsigned int height, bool allow_resize);
 	/// Close the active window.
 	static void CloseWindow();
 
 	/// Returns a platform-dependent handle to the window.
 	static void* GetWindowHandle();
 
-	/// Flips the OpenGL buffers.
-	static void FlipBuffers();
-
 	/// Run the event loop, calling the idle function every frame.
 	typedef void (*ShellIdleFunction)();
 	static void EventLoop(ShellIdleFunction idle_function);
@@ -81,10 +80,15 @@ public:
 	static void Log(const char* fmt, ...);
 
 	/// Get the number of seconds that have passed since shell startup.
-	static float GetElapsedTime();	
+	static float GetElapsedTime();
+	
+	/// Sets the context to send window resized events to.
+	/// @param[in] context The context to send  events to.
+	static void SetContext(Rocket::Core::Context* context);
 
 private:
 	static Rocket::Core::String executable_path;
+	static Rocket::Core::Context* context;
 };
 
 #include "ShellRenderInterfaceOpenGL.h"

+ 2 - 0
Samples/shell/include/ShellOpenGL.h

@@ -36,10 +36,12 @@
 #include <gl/Gl.h>
 #include <gl/Glu.h>
 #elif defined ROCKET_PLATFORM_MACOSX
+#include <AGL/agl.h>
 #include <OpenGL/gl.h>
 #include <OpenGL/glu.h>
 #include <OpenGL/glext.h>
 #elif defined ROCKET_PLATFORM_UNIX
+#include <GL/glx.h>
 #include <GL/gl.h>
 #include <GL/glext.h>
 #include <GL/glu.h>

+ 66 - 0
Samples/shell/include/ShellRenderInterfaceExtensions.h

@@ -0,0 +1,66 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2014, David Wimsey
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETSHELLRENDERINTERFACE_H
+#define ROCKETSHELLRENDERINTERFACE_H
+
+/**
+	Extensions to the RenderInterface class used by the Samples Shell to
+ 	handle various bits of rendering and rendering upkeep that would normally
+ 	be handled by the application rather than the libRocket RenderInterface class.
+	@author David Wimsey
+ */
+
+class ShellRenderInterfaceExtensions
+{
+public:
+    /**
+     * @param[in] width width of viewport
+     * @param[in] height height of viewport
+	 */
+    virtual void SetViewport(int width, int height) = 0;
+	
+    /**
+	 * @param[in] context Rocket::Core::Context to set dimensions on when SetViewport is called
+     */
+    virtual void SetContext(void *context) = 0;
+	
+	/// Attach the internal window buffer to a native window
+	/// @param[in] nativeWindow A handle to the OS specific native window handle
+	virtual bool AttachToNative(void *nativeWindow) = 0;
+	
+	/// Detach and cleanup the internal window buffer from a native window
+	virtual void DetachFromNative(void) = 0;
+	
+	/// Prepares the render buffer for drawing, in OpenGL, this would call glClear();
+	virtual void PrepareRenderBuffer(void) = 0;
+
+	/// Presents the rendered framebuffer to the screen, in OpenGL this would cal glSwapBuffers();
+	virtual void PresentRenderBuffer(void) = 0;
+};
+
+#endif

+ 37 - 10
Samples/shell/include/ShellRenderInterfaceOpenGL.h

@@ -25,8 +25,8 @@
  *
  */
 
-#ifndef ROCKETSHELLRENDERINTERFACE_H
-#define ROCKETSHELLRENDERINTERFACE_H
+#ifndef ROCKETSHELLRENDERINTERFACEOPENGL_H
+#define ROCKETSHELLRENDERINTERFACEOPENGL_H
 
 #include "Rocket/Core/RenderInterface.h"
 #include "ShellOpenGL.h"
@@ -36,17 +36,20 @@
 	@author Peter Curry
  */
 
-class ShellRenderInterfaceOpenGL : public Rocket::Core::RenderInterface
+#if defined(ROCKET_PLATFORM_LINUX)
+struct __X11NativeWindowData
+{
+	Window window;
+	Display *display;
+	XVisualInfo *visual_info;
+};
+#endif
+
+class ShellRenderInterfaceOpenGL : public Rocket::Core::RenderInterface,  public ShellRenderInterfaceExtensions
 {
 public:
 	ShellRenderInterfaceOpenGL();
 
-    /**
-     * @p width width of viewport
-     * @p height height of viewport
-     */
-    void SetViewport(int width, int height);
-
 	/// Called by Rocket when it wants to render geometry that it does not wish to optimise.
 	virtual void RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation);
 
@@ -70,9 +73,33 @@ public:
 	/// Called by Rocket when a loaded texture is no longer required.
 	virtual void ReleaseTexture(Rocket::Core::TextureHandle texture_handle);
 
-private:
+
+// ShellRenderInterfaceExtensions
+	virtual void SetViewport(int width, int height);
+	virtual void SetContext(void *context);
+	virtual bool AttachToNative(void *nativeWindow);
+	virtual void DetachFromNative(void);
+	virtual void PrepareRenderBuffer(void);
+	virtual void PresentRenderBuffer(void);
+
+protected:
 	int m_width;
 	int m_height;
+	void *m_rocket_context;
+	
+#if defined(ROCKET_PLATFORM_MACOSX)
+	AGLContext gl_context;
+#elif defined(ROCKET_PLATFORM_LINUX)
+	struct __X11NativeWindowData nwData;
+	GLXContext gl_context;
+#elif defined(ROCKET_PLATFORM_WIN32)
+	HWND window_handle;
+	HDC device_context;
+	HGLRC render_context;
+#else
+#error Platform is undefined, this must be resolved so gl_context is usable.
+#endif
+
 };
 
 #endif

+ 4 - 7
Samples/shell/src/ShellRenderInterfaceOpenGL.cpp

@@ -25,6 +25,7 @@
  *
  */
 
+#include <ShellRenderInterfaceExtensions.h>
 #include <ShellRenderInterfaceOpenGL.h>
 #include <Rocket/Core.h>
 
@@ -32,15 +33,11 @@
 
 ShellRenderInterfaceOpenGL::ShellRenderInterfaceOpenGL()
 {
+	m_rocket_context = NULL;
+	m_width = 0;
+	m_height = 0;
 }
 
-void ShellRenderInterfaceOpenGL::SetViewport(int width, int height)
-{
-    m_width = width;
-    m_height = height;
-}
-
-
 // Called by Rocket when it wants to render geometry that it does not wish to optimise.
 void ShellRenderInterfaceOpenGL::RenderGeometry(Rocket::Core::Vertex* vertices, int ROCKET_UNUSED_PARAMETER(num_vertices), int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation)
 {

+ 29 - 68
Samples/shell/src/macosx/ShellMacOSX.cpp

@@ -48,12 +48,10 @@ static const EventTypeSpec INPUT_EVENTS[] = {
 
 static const EventTypeSpec WINDOW_EVENTS[] = {
 	{ kEventClassWindow, kEventWindowClose },
+	{ kEventClassWindow, kEventWindowBoundsChanged },
 };
 
 static WindowRef window;
-static CGrafPtr window_port = NULL;
-static AGLContext gl_context = NULL;
-static bool opengl_attached = false;
 static timeval start_time;
 
 ShellFileInterface* file_interface = NULL;
@@ -95,12 +93,16 @@ void Shell::Shutdown()
 	file_interface = NULL;
 }
 
-bool Shell::OpenWindow(const char* name, bool attach_opengl)
+static ShellRenderInterfaceExtensions *shell_renderer;
+
+bool Shell::OpenWindow(const char* name, ShellRenderInterfaceExtensions *_shell_renderer, unsigned int width, unsigned int height, bool allow_resize)
 {
-	Rect content_bounds = { 60, 20, 60 + 768, 20 + 1024 };
+	shell_renderer = _shell_renderer;
+	Rect content_bounds = { 60, 20, 60 + height, 20 + width };
 
 	OSStatus result = CreateNewWindow(kDocumentWindowClass,
-									  kWindowCloseBoxAttribute | kWindowStandardHandlerAttribute,
+									  (allow_resize ? (kWindowStandardDocumentAttributes | kWindowLiveResizeAttribute) :
+									   kWindowCloseBoxAttribute) | kWindowStandardHandlerAttribute,
 									  &content_bounds,
 									  &window);
 	if (result != noErr)
@@ -120,68 +122,17 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 	CFRelease(window_title);
 
 	ShowWindow(window);
-
-	if (attach_opengl)
-	{
-		static GLint attributes[] =
-		{
-			AGL_RGBA,
-			AGL_DOUBLEBUFFER,
-			AGL_ALPHA_SIZE, 8,
-			AGL_DEPTH_SIZE, 24,
-			AGL_STENCIL_SIZE, 8,
-			AGL_ACCELERATED,
-			AGL_NONE
-		};
-
-		AGLPixelFormat pixel_format = aglChoosePixelFormat(NULL, 0, attributes);
-		if (pixel_format == NULL)
-			return false;
-
-		window_port = GetWindowPort(window);
-		if (window_port == NULL)
-			return false;
-
-		gl_context = aglCreateContext(pixel_format, NULL);
-		if (gl_context == NULL)
-			return false;
-
-		aglSetDrawable(gl_context, window_port);
-		aglSetCurrentContext(gl_context);
-
-		aglDestroyPixelFormat(pixel_format);
-		
-		// Set up the GL state.
-		glClearColor(0, 0, 0, 1);
-		glEnableClientState(GL_VERTEX_ARRAY);
-		glEnableClientState(GL_COLOR_ARRAY);
-
-		glEnable(GL_BLEND);
-		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-		glMatrixMode(GL_PROJECTION);
-		glLoadIdentity();
-		glOrtho(0, 1024, 768, 0, -1, 1);
-
-		glMatrixMode(GL_MODELVIEW);
-		glLoadIdentity();
-
-		opengl_attached = true;
-	}
     
+	if(shell_renderer != NULL) {
+		shell_renderer->AttachToNative(window);
+	}
     return true;
 }
 
 void Shell::CloseWindow()
 {
-	// Shutdown OpenGL if necessary.
-	if (opengl_attached)
-	{
-		aglSetCurrentContext(NULL);
-		aglSetDrawable(gl_context, NULL);
-		aglDestroyContext(gl_context);
-		
-		gl_context = NULL;
+	if(shell_renderer) {
+		shell_renderer->DetachFromNative();
 	}
 
 	// Close the window.
@@ -189,12 +140,6 @@ void Shell::CloseWindow()
 	ReleaseWindow(window);
 }
 
-// Flips the OpenGL buffers.
-void Shell::FlipBuffers()
-{
-	aglSwapBuffers(gl_context);
-}
-
 void Shell::EventLoop(ShellIdleFunction idle_function)
 {
 	OSStatus error;
@@ -313,6 +258,22 @@ static OSStatus EventHandler(EventHandlerCallRef next_handler, EventRef event, v
 				case kEventWindowClose:
 					Shell::RequestExit();
 					break;
+				case kEventWindowBoundsChanged:
+					// Window resized, update the rocket context
+					UInt32 attributes;
+					GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(UInt32), NULL, &attributes);
+
+					if(attributes & kWindowBoundsChangeSizeChanged)
+					{
+						Rect bounds;
+						GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds);
+
+						UInt32 width = bounds.right - bounds.left;
+						UInt32 height = bounds.bottom - bounds.top;
+
+						shell_renderer->SetViewport(width, height);
+					}
+					break;
 			}
 		}
 		break;

+ 125 - 0
Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp

@@ -0,0 +1,125 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include <ShellRenderInterfaceExtensions.h>
+#include <ShellRenderInterfaceOpenGL.h>
+#include <Carbon/Carbon.h>
+#include <Rocket/Core/Context.h>
+#include <Rocket/Core.h>
+#include <Rocket/Core/Platform.h>
+
+void ShellRenderInterfaceOpenGL::SetContext(void *context)
+{
+	m_rocket_context = context;
+}
+
+void ShellRenderInterfaceOpenGL::SetViewport(int width, int height)
+{
+	if(m_width != width || m_height != height) {
+		m_width = width;
+		m_height = height;
+
+		glViewport(0, 0, width, height);
+		glMatrixMode(GL_PROJECTION);
+		glLoadIdentity();
+		glOrtho(0, width, height, 0, -1, 1);
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+
+		aglUpdateContext(gl_context);
+	}
+	if(m_rocket_context != NULL)
+	{
+		((Rocket::Core::Context*)m_rocket_context)->SetDimensions(Rocket::Core::Vector2i(width, height));
+	}
+}
+
+bool ShellRenderInterfaceOpenGL::AttachToNative(void *nativeWindow)
+{
+	WindowRef window = (WindowRef)nativeWindow;
+	static GLint attributes[] =
+	{
+		AGL_RGBA,
+		AGL_DOUBLEBUFFER,
+		AGL_ALPHA_SIZE, 8,
+		AGL_DEPTH_SIZE, 24,
+		AGL_STENCIL_SIZE, 8,
+		AGL_ACCELERATED,
+		AGL_NONE
+	};
+	
+	AGLPixelFormat pixel_format = aglChoosePixelFormat(NULL, 0, attributes);
+	if (pixel_format == NULL)
+		return false;
+	
+	CGrafPtr window_port = GetWindowPort(window);
+	if (window_port == NULL)
+		return false;
+	
+	this->gl_context = aglCreateContext(pixel_format, NULL);
+	if (this->gl_context == NULL)
+		return false;
+	
+	aglSetDrawable(this->gl_context, window_port);
+	aglSetCurrentContext(this->gl_context);
+	
+	aglDestroyPixelFormat(pixel_format);
+	
+	// Set up the GL state.
+	glClearColor(0, 0, 0, 1);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_COLOR_ARRAY);
+	
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, 1024, 768, 0, -1, 1);
+	
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+}
+
+void ShellRenderInterfaceOpenGL::DetachFromNative()
+{
+	// Shutdown OpenGL if necessary.
+	aglSetCurrentContext(NULL);
+	aglSetDrawable(this->gl_context, NULL);
+	aglDestroyContext(this->gl_context);
+}
+
+void ShellRenderInterfaceOpenGL::PrepareRenderBuffer()
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void ShellRenderInterfaceOpenGL::PresentRenderBuffer()
+{
+	// Flips the OpenGL buffers.
+	aglSwapBuffers(this->gl_context);
+}

+ 155 - 0
Samples/shell/src/win32/ShellRenderInterfaceExtensionsOpenGL_Win32.cpp

@@ -0,0 +1,155 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include <ShellRenderInterfaceExtensions.h>
+#include <ShellRenderInterfaceOpenGL.h>
+#include <windows.h>
+#include <Rocket/Core.h>
+#include <Rocket/Core/Platform.h>
+#include <Shell.h>
+
+void ShellRenderInterfaceOpenGL::SetContext(void *context)
+{
+	m_rocket_context = context;
+}
+
+void ShellRenderInterfaceOpenGL::SetViewport(int width, int height)
+{
+	if(m_width != width || m_height != height) {
+		m_width = width;
+		m_height = height;
+		
+		glViewport(0, 0, width, height);
+		glMatrixMode(GL_PROJECTION);
+		glLoadIdentity();
+		glOrtho(0, width, height, 0, -1, 1);
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+	}
+	if(m_rocket_context != NULL)
+	{
+		((Rocket::Core::Context*)m_rocket_context)->SetDimensions(Rocket::Core::Vector2i(width, height));
+	}
+}
+
+bool ShellRenderInterfaceOpenGL::AttachToNative(void *nativeWindow)
+{
+	this->render_context = NULL;
+	this->window_handle = (HWND)nativeWindow;
+	this->device_context = GetDC(this->window_handle);
+	if (this->device_context == NULL)
+	{
+		Shell::DisplayError("Could not get device context.");
+		return false;
+	}
+
+	PIXELFORMATDESCRIPTOR pixel_format_descriptor;
+	memset(&pixel_format_descriptor, 0, sizeof(pixel_format_descriptor));
+	pixel_format_descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+	pixel_format_descriptor.nVersion = 1;
+	pixel_format_descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+	pixel_format_descriptor.iPixelType = PFD_TYPE_RGBA;
+	pixel_format_descriptor.cColorBits = 32;
+	pixel_format_descriptor.cRedBits = 8;
+	pixel_format_descriptor.cGreenBits = 8;
+	pixel_format_descriptor.cBlueBits = 8;
+	pixel_format_descriptor.cAlphaBits = 8;
+	pixel_format_descriptor.cDepthBits = 24;
+	pixel_format_descriptor.cStencilBits = 8;
+
+	int pixel_format = ChoosePixelFormat(this->device_context, &pixel_format_descriptor);
+	if (pixel_format == 0)
+	{
+		Shell::DisplayError("Could not choose 32-bit pixel format.");
+		return false;
+	}
+
+	if (SetPixelFormat(this->device_context, pixel_format, &pixel_format_descriptor) == FALSE)
+	{
+		Shell::DisplayError("Could not set pixel format.");
+		return false;
+	}
+
+	this->render_context = wglCreateContext(this->device_context);
+	if (this->render_context == NULL)
+	{ 
+		Shell::DisplayError("Could not create OpenGL rendering context.");
+		return false;
+	}
+
+	// Activate the rendering context.
+	if (wglMakeCurrent(this->device_context, this->render_context) == FALSE)
+	{
+		Shell::DisplayError("Unable to make rendering context current.");
+		return false;
+	}
+
+	// Set up the GL state.
+	glClearColor(0, 0, 0, 1);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_COLOR_ARRAY);
+
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, 1024, 768, 0, -1, 1);
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	return true;
+}
+
+void ShellRenderInterfaceOpenGL::DetachFromNative()
+{
+	// Shutdown OpenGL
+	if (this->render_context != NULL)
+	{
+		wglMakeCurrent(NULL, NULL); 
+		wglDeleteContext(this->render_context);
+		this->render_context = NULL;
+	}
+
+	if (this->device_context != NULL)
+	{
+		ReleaseDC(this->window_handle, this->device_context);
+		this->device_context = NULL;
+	}
+}
+
+void ShellRenderInterfaceOpenGL::PrepareRenderBuffer()
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void ShellRenderInterfaceOpenGL::PresentRenderBuffer()
+{
+	// Flips the OpenGL buffers.
+	SwapBuffers(this->device_context);
+}

+ 19 - 110
Samples/shell/src/win32/ShellWin32.cpp

@@ -32,18 +32,13 @@
 #include <windows.h>
 #include <stdio.h>
 
-static bool AttachOpenGL();
-static void DetachOpenGL();
 static LRESULT CALLBACK WindowProcedure(HWND window_handle, UINT message, WPARAM w_param, LPARAM l_param);
 
 static bool activated = true;
 static bool running = false;
-static bool opengl_attached = false;
 static const char* instance_name = NULL;
 static HWND window_handle = NULL;
 static HINSTANCE instance_handle = NULL;
-static HDC device_context = NULL;
-static HGLRC render_context = NULL;
 
 static double time_frequency;
 static LARGE_INTEGER time_startup;
@@ -83,7 +78,8 @@ void Shell::Shutdown()
 	file_interface = NULL;
 }
 
-bool Shell::OpenWindow(const char* name, bool attach_opengl)
+static ShellRenderInterfaceExtensions *shell_renderer = NULL;
+bool Shell::OpenWindow(const char* name, ShellRenderInterfaceExtensions *_shell_renderer, unsigned int width, unsigned int height, bool allow_resize)
 {
 	WNDCLASS window_class;
 
@@ -112,7 +108,7 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 								   name,
 								   WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
 								   0, 0,	// Window position.
-								   0, 0,	// Window size.
+								   width, height,// Window size.
 								   NULL,
 								   NULL,
 								   instance_handle,
@@ -127,15 +123,15 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 
 	instance_name = name;
 
-	DWORD style = WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX;
+	DWORD style = (allow_resize ? WS_OVERLAPPEDWINDOW : (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX));
 	DWORD extended_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
 
 	// Adjust the window size to take into account the edges
 	RECT window_rect;
 	window_rect.top = 0;
 	window_rect.left = 0;
-	window_rect.right = 1024;
-	window_rect.bottom = 768;
+	window_rect.right = width;
+	window_rect.bottom = height;
 	AdjustWindowRectEx(&window_rect, style, FALSE, extended_style);
 
 	SetWindowLong(window_handle, GWL_EXSTYLE, extended_style);
@@ -149,12 +145,10 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 	SetForegroundWindow(window_handle);
 	SetFocus(window_handle);
 
-	// Attach OpenGL if necessary
-	if (attach_opengl)
+	if (_shell_renderer != NULL)
 	{
-		opengl_attached = AttachOpenGL();
-		if (!opengl_attached)
-			return false;
+		shell_renderer = _shell_renderer;
+		return(shell_renderer->AttachToNative(window_handle));
 	}
 
     return true;
@@ -162,11 +156,8 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 
 void Shell::CloseWindow()
 {
-	// Shutdown opengl if necessary
-	if (opengl_attached)
-	{
-		DetachOpenGL();
-		opengl_attached = false;
+	if(shell_renderer) {
+		shell_renderer->DetachFromNative();
 	}
 
 	DestroyWindow(window_handle);  
@@ -179,12 +170,6 @@ void* Shell::GetWindowHandle()
 	return window_handle;
 }
 
-// Flips the OpenGL buffers.
-void Shell::FlipBuffers()
-{
-	SwapBuffers(device_context);
-}
-
 void Shell::EventLoop(ShellIdleFunction idle_function)
 {
 	MSG message;
@@ -261,90 +246,6 @@ float Shell::GetElapsedTime()
 	return (float)((counter.QuadPart - time_startup.QuadPart) * time_frequency);
 }
 
-static bool AttachOpenGL()
-{
-	device_context = GetDC(window_handle);
-	if (device_context == NULL)
-	{
-		Shell::DisplayError("Could not get device context.");
-		return false;
-	}
-
-	PIXELFORMATDESCRIPTOR pixel_format_descriptor;
-	memset(&pixel_format_descriptor, 0, sizeof(pixel_format_descriptor));
-	pixel_format_descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
-	pixel_format_descriptor.nVersion = 1;
-	pixel_format_descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
-	pixel_format_descriptor.iPixelType = PFD_TYPE_RGBA;
-	pixel_format_descriptor.cColorBits = 32;
-	pixel_format_descriptor.cRedBits = 8;
-	pixel_format_descriptor.cGreenBits = 8;
-	pixel_format_descriptor.cBlueBits = 8;
-	pixel_format_descriptor.cAlphaBits = 8;
-	pixel_format_descriptor.cDepthBits = 24;
-	pixel_format_descriptor.cStencilBits = 8;
-
-	int pixel_format = ChoosePixelFormat(device_context, &pixel_format_descriptor);
-	if (pixel_format == 0)
-	{
-		Shell::DisplayError("Could not choose 32-bit pixel format.");
-		return false;
-	}
-
-	if (SetPixelFormat(device_context, pixel_format, &pixel_format_descriptor) == FALSE)
-	{
-		Shell::DisplayError("Could not set pixel format.");
-		return false;
-	}
-
-	render_context = wglCreateContext(device_context);
-	if (render_context == NULL)
-	{ 
-		Shell::DisplayError("Could not create OpenGL rendering context.");
-		return false;
-	}
-
-	// Activate the rendering context.
-	if (wglMakeCurrent(device_context, render_context) == FALSE)
-	{
-		Shell::DisplayError("Unable to make rendering context current.");
-		return false;
-	}
-
-	// Set up the GL state.
-	glClearColor(0, 0, 0, 1);
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
-
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrtho(0, 1024, 768, 0, -1, 1);
-
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-
-	return true;
-}
-
-static void DetachOpenGL()
-{
-	if (render_context != NULL)
-	{
-		wglMakeCurrent(NULL, NULL); 
-		wglDeleteContext(render_context);
-		render_context = NULL;
-	}
-
-	if (device_context != NULL)
-	{
-		ReleaseDC(window_handle, device_context);
-		device_context = NULL;
-	}
-}
-
 static LRESULT CALLBACK WindowProcedure(HWND window_handle, UINT message, WPARAM w_param, LPARAM l_param)
 {
 	// See what kind of message we've got.
@@ -371,6 +272,14 @@ static LRESULT CALLBACK WindowProcedure(HWND window_handle, UINT message, WPARAM
 		}
 		break;
 
+		case WM_SIZE:
+		{
+			int width = LOWORD(l_param);;
+			int height = HIWORD(l_param);;
+			shell_renderer->SetViewport(width, height);
+		}
+		break;
+
 		default:
 		{
 			InputWin32::ProcessWindowsEvent(message, w_param, l_param);

+ 118 - 0
Samples/shell/src/x11/ShellRenderInterfaceExtensionsOpenGL_X11.cpp

@@ -0,0 +1,118 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include <ShellRenderInterfaceExtensions.h>
+#include <ShellRenderInterfaceOpenGL.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/xf86vmode.h>
+#include <Rocket/Core.h>
+#include <Rocket/Core/Platform.h>
+#include "../../include/Shell.h"
+
+void ShellRenderInterfaceOpenGL::SetContext(void *context)
+{
+	m_rocket_context = context;
+}
+
+
+void ShellRenderInterfaceOpenGL::SetViewport(int width, int height)
+{
+	if(m_width != width || m_height != height) {
+		m_width = width;
+		m_height = height;
+		
+		glViewport(0, 0, width, height);
+		glMatrixMode(GL_PROJECTION);
+		glLoadIdentity();
+		glOrtho(0, width, height, 0, -1, 1);
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+	}
+	if(m_rocket_context != NULL)
+	{
+		((Rocket::Core::Context*)m_rocket_context)->SetDimensions(Rocket::Core::Vector2i(width, height));
+	}
+}
+
+bool ShellRenderInterfaceOpenGL::AttachToNative(void *nativeWindow)
+{
+	this->nwData.display = ((__X11NativeWindowData *)nativeWindow)->display;
+	this->nwData.window = ((__X11NativeWindowData *)nativeWindow)->window;
+	this->nwData.visual_info = ((__X11NativeWindowData *)nativeWindow)->visual_info;
+
+	this->gl_context = glXCreateContext(nwData.display, nwData.visual_info, NULL, GL_TRUE);
+	if (this->gl_context == NULL)
+		return false;
+	
+	if (!glXMakeCurrent(nwData.display, nwData.window, this->gl_context))
+		return false;
+	
+	if (!glXIsDirect(nwData.display, this->gl_context))
+		Shell::Log("OpenGL context does not support direct rendering; performance is likely to be poor.");
+
+	Window root_window;
+	int x, y;
+	unsigned int width, height;
+	unsigned int border_width, depth;
+	XGetGeometry(nwData.display, nwData.window, &root_window, &x, &y, &width, &height, &border_width, &depth);
+	
+	// Set up the GL state.
+	glClearColor(0, 0, 0, 1);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_COLOR_ARRAY);
+	
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, 1024, 768, 0, -1, 1);
+	
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	return true;
+}
+
+void ShellRenderInterfaceOpenGL::DetachFromNative()
+{
+	// Shutdown OpenGL	
+	glXMakeCurrent(this->nwData.display, None, NULL);
+	glXDestroyContext(this->nwData.display, this->gl_context);
+	this->gl_context = NULL;
+}
+
+void ShellRenderInterfaceOpenGL::PrepareRenderBuffer()
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void ShellRenderInterfaceOpenGL::PresentRenderBuffer()
+{
+
+	// Flips the OpenGL buffers.
+	glXSwapBuffers(this->nwData.display, this->nwData.window);
+}

+ 46 - 73
Samples/shell/src/x11/ShellX11.cpp

@@ -31,8 +31,6 @@
 #include <x11/InputX11.h>
 #include <X11/Xlib.h>
 #include <X11/extensions/xf86vmode.h>
-#include <GL/glx.h>
-#include <GL/gl.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <time.h>
@@ -40,11 +38,7 @@
 #include <stdio.h>
 
 static bool running = false;
-static Display* display = NULL;
 static int screen = -1;
-static XVisualInfo* visual_info = NULL;
-static Window window = 0;
-static GLXContext gl_context = NULL;
 static timeval start_time;
 
 static ShellFileInterface* file_interface = NULL;
@@ -68,11 +62,14 @@ void Shell::Shutdown()
 	file_interface = NULL;
 }
 
-bool Shell::OpenWindow(const char* name, bool attach_opengl)
-{
-	unsigned int width = 1024;
-	unsigned int height = 768;
+static Display* display = NULL;
+static XVisualInfo* visual_info = NULL;
+static Window window = 0;
+
+static ShellRenderInterfaceExtensions *shell_renderer = NULL;
 
+bool Shell::OpenWindow(const char* name, ShellRenderInterfaceExtensions *_shell_renderer, unsigned int width, unsigned int height, bool allow_resize)
+{
 	display = XOpenDisplay(0);
 	if (display == NULL)
 		return false;
@@ -130,76 +127,56 @@ bool Shell::OpenWindow(const char* name, bool attach_opengl)
 								  PointerMotionMask |
 								  StructureNotifyMask);
 
-	// Force the window to remain at the fixed size by asking the window manager nicely, it may choose to ignore us
-	XSizeHints* win_size_hints = XAllocSizeHints();		// Allocate a size hint structure
-	if (win_size_hints == NULL)
-	{
-		fprintf(stderr, "XAllocSizeHints - out of memory\n");
-	}
-	else
+	if(!allow_resize)
 	{
-		// Initialize the structure and specify which hints will be providing
-		win_size_hints->flags = PSize | PMinSize | PMaxSize;
-
-		// Set the sizes we want the window manager to use
-		win_size_hints->base_width = width;
-		win_size_hints->base_height = height;
-		win_size_hints->min_width = width;
-		win_size_hints->min_height = height;
-		win_size_hints->max_width = width;
-		win_size_hints->max_height = height;
-
-		// {ass the size hints to the window manager.
-		XSetWMNormalHints(display, window, win_size_hints);
-
-		// Free the size buffer
-		XFree(win_size_hints);
+		// Force the window to remain at the fixed size by asking the window manager nicely, it may choose to ignore us
+		XSizeHints* win_size_hints = XAllocSizeHints();		// Allocate a size hint structure
+		if (win_size_hints == NULL)
+		{
+			fprintf(stderr, "XAllocSizeHints - out of memory\n");
+		}
+		else
+		{
+			// Initialize the structure and specify which hints will be providing
+			win_size_hints->flags = PSize | PMinSize | PMaxSize;
+
+			// Set the sizes we want the window manager to use
+			win_size_hints->base_width = width;
+			win_size_hints->base_height = height;
+			win_size_hints->min_width = width;
+			win_size_hints->min_height = height;
+			win_size_hints->max_width = width;
+			win_size_hints->max_height = height;
+
+			// {ass the size hints to the window manager.
+			XSetWMNormalHints(display, window, win_size_hints);
+
+			// Free the size buffer
+			XFree(win_size_hints);
+		}
 	}
 
 	// Set the window title and show the window.
 	XSetStandardProperties(display, window, name, "", None, NULL, 0, NULL);
 	XMapRaised(display, window);
 
-	gl_context = glXCreateContext(display, visual_info, NULL, GL_TRUE);
-	if (gl_context == NULL)
-		return false;
-
-	if (!glXMakeCurrent(display, window, gl_context))
-		return false;
-
-	if (!glXIsDirect(display, gl_context))
-		Log("OpenGL context does not support direct rendering; performance is likely to be poor.");
-
-	Window root_window;
-	int x, y;
-	unsigned int border_width, depth;
-	XGetGeometry(display, window, &root_window, &x, &y, &width, &height, &border_width, &depth);
-
-	// Set up the GL state.
-	glClearColor(0, 0, 0, 1);
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
-
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrtho(0, width, height, 0, -1, 1);
-
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-
+	shell_renderer = _shell_renderer;
+	if(shell_renderer != NULL)
+	{
+		struct __X11NativeWindowData nwData;
+		nwData.display = display;
+		nwData.window = window;
+		nwData.visual_info = visual_info;
+		return shell_renderer->AttachToNative(&nwData);
+	}
     return true;
 }
 
 void Shell::CloseWindow()
 {
-	if (gl_context != NULL)
+	if(shell_renderer != NULL)
 	{
-		glXMakeCurrent(display, None, NULL);
-		glXDestroyContext(display, gl_context);
-		gl_context = NULL;
+		shell_renderer->DetachFromNative();
 	}
 
 	if (display != NULL)
@@ -215,12 +192,6 @@ void* Shell::GetWindowHandle()
 	return NULL;
 }
 
-// Flips the OpenGL buffers.
-void Shell::FlipBuffers()
-{
-	glXSwapBuffers(display, window);
-}
-
 void Shell::EventLoop(ShellIdleFunction idle_function)
 {
 	running = true;
@@ -252,6 +223,8 @@ void Shell::EventLoop(ShellIdleFunction idle_function)
 				{
 					int x = event.xconfigure.width;
 					int y = event.xconfigure.height;
+
+					shell_renderer->SetViewport(x, y);
 				}
 				break;
 				

+ 10 - 7
Samples/tutorial/datagrid/src/main.cpp

@@ -19,14 +19,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -46,18 +47,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/tutorial/datagrid/") ||
-		!Shell::OpenWindow("Datagrid Tutorial", true))
+		!Shell::OpenWindow("Datagrid Tutorial", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024,768);
+	opengl_renderer.SetViewport(1024,768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 7
Samples/tutorial/datagrid_tree/src/main.cpp

@@ -20,14 +20,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -47,18 +48,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/tutorial/datagrid_tree/") ||
-		!Shell::OpenWindow("Datagrid Tree Tutorial", true))
+		!Shell::OpenWindow("Datagrid Tree Tutorial", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024, 768);
+	opengl_renderer.SetViewport(1024, 768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 7
Samples/tutorial/template/src/main.cpp

@@ -16,14 +16,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -43,18 +44,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/tutorial/template/") ||
-		!Shell::OpenWindow("Template Tutorial", true))
+		!Shell::OpenWindow("Template Tutorial", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024, 768);
+	opengl_renderer.SetViewport(1024, 768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);

+ 10 - 7
Samples/tutorial/tutorial_drag/src/main.cpp

@@ -17,14 +17,15 @@
 
 Rocket::Core::Context* context = NULL;
 
+ShellRenderInterfaceExtensions *shell_renderer;
+
 void GameLoop()
 {
-	glClear(GL_COLOR_BUFFER_BIT);
-
 	context->Update();
-	context->Render();
 
-	Shell::FlipBuffers();
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -44,18 +45,20 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
 	// Generic OS initialisation, creates a window and attaches OpenGL.
 	if (!Shell::Initialise("../Samples/tutorial/tutorial_drag/") ||
-		!Shell::OpenWindow("Drag Tutorial", true))
+		!Shell::OpenWindow("Drag Tutorial", shell_renderer, 1024, 768, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
 	// Rocket initialisation.
-	ShellRenderInterfaceOpenGL opengl_renderer;
 	Rocket::Core::SetRenderInterface(&opengl_renderer);
-    opengl_renderer.SetViewport(1024, 768);
+	opengl_renderer.SetViewport(1024, 768);
 
 	ShellSystemInterface system_interface;
 	Rocket::Core::SetSystemInterface(&system_interface);