Pārlūkot izejas kodu

Merge pull request #198 from libRocket/feature/resizable-samples-shell-windows

Make samples shell allow for and handle window resizing
David Wimsey 11 gadi atpakaļ
vecāks
revīzija
b521c28567
32 mainītis faili ar 1260 papildinājumiem un 585 dzēšanām
  1. 6 0
      Build/cmake/SampleFileList.cmake
  2. 3 0
      Build/cmake/gen_samplelists.sh
  3. 11 7
      Samples/basic/customlog/src/main.cpp
  4. 49 14
      Samples/basic/directx/src/RenderInterfaceDirectX.cpp
  5. 12 2
      Samples/basic/directx/src/RenderInterfaceDirectX.h
  6. 152 0
      Samples/basic/directx/src/ShellRenderInterfaceExtensionsDirectX_Win32.cpp
  7. 15 98
      Samples/basic/directx/src/main.cpp
  8. 15 23
      Samples/basic/directx10/src/RenderInterfaceDirectx10.cpp
  9. 22 4
      Samples/basic/directx10/src/RenderInterfaceDirectx10.h
  10. 243 0
      Samples/basic/directx10/src/ShellRenderInterfaceExtensionsDirectX10_Win32.cpp
  11. 12 101
      Samples/basic/directx10/src/main.cpp
  12. 11 7
      Samples/basic/drag/src/main.cpp
  13. 11 7
      Samples/basic/loaddocument/src/main.cpp
  14. 11 8
      Samples/basic/treeview/src/main.cpp
  15. 10 5
      Samples/invaders/src/main.cpp
  16. 9 4
      Samples/luainvaders/src/main.cpp
  17. 10 4
      Samples/pyinvaders/src/main.cpp
  18. 10 6
      Samples/shell/include/Shell.h
  19. 2 0
      Samples/shell/include/ShellOpenGL.h
  20. 66 0
      Samples/shell/include/ShellRenderInterfaceExtensions.h
  21. 37 10
      Samples/shell/include/ShellRenderInterfaceOpenGL.h
  22. 4 7
      Samples/shell/src/ShellRenderInterfaceOpenGL.cpp
  23. 29 68
      Samples/shell/src/macosx/ShellMacOSX.cpp
  24. 125 0
      Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp
  25. 155 0
      Samples/shell/src/win32/ShellRenderInterfaceExtensionsOpenGL_Win32.cpp
  26. 22 109
      Samples/shell/src/win32/ShellWin32.cpp
  27. 118 0
      Samples/shell/src/x11/ShellRenderInterfaceExtensionsOpenGL_X11.cpp
  28. 46 73
      Samples/shell/src/x11/ShellX11.cpp
  29. 11 7
      Samples/tutorial/datagrid/src/main.cpp
  30. 11 7
      Samples/tutorial/datagrid_tree/src/main.cpp
  31. 11 7
      Samples/tutorial/template/src/main.cpp
  32. 11 7
      Samples/tutorial/tutorial_drag/src/main.cpp

+ 6 - 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
 )
@@ -77,6 +78,7 @@ set(directx_HDR_FILES
 set(directx_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Samples/basic/directx/src/main.cpp
     ${PROJECT_SOURCE_DIR}/Samples/basic/directx/src/RenderInterfaceDirectX.cpp
+    ${PROJECT_SOURCE_DIR}/Samples/basic/directx/src/ShellRenderInterfaceExtensionsDirectX_Win32.cpp
 )
 
 set(directx10_HDR_FILES
@@ -87,6 +89,7 @@ set(directx10_HDR_FILES
 set(directx10_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Samples/basic/directx10/src/main.cpp
     ${PROJECT_SOURCE_DIR}/Samples/basic/directx10/src/RenderInterfaceDirectx10.cpp
+    ${PROJECT_SOURCE_DIR}/Samples/basic/directx10/src/ShellRenderInterfaceExtensionsDirectX10_Win32.cpp
 )
 
 set(template_HDR_FILES
@@ -261,6 +264,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 +273,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 +282,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

+ 11 - 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.
@@ -91,6 +94,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 49 - 14
Samples/basic/directx/src/RenderInterfaceDirectX.cpp

@@ -53,10 +53,11 @@ struct RocketD3D9Vertex
 
 DWORD vertex_fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
 
-RenderInterfaceDirectX::RenderInterfaceDirectX(LPDIRECT3D9 _g_pD3D, LPDIRECT3DDEVICE9 _g_pd3dDevice)
+RenderInterfaceDirectX::RenderInterfaceDirectX()
 {
-	g_pD3D = _g_pD3D;
-	g_pd3dDevice = _g_pd3dDevice;
+	g_pD3D = NULL;
+	g_pd3dDevice = NULL;
+	m_rocket_context = NULL;
 }
 
 RenderInterfaceDirectX::~RenderInterfaceDirectX()
@@ -64,23 +65,32 @@ RenderInterfaceDirectX::~RenderInterfaceDirectX()
 }
 
 // Called by Rocket when it wants to render geometry that it does not wish to optimise.
-void RenderInterfaceDirectX::RenderGeometry(Rocket::Core::Vertex* ROCKET_UNUSED_PARAMETER(vertices), int ROCKET_UNUSED_PARAMETER(num_vertices), int* ROCKET_UNUSED_PARAMETER(indices), int ROCKET_UNUSED_PARAMETER(num_indices), const Rocket::Core::TextureHandle ROCKET_UNUSED_PARAMETER(texture), const Rocket::Core::Vector2f& ROCKET_UNUSED_PARAMETER(translation))
+void RenderInterfaceDirectX::RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation)
 {
-	ROCKET_UNUSED(vertices);
-	ROCKET_UNUSED(num_vertices);
-	ROCKET_UNUSED(indices);
-	ROCKET_UNUSED(num_indices);
-	ROCKET_UNUSED(texture);
-	ROCKET_UNUSED(translation);
-
-	// We've chosen to not support non-compiled geometry in the DirectX renderer. If you wanted to render non-compiled
-	// geometry, for example for very small sections of geometry, you could use DrawIndexedPrimitiveUP or write to a
-	// dynamic vertex buffer which is flushed when either the texture changes or compiled geometry is drawn.
+	/// @TODO We've chosen to not support non-compiled geometry in the DirectX renderer. If you wanted to render non-compiled
+	/// geometry, for example for very small sections of geometry, you could use DrawIndexedPrimitiveUP or write to a
+	/// dynamic vertex buffer which is flushed when either the texture changes or compiled geometry is drawn.
+
+	if(g_pd3dDevice == NULL)
+	{
+		return;
+	}
+
+	/// @TODO, HACK, just use the compiled geometry framework for now, this is inefficient but better than absolutely nothing
+	/// for the time being
+	Rocket::Core::CompiledGeometryHandle gemo = this->CompileGeometry(vertices, num_vertices, indices, num_indices, texture);
+	this->RenderCompiledGeometry(gemo, translation);
+	this->ReleaseCompiledGeometry(gemo);
 }
 
 // Called by Rocket when it wants to compile geometry it believes will be static for the forseeable future.
 Rocket::Core::CompiledGeometryHandle RenderInterfaceDirectX::CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return false;
+	}
+
 	// Construct a new RocketD3D9CompiledGeometry structure, which will be returned as the handle, and the buffers to
 	// store the geometry.
 	RocketD3D9CompiledGeometry* geometry = new RocketD3D9CompiledGeometry();
@@ -120,6 +130,11 @@ Rocket::Core::CompiledGeometryHandle RenderInterfaceDirectX::CompileGeometry(Roc
 // Called by Rocket when it wants to render application-compiled geometry.
 void RenderInterfaceDirectX::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return;
+	}
+
 	// Build and set the transform matrix.
 	D3DXMATRIX world_transform;
 	D3DXMatrixTranslation(&world_transform, translation.x, translation.y, 0);
@@ -156,12 +171,22 @@ void RenderInterfaceDirectX::ReleaseCompiledGeometry(Rocket::Core::CompiledGeome
 // Called by Rocket when it wants to enable or disable scissoring to clip content.
 void RenderInterfaceDirectX::EnableScissorRegion(bool enable)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return;
+	}
+
 	g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enable);
 }
 
 // Called by Rocket when it wants to change the scissor region.
 void RenderInterfaceDirectX::SetScissorRegion(int x, int y, int width, int height)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return;
+	}
+
 	RECT scissor_rect;
 	scissor_rect.left = x;
 	scissor_rect.right = x + width;
@@ -194,6 +219,11 @@ struct TGAHeader
 // Called by Rocket when a texture is required by the library.
 bool RenderInterfaceDirectX::LoadTexture(Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return false;
+	}
+
 	Rocket::Core::FileInterface* file_interface = Rocket::Core::GetFileInterface();
 	Rocket::Core::FileHandle file_handle = file_interface->Open(source);
 	if (file_handle == NULL)
@@ -263,6 +293,11 @@ bool RenderInterfaceDirectX::LoadTexture(Rocket::Core::TextureHandle& texture_ha
 // Called by Rocket when a texture is required to be built from an internally-generated sequence of pixels.
 bool RenderInterfaceDirectX::GenerateTexture(Rocket::Core::TextureHandle& texture_handle, const byte* source, const Rocket::Core::Vector2i& source_dimensions)
 {
+	if(g_pd3dDevice == NULL)
+	{
+		return false;
+	}
+
 	// Create a Direct3DTexture9, which will be set as the texture handle. Note that we only create one surface for
 	// this texture; because we're rendering in a 2D context, mip-maps are not required.
 	LPDIRECT3DTEXTURE9 d3d9_texture;

+ 12 - 2
Samples/basic/directx/src/RenderInterfaceDirectX.h

@@ -29,6 +29,7 @@
 #define RENDERINTERFACEDIRECTX_H
 
 #include <Rocket/Core/RenderInterface.h>
+#include "../../../shell/include/ShellRenderInterfaceExtensions.h"
 #include <d3d9.h>
 
 /**
@@ -37,10 +38,10 @@
 	@author Peter Curry
  */
 
-class RenderInterfaceDirectX : public Rocket::Core::RenderInterface
+class RenderInterfaceDirectX : public Rocket::Core::RenderInterface, public ShellRenderInterfaceExtensions
 {
 public:
-	RenderInterfaceDirectX(LPDIRECT3D9 g_pD3D, LPDIRECT3DDEVICE9 g_pd3dDevice);
+	RenderInterfaceDirectX(void);
 	virtual ~RenderInterfaceDirectX();
 
 	/// Called by Rocket when it wants to render geometry that it does not wish to optimise.
@@ -71,9 +72,18 @@ public:
 	/// Returns the native vertical texel offset for the renderer.
 	float GetVerticalTexelOffset();
 
+// 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);
+
 private:
 	LPDIRECT3D9 g_pD3D;
 	LPDIRECT3DDEVICE9 g_pd3dDevice;
+	void *m_rocket_context;
 };
 
 #endif

+ 152 - 0
Samples/basic/directx/src/ShellRenderInterfaceExtensionsDirectX_Win32.cpp

@@ -0,0 +1,152 @@
+/*
+ * 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.
+ *
+ */
+
+#include "RenderInterfaceDirectX.h"
+#include <Rocket/Core.h>
+#include <d3dx9.h>
+
+void RenderInterfaceDirectX::SetContext(void *context)
+{
+	m_rocket_context = context;
+}
+
+void RenderInterfaceDirectX::SetViewport(int width, int height)
+{
+	if(g_pd3dDevice != NULL)
+	{
+		D3DXMATRIX projection;
+		D3DXMatrixOrthoOffCenterLH(&projection, 0, (float)width, (float)height, 0, -1, 1);
+		g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
+	}
+
+	if(m_rocket_context != NULL)
+	{
+		((Rocket::Core::Context*)m_rocket_context)->SetDimensions(Rocket::Core::Vector2i(width, height));
+	}
+}
+
+bool RenderInterfaceDirectX::AttachToNative(void *nativeWindow)
+{
+	RECT clientRect;
+	if(!GetClientRect((HWND) nativeWindow, &clientRect))
+	{
+		// if we can't lookup the client rect, abort, something is seriously wrong
+		return false;
+	}
+
+	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
+	if (g_pD3D == NULL)
+		return false;
+
+	D3DPRESENT_PARAMETERS d3dpp;
+	ZeroMemory(&d3dpp, sizeof(d3dpp));
+	d3dpp.Windowed = TRUE;
+	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
+	g_pd3dDevice = NULL;
+
+	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
+									D3DDEVTYPE_HAL,
+									(HWND) nativeWindow,
+									D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+									&d3dpp,
+									&g_pd3dDevice)))
+	{
+
+		this->DetachFromNative();
+		return false;
+	}
+
+	// Set up an orthographic projection.
+	D3DXMATRIX projection;
+	D3DXMatrixOrthoOffCenterLH(&projection, 0, (FLOAT)clientRect.right, (FLOAT)clientRect.bottom, 0, -1, 1);
+
+	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
+
+	// Switch to clockwise culling instead of counter-clockwise culling; Rocket generates counter-clockwise geometry,
+	// so you can either reverse the culling mode when Rocket is rendering, or reverse the indices in the render
+	// interface.
+	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
+
+	// Enable alpha-blending for Rocket.
+	g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+	g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+	g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+	// Set up the texture stage states for the diffuse texture.
+	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+	g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+	g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+
+	g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+	g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+
+	// Disable lighting for Rocket.
+	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+
+	return true;
+}
+
+void RenderInterfaceDirectX::DetachFromNative()
+{
+	if (g_pd3dDevice != NULL)
+	{
+		// Release the last resources we bound to the device.
+		g_pd3dDevice->SetTexture(0, NULL);
+		g_pd3dDevice->SetStreamSource(0, NULL, 0, 0);
+		g_pd3dDevice->SetIndices(NULL);
+
+		g_pd3dDevice->Release();
+		g_pd3dDevice = NULL;
+	}
+
+	if (g_pD3D != NULL)
+	{
+		g_pD3D->Release();
+		g_pD3D = NULL;
+	}
+}
+
+void RenderInterfaceDirectX::PrepareRenderBuffer()
+{
+	if(g_pd3dDevice != NULL)
+	{
+		g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
+		g_pd3dDevice->BeginScene();
+	}
+}
+
+void RenderInterfaceDirectX::PresentRenderBuffer()
+{
+	if(g_pd3dDevice != NULL)
+	{
+		g_pd3dDevice->EndScene();
+		g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
+	}
+}

+ 15 - 98
Samples/basic/directx/src/main.cpp

@@ -30,97 +30,18 @@
 #include <Input.h>
 #include <Shell.h>
 #include "RenderInterfaceDirectX.h"
-#include <d3d9.h>
-#include <d3dx9.h>
-
-static LPDIRECT3D9 g_pD3D = NULL;
-static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
 
 static Rocket::Core::Context* context = NULL;
 
-bool InitialiseDirectX()
-{
-	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
-	if (g_pD3D == NULL)
-		return false;
-
-	D3DPRESENT_PARAMETERS d3dpp;
-	ZeroMemory(&d3dpp, sizeof(d3dpp));
-	d3dpp.Windowed = TRUE;
-	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
-	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
-
-	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
-									D3DDEVTYPE_HAL,
-									(HWND) Shell::GetWindowHandle(),
-									D3DCREATE_SOFTWARE_VERTEXPROCESSING,
-									&d3dpp,
-									&g_pd3dDevice)))
-	{
-		return false;
-	}
-
-	// Set up an orthographic projection.
-	D3DXMATRIX projection;
-	D3DXMatrixOrthoOffCenterLH(&projection, 0, 1024, 768, 0, -1, 1);
-	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
-
-	// Switch to clockwise culling instead of counter-clockwise culling; Rocket generates counter-clockwise geometry,
-	// so you can either reverse the culling mode when Rocket is rendering, or reverse the indices in the render
-	// interface.
-	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
-
-	// Enable alpha-blending for Rocket.
-	g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
-	g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
-	g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
-
-	// Set up the texture stage states for the diffuse texture.
-	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
-	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
-	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
-	g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
-	g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
-
-	g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
-	g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
-
-	// Disable lighting for Rocket.
-	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
-
-	return true;
-}
-
-void ShutdownDirectX()
-{
-	if (g_pd3dDevice != NULL)
-	{
-		// Release the last resources we bound to the device.
-		g_pd3dDevice->SetTexture(0, NULL);
-		g_pd3dDevice->SetStreamSource(0, NULL, 0, 0);
-		g_pd3dDevice->SetIndices(NULL);
-
-		g_pd3dDevice->Release();
-		g_pd3dDevice = NULL;
-	}
-
-	if (g_pD3D != NULL)
-	{
-		g_pD3D->Release();
-		g_pD3D = NULL;
-	}
-}
+ShellRenderInterfaceExtensions *shell_renderer;
 
 void GameLoop()
 {
-	g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
-	g_pd3dDevice->BeginScene();
-
 	context->Update();
-	context->Render();
 
-	g_pd3dDevice->EndScene();
-	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 #if defined ROCKET_PLATFORM_WIN32
@@ -140,25 +61,21 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	ROCKET_UNUSED(argv);
 #endif
 
-	// Generic OS initialisation, creates a window and does not attach OpenGL.
-	if (!Shell::Initialise("../Samples/basic/directx/") ||
-		!Shell::OpenWindow("DirectX Sample", false))
-	{
-		Shell::Shutdown();
-		return -1;
-	}
+	int window_width = 1024;
+	int window_height = 768;
+
+	RenderInterfaceDirectX directx_renderer;
+	shell_renderer = &directx_renderer;
 
-	// DirectX initialisation.
-	if (!InitialiseDirectX())
+	// Generic OS initialisation, creates a window
+	if (!Shell::Initialise("../Samples/basic/directx/") ||
+		!Shell::OpenWindow("DirectX Sample", shell_renderer, window_width, window_height, true))
 	{
-		Shell::CloseWindow();
 		Shell::Shutdown();
-
 		return -1;
 	}
 
 	// Install our DirectX render interface into Rocket.
-	RenderInterfaceDirectX directx_renderer(g_pD3D, g_pd3dDevice);
 	Rocket::Core::SetRenderInterface(&directx_renderer);
 
 	ShellSystemInterface system_interface;
@@ -167,7 +84,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	Rocket::Core::Initialise();
 
 	// Create the main Rocket context and set it on the shell's input layer.
-	context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(1024, 768));
+	context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(window_width, window_height));
 	if (context == NULL)
 	{
 		Rocket::Core::Shutdown();
@@ -177,6 +94,8 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
+
 
 	Shell::LoadFonts("../../assets/");
 
@@ -194,8 +113,6 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	context->RemoveReference();
 	Rocket::Core::Shutdown();
 
-	ShutdownDirectX();
-
 	Shell::CloseWindow();
 	Shell::Shutdown();
 

+ 15 - 23
Samples/basic/directx10/src/RenderInterfaceDirectx10.cpp

@@ -44,32 +44,24 @@ const D3D10_INPUT_ELEMENT_DESC layout[] =
 };
 
 //The constructor of the render
-RenderInterfaceDirectX10::RenderInterfaceDirectX10(ID3D10Device * pD3D10Device,float screenWidth,float screenHeight)
+RenderInterfaceDirectX10::RenderInterfaceDirectX10(void)
 {
+	m_rocket_context = NULL;
+	m_pD3D10Device = NULL;
+
+	m_pEffect = NULL;
+	m_pTechnique = NULL;
+	m_pVertexLayout = NULL;
+
+	m_pSwapChain = NULL;
+	m_pRenderTargetView = NULL;
+
+	m_pProjectionMatrixVariable = NULL;
+	m_pWorldMatrixVariable = NULL;
+	m_pDiffuseTextureVariable = NULL;
+
 	m_pScissorTestDisable = NULL;
 	m_pScissorTestEnable = NULL;
-	m_pD3D10Device=pD3D10Device;
-	setupEffect();
-	//Create our view and projection matrix
-	D3DXMatrixOrthoOffCenterLH(&m_matProjection, 0, screenWidth, screenHeight, 0, -1, 1);
-	m_pProjectionMatrixVariable->SetMatrix((float*)m_matProjection);
-
-	//Create scissor raster states
-	D3D10_RASTERIZER_DESC rasterDesc;
-	rasterDesc.FillMode=D3D10_FILL_SOLID;
-	rasterDesc.CullMode=D3D10_CULL_NONE;
-	rasterDesc.ScissorEnable=TRUE;
-	rasterDesc.FrontCounterClockwise=TRUE;
-	if (FAILED(m_pD3D10Device->CreateRasterizerState(&rasterDesc, &m_pScissorTestEnable)))
-	{
-		Rocket::Core::Log::Message(Rocket::Core::Log::LT_ERROR, "Can't create Raster State - ScissorEnable");
-	}
-
-	rasterDesc.ScissorEnable=FALSE;
-	if (FAILED(m_pD3D10Device->CreateRasterizerState(&rasterDesc, &m_pScissorTestDisable)))
-	{
-		Rocket::Core::Log::Message(Rocket::Core::Log::LT_ERROR, "Can't create Raster State - ScissorDisable");
-	}
 }
 
 //Loads the effect from memory and retrieves initial variables from the effect

+ 22 - 4
Samples/basic/directx10/src/RenderInterfaceDirectx10.h

@@ -2,6 +2,7 @@
 #define RENDERINTERFACEDIRECTX_H
 
 #include <Rocket/Core/RenderInterface.h>
+#include "../../../shell/include/ShellRenderInterfaceExtensions.h"
 #include <d3d10.h>
 #include <d3dx10.h>
 
@@ -14,11 +15,11 @@
 	@author Brian McDonald
  */
 
-class RenderInterfaceDirectX10 : public Rocket::Core::RenderInterface
+class RenderInterfaceDirectX10 : public Rocket::Core::RenderInterface, public ShellRenderInterfaceExtensions
 {
 public:
-	RenderInterfaceDirectX10(ID3D10Device * pD3D10Device,float screenWidth,float screenHeight);
-	virtual ~RenderInterfaceDirectX10();
+	RenderInterfaceDirectX10();
+	virtual ~RenderInterfaceDirectX10(void);
 
 	/// 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);
@@ -51,7 +52,19 @@ public:
 	//loads the effect from memory
 	void setupEffect();
 
+	// 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);
+
 private:
+	// Rocket Context, needed for when the shell window is resized so we can update the Rocket::Core::Context
+	// dimensions
+	void *m_rocket_context;
+
 	//The D3D 10 Device
 	ID3D10Device * m_pD3D10Device;
 	//The Effect we are using to render GUI
@@ -61,7 +74,12 @@ private:
 	//The Vertex Layout
 	ID3D10InputLayout*      m_pVertexLayout;
 
-	//Effect varibales, used to send variables to the effect
+	//Swap Chain
+	IDXGISwapChain* m_pSwapChain;
+	//Render Target
+	ID3D10RenderTargetView* m_pRenderTargetView;
+
+	//Effect variables, used to send variables to the effect
 	ID3D10EffectMatrixVariable * m_pProjectionMatrixVariable;
 	ID3D10EffectMatrixVariable * m_pWorldMatrixVariable;
 	ID3D10EffectShaderResourceVariable *m_pDiffuseTextureVariable;

+ 243 - 0
Samples/basic/directx10/src/ShellRenderInterfaceExtensionsDirectX10_Win32.cpp

@@ -0,0 +1,243 @@
+/*
+ * 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.
+ *
+ */
+
+#include "RenderInterfaceDirectX10.h"
+#include <Rocket/Core.h>
+#include <d3d10.h>
+#include <d3dx10.h>
+
+// For _T unicode/mbcs macro
+#include <tchar.h>
+
+void RenderInterfaceDirectX10::SetContext(void *context)
+{
+	m_rocket_context = context;
+}
+
+void RenderInterfaceDirectX10::SetViewport(int width, int height)
+{
+	if(this->m_pD3D10Device != NULL)
+	{
+		if(width == 0 || height == 0)
+		{
+			// Windows with no client area cause crashes
+			return;
+		}
+
+		if(this->m_pRenderTargetView)
+		{
+			// Release the existing render target
+			this->m_pRenderTargetView->Release();
+			this->m_pRenderTargetView = NULL;
+		}
+
+		// Resize the swap chain's buffer to the given dimensions
+		m_pSwapChain->ResizeBuffers(2, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
+
+		// Recreate Render Target
+		ID3D10Texture2D *pBackBuffer;
+		if(FAILED(this->m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &pBackBuffer)))
+		{
+			MessageBox(NULL, _T("SwapChain->GetBuffer failed."), _T("Could not resize DirectX 10 surface"), MB_OK|MB_ICONERROR);
+			return;
+		}
+		if(FAILED(this->m_pD3D10Device->CreateRenderTargetView(pBackBuffer, NULL, &this->m_pRenderTargetView)))
+		{
+				pBackBuffer->Release();
+				MessageBox(NULL, _T("D3D10Device->CreateRenderTargetView failed."), _T("Could not resize DirectX 10 surface"), MB_OK|MB_ICONERROR);
+				return;
+		}
+		pBackBuffer->Release();
+	
+		this->m_pD3D10Device->OMSetRenderTargets(1, &this->m_pRenderTargetView, NULL);
+
+		D3D10_VIEWPORT vp;
+		vp.Width = width;
+		vp.Height = height;
+		vp.MinDepth = 0.0f;
+		vp.MaxDepth = 1.0f;
+		vp.TopLeftX = 0;
+		vp.TopLeftY = 0;
+		this->m_pD3D10Device->RSSetViewports(1, &vp);
+
+		// Recreate our view and projection matrix
+		D3DXMatrixOrthoOffCenterLH(&this->m_matProjection, 0, width, height, 0, -1, 1);
+		m_pProjectionMatrixVariable->SetMatrix((float*)this->m_matProjection);
+	}
+
+	if(m_rocket_context != NULL)
+	{
+		((Rocket::Core::Context*)m_rocket_context)->SetDimensions(Rocket::Core::Vector2i(width, height));
+	}
+}
+
+bool RenderInterfaceDirectX10::AttachToNative(void *nativeWindow)
+{
+	RECT clientRect;
+	if(!GetClientRect((HWND) nativeWindow, &clientRect))
+	{
+		// if we can't lookup the client rect, abort, something is seriously wrong
+		return false;
+	}
+	int width = clientRect.right - clientRect.left;
+	int height = clientRect.bottom - clientRect.top;
+
+	//put the device into debug if we are in a debug build
+	UINT createDeviceFlags=0;
+#ifdef _DEBUG
+	createDeviceFlags|=D3D10_CREATE_DEVICE_DEBUG;
+#endif
+
+	//Setup swap chain
+	DXGI_SWAP_CHAIN_DESC sd;
+	ZeroMemory(&sd, sizeof(sd));
+	sd.BufferCount=1;
+	sd.OutputWindow = (HWND) nativeWindow;
+	sd.Windowed = TRUE;
+	sd.SampleDesc.Count = 1;
+	sd.SampleDesc.Quality = 0;
+	sd.BufferDesc.Width = width;
+	sd.BufferDesc.Height = height;
+	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+	sd.BufferDesc.RefreshRate.Numerator = 60;
+	sd.BufferDesc.RefreshRate.Denominator = 1;
+	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+
+	//Create device and swapchain
+	if(FAILED(D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags,	D3D10_SDK_VERSION, &sd, &this->m_pSwapChain, &this->m_pD3D10Device)))
+	{
+		if(MessageBox(NULL, _T("D3D10CreateDeviceAndSwapChain failed for D3D10_DRIVER_TYPE_HARDWARE.\r\n\r\nWould you like to try the reference renderer, this will be very slow!"), _T("Could not intialized DirectX 10"), MB_OKCANCEL|MB_ICONERROR) == IDOK)
+		{
+			if(FAILED(D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL, createDeviceFlags,	D3D10_SDK_VERSION, &sd, &this->m_pSwapChain, &this->m_pD3D10Device)))
+			{
+				MessageBox(NULL, _T("D3D10CreateDeviceAndSwapChain failed for D3D10_DRIVER_TYPE_REFERENCE, giving up."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
+				return false;
+			}
+		}
+		else
+		{
+			return false;
+		}
+	}
+	
+	//Create Render Target
+	ID3D10Texture2D *pBackBuffer;
+	if(FAILED (this->m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),(void**)&pBackBuffer)))
+	{
+		MessageBox(NULL, _T("SwapChain->GetBuffer failed."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
+		return false;
+	}
+	if(FAILED(this->m_pD3D10Device->CreateRenderTargetView(pBackBuffer, NULL, &this->m_pRenderTargetView)))
+	{
+			pBackBuffer->Release();
+			MessageBox(NULL, _T("D3D10Device->CreateRenderTargetView failed."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
+			return false;
+	}
+	pBackBuffer->Release();
+	
+	this->m_pD3D10Device->OMSetRenderTargets(1, &this->m_pRenderTargetView, NULL);
+
+	D3D10_VIEWPORT vp;
+	vp.Width = width;
+	vp.Height = height;
+	vp.MinDepth = 0.0f;
+	vp.MaxDepth = 1.0f;
+	vp.TopLeftX = 0;
+	vp.TopLeftY = 0;
+	this->m_pD3D10Device->RSSetViewports(1, &vp);
+
+	setupEffect();
+
+	//Create our view and projection matrix
+	D3DXMatrixOrthoOffCenterLH(&this->m_matProjection, 0, width, height, 0, -1, 1);
+	m_pProjectionMatrixVariable->SetMatrix((float*)this->m_matProjection);
+
+	//Create scissor raster states
+	D3D10_RASTERIZER_DESC rasterDesc;
+	rasterDesc.FillMode=D3D10_FILL_SOLID;
+	rasterDesc.CullMode=D3D10_CULL_NONE;
+	rasterDesc.ScissorEnable=TRUE;
+	rasterDesc.FrontCounterClockwise=TRUE;
+	if(FAILED(this->m_pD3D10Device->CreateRasterizerState(&rasterDesc, &this->m_pScissorTestEnable)))
+	{
+		Rocket::Core::Log::Message(Rocket::Core::Log::LT_ERROR, "Can't create Raster State - ScissorEnable");
+	}
+
+	rasterDesc.ScissorEnable=FALSE;
+	if(FAILED(this->m_pD3D10Device->CreateRasterizerState(&rasterDesc, &this->m_pScissorTestDisable)))
+	{
+		Rocket::Core::Log::Message(Rocket::Core::Log::LT_ERROR, "Can't create Raster State - ScissorDisable");
+	}
+
+	return true;
+}
+
+void RenderInterfaceDirectX10::DetachFromNative()
+{
+	if(this->m_pD3D10Device != NULL)
+	{
+		this->m_pD3D10Device->ClearState();
+		this->m_pD3D10Device = NULL;
+	}
+	if(this->m_pRenderTargetView != NULL)
+	{
+		this->m_pRenderTargetView->Release();
+		this->m_pRenderTargetView = NULL;
+	}
+	if(this->m_pSwapChain != NULL)
+	{
+		this->m_pSwapChain->Release();
+		this->m_pSwapChain = NULL;
+	}
+	if(this->m_pD3D10Device != NULL)
+	{
+		this->m_pD3D10Device->Release();
+		this->m_pD3D10Device = NULL;
+	}
+
+}
+
+void RenderInterfaceDirectX10::PrepareRenderBuffer()
+{
+	if(this->m_pD3D10Device == NULL)
+	{
+		return;
+	}
+
+	float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };
+	this->m_pD3D10Device->ClearRenderTargetView(this->m_pRenderTargetView, ClearColor);
+}
+
+void RenderInterfaceDirectX10::PresentRenderBuffer()
+{
+	if(this->m_pSwapChain == NULL)
+	{
+		return;
+	}
+
+	this->m_pSwapChain->Present(0, 0);
+}

+ 12 - 101
Samples/basic/directx10/src/main.cpp

@@ -10,101 +10,17 @@
 // For _T unicode/mbcs macro
 #include <tchar.h>
 
-//Our device for this sample
-static ID3D10Device * pD3D10Device=NULL;
-//Swap Chain
-static IDXGISwapChain * pSwapChain=NULL;
-//Render Target
-static ID3D10RenderTargetView * pRenderTargetView=NULL;
-
 static Rocket::Core::Context* context = NULL;
 
-bool InitialiseDirectX()
-{
-	//get the size of the window
-	RECT windowRect;
-	GetClientRect((HWND) Shell::GetWindowHandle(),&windowRect);
-	UINT width=windowRect.right-windowRect.left;
-	UINT height=windowRect.bottom-windowRect.top;
-
-	//put the device into debug if we are in a debug build
-	UINT createDeviceFlags=0;
-#ifdef _DEBUG
-	createDeviceFlags|=D3D10_CREATE_DEVICE_DEBUG;
-#endif
-
-	//Setup swap chain
-	DXGI_SWAP_CHAIN_DESC sd;
-	ZeroMemory( &sd, sizeof( sd ) );
-	sd.BufferCount=1;
-	sd.OutputWindow = (HWND) Shell::GetWindowHandle();
-	sd.Windowed = TRUE;
-	sd.SampleDesc.Count = 1;
-	sd.SampleDesc.Quality = 0;
-	sd.BufferDesc.Width = width;
-	sd.BufferDesc.Height = height;
-	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
-	sd.BufferDesc.RefreshRate.Numerator = 60;
-	sd.BufferDesc.RefreshRate.Denominator = 1;
-	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-
-	//Create device and swapchain
-	if (FAILED(D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags,	D3D10_SDK_VERSION, &sd, &pSwapChain, &pD3D10Device)))
-	{
-		MessageBox(NULL, _T("D3D10CreateDeviceAndSwapChain failed for D3D10_DRIVER_TYPE_HARDWARE."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
-		return false;
-	}
-	
-	//Create Render Target
-	ID3D10Texture2D *pBackBuffer;
-	if ( FAILED (pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),(void**)&pBackBuffer)))
-	{
-		MessageBox(NULL, _T("SwapChain->GetBuffer failed."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
-		return false;
-	}
-	if (FAILED(pD3D10Device->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView )))
-	{
-			pBackBuffer->Release();
-			MessageBox(NULL, _T("D3D10Device->CreateRenderTargetView failed."), _T("Could not intialized DirectX 10"), MB_OK|MB_ICONERROR);
-			return false;
-	}
-	pBackBuffer->Release();
-	
-	pD3D10Device->OMSetRenderTargets(1,&pRenderTargetView,NULL);
-
-	D3D10_VIEWPORT vp;
-	vp.Width = width;
-	vp.Height = height;
-	vp.MinDepth = 0.0f;
-	vp.MaxDepth = 1.0f;
-	vp.TopLeftX = 0;
-	vp.TopLeftY = 0;
-	pD3D10Device->RSSetViewports( 1, &vp );
-
-	return true;
-}
-
-void ShutdownDirectX()
-{	
-	if (pD3D10Device)
-		pD3D10Device->ClearState();
-	if (pRenderTargetView)
-		pRenderTargetView->Release();
-	if (pSwapChain)
-		pSwapChain->Release();
-	if (pD3D10Device)
-		pD3D10Device->Release();
-}
+ShellRenderInterfaceExtensions *shell_renderer;
 
 void GameLoop()
 {
-	float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };
-	pD3D10Device->ClearRenderTargetView( pRenderTargetView,ClearColor );
-
 	context->Update();
-	context->Render();
 
-	pSwapChain->Present( 0, 0 );
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
 }
 
 int APIENTRY WinMain(HINSTANCE ROCKET_UNUSED_PARAMETER(instance_handle), HINSTANCE ROCKET_UNUSED_PARAMETER(previous_instance_handle), char* ROCKET_UNUSED_PARAMETER(command_line), int ROCKET_UNUSED_PARAMETER(command_show))
@@ -114,25 +30,21 @@ int APIENTRY WinMain(HINSTANCE ROCKET_UNUSED_PARAMETER(instance_handle), HINSTAN
 	ROCKET_UNUSED(command_line);
 	ROCKET_UNUSED(command_show);
 
+	int window_width = 1024;
+	int window_height = 768;
+
+	RenderInterfaceDirectX10 directx_renderer;
+	shell_renderer = &directx_renderer;
+
 	// Generic OS initialisation, creates a window and does not attach OpenGL.
 	if (!Shell::Initialise("../Samples/basic/directx/") ||
-		!Shell::OpenWindow("DirectX 10 Sample", false))
+		!Shell::OpenWindow("DirectX 10 Sample", shell_renderer, window_width, window_height, true))
 	{
 		Shell::Shutdown();
 		return -1;
 	}
 
-	// DirectX initialisation.
-	if (!InitialiseDirectX())
-	{
-		Shell::CloseWindow();
-		Shell::Shutdown();
-
-		return -1;
-	}
-
 	// Install our DirectX render interface into Rocket.
-	RenderInterfaceDirectX10 directx_renderer(pD3D10Device,1024,768);
 	Rocket::Core::SetRenderInterface(&directx_renderer);
 
 	ShellSystemInterface system_interface;
@@ -151,6 +63,7 @@ int APIENTRY WinMain(HINSTANCE ROCKET_UNUSED_PARAMETER(instance_handle), HINSTAN
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 
@@ -168,8 +81,6 @@ int APIENTRY WinMain(HINSTANCE ROCKET_UNUSED_PARAMETER(instance_handle), HINSTAN
 	context->RemoveReference();
 	Rocket::Core::Shutdown();
 
-	ShutdownDirectX();
-
 	Shell::CloseWindow();
 	Shell::Shutdown();
 

+ 11 - 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);
@@ -89,6 +92,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 11 - 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);
@@ -88,6 +91,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 11 - 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;
@@ -93,6 +95,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	Rocket::Controls::Initialise();
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 10 - 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);
@@ -92,6 +96,7 @@ int main(int, char**)
 	// Initialise the Rocket debugger.
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	// Load the font faces required for Invaders.
 	Shell::LoadFonts("../assets/");

+ 9 - 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);
 
@@ -107,6 +111,7 @@ int main(int, char**)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	// Load the font faces required for Invaders.
 	Shell::LoadFonts("../assets/");

+ 10 - 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, false))
 	{
 		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);
@@ -113,6 +118,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	// Load the font faces required for Invaders.
 	Shell::LoadFonts("../assets/");

+ 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);
+}

+ 22 - 109
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,14 @@ 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)
+		shell_renderer = _shell_renderer;
+		if(!shell_renderer->AttachToNative(window_handle))
+		{
+			CloseWindow();
 			return false;
+		}
 	}
 
     return true;
@@ -162,11 +160,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 +174,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 +250,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 +276,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;
 				

+ 11 - 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);
@@ -76,6 +79,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 11 - 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);
@@ -77,6 +80,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 11 - 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);
@@ -72,6 +75,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");
 

+ 11 - 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);
@@ -73,6 +76,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 
 	Rocket::Debugger::Initialise(context);
 	Input::SetContext(context);
+	shell_renderer->SetContext(context);
 
 	Shell::LoadFonts("../../assets/");