Browse Source

Added experimental Graphics::SetExternalWindow() function. Due to SDL limitations (external windows are not marked OpenGL-capable) will only work on Direct3D9 for now.
Fixed the INTZ depth stencil surface not being resized for new screen mode, which caused rendering to fail if the window was grown larger than initial size.

Lasse Öörni 13 years ago
parent
commit
a399726d42

+ 39 - 9
Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -162,6 +162,7 @@ OBJECTTYPESTATIC(Graphics);
 Graphics::Graphics(Context* context) :
 Graphics::Graphics(Context* context) :
     Object(context),
     Object(context),
     impl_(new GraphicsImpl()),
     impl_(new GraphicsImpl()),
+    externalWindow_(0),
     width_(0),
     width_(0),
     height_(0),
     height_(0),
     multiSample_(1),
     multiSample_(1),
@@ -249,6 +250,14 @@ Graphics::~Graphics()
     }
     }
 }
 }
 
 
+void Graphics::SetExternalWindow(void* window)
+{
+    if (!impl_->window_)
+        externalWindow_ = window;
+    else
+        LOGERROR("Window already opened, can not set external window");
+}
+
 void Graphics::SetWindowTitle(const String& windowTitle)
 void Graphics::SetWindowTitle(const String& windowTitle)
 {
 {
     windowTitle_ = windowTitle;
     windowTitle_ = windowTitle;
@@ -328,6 +337,8 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
             multiSample = 1;
             multiSample = 1;
     }
     }
     
     
+    AdjustWindow(width, height, fullscreen);
+    
     if (fullscreen)
     if (fullscreen)
     {
     {
         impl_->presentParams_.BackBufferFormat = fullscreenFormat;
         impl_->presentParams_.BackBufferFormat = fullscreenFormat;
@@ -365,8 +376,6 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
     vsync_ = vsync;
     vsync_ = vsync;
     tripleBuffer_ = tripleBuffer;
     tripleBuffer_ = tripleBuffer;
     
     
-    AdjustWindow(width, height, fullscreen);
-    
     if (!impl_->device_)
     if (!impl_->device_)
     {
     {
         unsigned adapter = D3DADAPTER_DEFAULT;
         unsigned adapter = D3DADAPTER_DEFAULT;
@@ -528,6 +537,16 @@ bool Graphics::BeginFrame()
     if (!IsInitialized())
     if (!IsInitialized())
         return false;
         return false;
     
     
+    // If using an external window, check it for size changes, and reset screen mode if necessary
+    if (externalWindow_)
+    {
+        int width, height;
+        
+        SDL_GetWindowSize(impl_->window_, &width, &height);
+        if (width != width_ || height != height_)
+            SetMode(width, height);
+    }
+    
     // Check for lost device before rendering
     // Check for lost device before rendering
     HRESULT hr = impl_->device_->TestCooperativeLevel();
     HRESULT hr = impl_->device_->TestCooperativeLevel();
     if (hr != D3D_OK)
     if (hr != D3D_OK)
@@ -1915,7 +1934,10 @@ unsigned Graphics::GetDepthStencilFormat()
 
 
 bool Graphics::OpenWindow(int width, int height)
 bool Graphics::OpenWindow(int width, int height)
 {
 {
-    impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);
+    if (!externalWindow_)
+        impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);
+    else
+        impl_->window_ = SDL_CreateWindowFrom(externalWindow_);
     
     
     if (!impl_->window_)
     if (!impl_->window_)
     {
     {
@@ -1926,10 +1948,19 @@ bool Graphics::OpenWindow(int width, int height)
     return true;
     return true;
 }
 }
 
 
-void Graphics::AdjustWindow(int newWidth, int newHeight, bool newFullscreen)
+void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen)
 {
 {
-    SDL_SetWindowSize(impl_->window_, newWidth, newHeight);
-    SDL_SetWindowFullscreen(impl_->window_, newFullscreen ? SDL_TRUE : SDL_FALSE);
+    if (!externalWindow_)
+    {
+        SDL_SetWindowSize(impl_->window_, newWidth, newHeight);
+        SDL_SetWindowFullscreen(impl_->window_, newFullscreen ? SDL_TRUE : SDL_FALSE);
+    }
+    else
+    {
+        // If external window, must ask its dimensions instead of trying to set them
+        SDL_GetWindowSize(impl_->window_, &newWidth, &newHeight);
+        newFullscreen = false;
+    }
 }
 }
 
 
 bool Graphics::CreateInterface()
 bool Graphics::CreateInterface()
@@ -2144,10 +2175,9 @@ void Graphics::OnDeviceReset()
     else
     else
     {
     {
         if (!depthTexture_)
         if (!depthTexture_)
-        {
             depthTexture_ = new Texture2D(context_);
             depthTexture_ = new Texture2D(context_);
-            depthTexture_->SetSize(width_, height_, (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'), TEXTURE_DEPTHSTENCIL);
-        }
+        
+        depthTexture_->SetSize(width_, height_, (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'), TEXTURE_DEPTHSTENCIL);
         
         
         impl_->defaultDepthStencilSurface_ = (IDirect3DSurface9*)depthTexture_->GetRenderSurface()->GetSurface();
         impl_->defaultDepthStencilSurface_ = (IDirect3DSurface9*)depthTexture_->GetRenderSurface()->GetSurface();
         systemDepthStencil_ = false;
         systemDepthStencil_ = false;

+ 7 - 1
Engine/Graphics/Direct3D9/D3D9Graphics.h

@@ -77,6 +77,8 @@ public:
     /// Destruct. Close the window and release the Direct3D9 device.
     /// Destruct. Close the window and release the Direct3D9 device.
     virtual ~Graphics();
     virtual ~Graphics();
     
     
+    /// %Set external window handle. Call before setting mode for the first time.
+    void SetExternalWindow(void* window);
     /// %Set window title.
     /// %Set window title.
     void SetWindowTitle(const String& windowTitle);
     void SetWindowTitle(const String& windowTitle);
     /// %Set screen mode. Return true if successful.
     /// %Set screen mode. Return true if successful.
@@ -196,6 +198,8 @@ public:
     bool IsInitialized() const;
     bool IsInitialized() const;
     /// Return graphics implementation, which holds the actual API-specific resources.
     /// Return graphics implementation, which holds the actual API-specific resources.
     GraphicsImpl* GetImpl() const { return impl_; }
     GraphicsImpl* GetImpl() const { return impl_; }
+    /// Return OS-specific external window handle. Null if not in use.
+    void* GetExternalWindow() const { return externalWindow_; }
     /// Return window title.
     /// Return window title.
     const String& GetWindowTitle() const { return windowTitle_; }
     const String& GetWindowTitle() const { return windowTitle_; }
     /// Return window width.
     /// Return window width.
@@ -339,7 +343,7 @@ private:
     /// Create the application window.
     /// Create the application window.
     bool OpenWindow(int width, int height);
     bool OpenWindow(int width, int height);
     /// Adjust the window for new resolution and fullscreen mode.
     /// Adjust the window for new resolution and fullscreen mode.
-    void AdjustWindow(int newWidth, int newHeight, bool newFullscreen);
+    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen);
     /// Create the Direct3D interface.
     /// Create the Direct3D interface.
     bool CreateInterface();
     bool CreateInterface();
     /// Create the Direct3D device.
     /// Create the Direct3D device.
@@ -361,6 +365,8 @@ private:
     GraphicsImpl* impl_;
     GraphicsImpl* impl_;
     /// Window title.
     /// Window title.
     String windowTitle_;
     String windowTitle_;
+    /// External window, null if not in use (default.)
+    void* externalWindow_;
     /// Window width.
     /// Window width.
     int width_;
     int width_;
     /// Window height.
     /// Window height.

+ 26 - 1
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -133,6 +133,7 @@ bool CheckExtension(const String& name)
 Graphics::Graphics(Context* context_) :
 Graphics::Graphics(Context* context_) :
     Object(context_),
     Object(context_),
     impl_(new GraphicsImpl()),
     impl_(new GraphicsImpl()),
+    externalWindow_(0),
     width_(0),
     width_(0),
     height_(0),
     height_(0),
     multiSample_(1),
     multiSample_(1),
@@ -184,6 +185,14 @@ Graphics::~Graphics()
     }
     }
 }
 }
 
 
+void Graphics::SetExternalWindow(void* window)
+{
+    if (!impl_->window_)
+        externalWindow_ = window;
+    else
+        LOGERROR("Window already opened, can not set external window");
+}
+
 void Graphics::SetWindowTitle(const String& windowTitle)
 void Graphics::SetWindowTitle(const String& windowTitle)
 {
 {
     windowTitle_ = windowTitle;
     windowTitle_ = windowTitle;
@@ -269,7 +278,13 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
         if (fullscreen)
         if (fullscreen)
             flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
             flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
         
         
-        impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), x, y, width, height, flags);
+        if (!externalWindow_)
+            impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), x, y, width, height, flags);
+        else
+        {
+            impl_->window_ = SDL_CreateWindowFrom(externalWindow_);
+            fullscreen = false;
+        }
         if (!impl_->window_)
         if (!impl_->window_)
         {
         {
             LOGERROR("Could not open window");
             LOGERROR("Could not open window");
@@ -389,6 +404,16 @@ bool Graphics::BeginFrame()
     if (!IsInitialized() || IsDeviceLost())
     if (!IsInitialized() || IsDeviceLost())
         return false;
         return false;
     
     
+    // If using an external window, check it for size changes, and reset screen mode if necessary
+    if (externalWindow_)
+    {
+        int width, height;
+        
+        SDL_GetWindowSize(impl_->window_, &width, &height);
+        if (width != width_ || height != height_)
+            SetMode(width, height);
+    }
+
     // Set default rendertarget and depth buffer
     // Set default rendertarget and depth buffer
     ResetRenderTargets();
     ResetRenderTargets();
     
     

+ 41 - 35
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -82,11 +82,13 @@ public:
     /// Destruct. Release the OpenGL context and close the window.
     /// Destruct. Release the OpenGL context and close the window.
     virtual ~Graphics();
     virtual ~Graphics();
     
     
-    /// Set window title.
+    /// %Set external window handle. Call before setting mode for the first time.
+    void SetExternalWindow(void* window);
+    /// %Set window title.
     void SetWindowTitle(const String& windowTitle);
     void SetWindowTitle(const String& windowTitle);
-    /// Set screen mode. Return true if successful.
+    /// %Set screen mode. Return true if successful.
     bool SetMode(int width, int height, bool fullscreen, bool vsync, bool tripleBuffer, int multiSample);
     bool SetMode(int width, int height, bool fullscreen, bool vsync, bool tripleBuffer, int multiSample);
-    /// Set screen resolution only. Return true if successful.
+    /// %Set screen resolution only. Return true if successful.
     bool SetMode(int width, int height);
     bool SetMode(int width, int height);
     /// Toggle between full screen and windowed mode.
     /// Toggle between full screen and windowed mode.
     bool ToggleFullscreen();
     bool ToggleFullscreen();
@@ -108,31 +110,31 @@ public:
     void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
     void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
     /// Draw indexed, instanced geometry. No-op on OpenGL.
     /// Draw indexed, instanced geometry. No-op on OpenGL.
     void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount, unsigned instanceCount);
     void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount, unsigned instanceCount);
-    /// Set vertex buffer.
+    /// %Set vertex buffer.
     void SetVertexBuffer(VertexBuffer* buffer);
     void SetVertexBuffer(VertexBuffer* buffer);
-    /// Set multiple vertex buffers.
+    /// %Set multiple vertex buffers.
     bool SetVertexBuffers(const Vector<VertexBuffer*>& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
     bool SetVertexBuffers(const Vector<VertexBuffer*>& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
-    /// Set multiple vertex buffers.
+    /// %Set multiple vertex buffers.
     bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
     bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
-    /// Set index buffer.
+    /// %Set index buffer.
     void SetIndexBuffer(IndexBuffer* buffer);
     void SetIndexBuffer(IndexBuffer* buffer);
-    /// Set shaders.
+    /// %Set shaders.
     void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
     void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
-    /// Set shader float constants.
+    /// %Set shader float constants.
     void SetShaderParameter(StringHash param, const float* data, unsigned count);
     void SetShaderParameter(StringHash param, const float* data, unsigned count);
-    /// Set shader float constant.
+    /// %Set shader float constant.
     void SetShaderParameter(StringHash param, float value);
     void SetShaderParameter(StringHash param, float value);
-    /// Set shader color constant.
+    /// %Set shader color constant.
     void SetShaderParameter(StringHash param, const Color& color);
     void SetShaderParameter(StringHash param, const Color& color);
-    /// Set shader 3x3 matrix constant.
+    /// %Set shader 3x3 matrix constant.
     void SetShaderParameter(StringHash param, const Matrix3& matrix);
     void SetShaderParameter(StringHash param, const Matrix3& matrix);
-    /// Set shader 3D vector constant.
+    /// %Set shader 3D vector constant.
     void SetShaderParameter(StringHash param, const Vector3& vector);
     void SetShaderParameter(StringHash param, const Vector3& vector);
-    /// Set shader 4x4 matrix constant.
+    /// %Set shader 4x4 matrix constant.
     void SetShaderParameter(StringHash param, const Matrix4& matrix);
     void SetShaderParameter(StringHash param, const Matrix4& matrix);
-    /// Set shader 4D vector constant.
+    /// %Set shader 4D vector constant.
     void SetShaderParameter(StringHash param, const Vector4& vector);
     void SetShaderParameter(StringHash param, const Vector4& vector);
-    /// Set shader 4x3 matrix constant.
+    /// %Set shader 4x3 matrix constant.
     void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
     void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
     /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
     /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
     bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
     bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
@@ -148,13 +150,13 @@ public:
     void ClearTransformSources();
     void ClearTransformSources();
     /// Clean up unused shader programs.
     /// Clean up unused shader programs.
     void CleanupShaderPrograms();
     void CleanupShaderPrograms();
-    /// Set texture.
+    /// %Set texture.
     void SetTexture(unsigned index, Texture* texture);
     void SetTexture(unsigned index, Texture* texture);
     /// Bind texture unit 0 for update. Called by Texture.
     /// Bind texture unit 0 for update. Called by Texture.
     void SetTextureForUpdate(Texture* texture);
     void SetTextureForUpdate(Texture* texture);
-    /// Set default texture filtering mode.
+    /// %Set default texture filtering mode.
     void SetDefaultTextureFilterMode(TextureFilterMode mode);
     void SetDefaultTextureFilterMode(TextureFilterMode mode);
-    /// Set texture anisotropy.
+    /// %Set texture anisotropy.
     void SetTextureAnisotropy(unsigned level);
     void SetTextureAnisotropy(unsigned level);
     /// Dirty texture parameters of all textures (when global settings change.)
     /// Dirty texture parameters of all textures (when global settings change.)
     void SetTextureParametersDirty();
     void SetTextureParametersDirty();
@@ -164,47 +166,49 @@ public:
     void ResetRenderTarget(unsigned index);
     void ResetRenderTarget(unsigned index);
     /// Reset depth-stencil surface.
     /// Reset depth-stencil surface.
     void ResetDepthStencil();
     void ResetDepthStencil();
-    /// Set rendertarget.
+    /// %Set rendertarget.
     void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
     void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
-    /// Set rendertarget.
+    /// %Set rendertarget.
     void SetRenderTarget(unsigned index, Texture2D* texture);
     void SetRenderTarget(unsigned index, Texture2D* texture);
-    /// Set depth-stencil surface.
+    /// %Set depth-stencil surface.
     void SetDepthStencil(RenderSurface* depthStencil);
     void SetDepthStencil(RenderSurface* depthStencil);
-    /// Set depth-stencil surface.
+    /// %Set depth-stencil surface.
     void SetDepthStencil(Texture2D* texture);
     void SetDepthStencil(Texture2D* texture);
     /// %Set view texture (deferred rendering final output rendertarget) to prevent it from being sampled.
     /// %Set view texture (deferred rendering final output rendertarget) to prevent it from being sampled.
     void SetViewTexture(Texture* texture);
     void SetViewTexture(Texture* texture);
-    /// Set viewport.
+    /// %Set viewport.
     void SetViewport(const IntRect& rect);
     void SetViewport(const IntRect& rect);
-    /// Set blending mode.
+    /// %Set blending mode.
     void SetBlendMode(BlendMode mode);
     void SetBlendMode(BlendMode mode);
-    /// Set color write on/off.
+    /// %Set color write on/off.
     void SetColorWrite(bool enable);
     void SetColorWrite(bool enable);
-    /// Set hardware culling mode.
+    /// %Set hardware culling mode.
     void SetCullMode(CullMode mode);
     void SetCullMode(CullMode mode);
-    /// Set depth bias.
+    /// %Set depth bias.
     void SetDepthBias(float constantBias, float slopeScaledBias);
     void SetDepthBias(float constantBias, float slopeScaledBias);
-    /// Set depth compare.
+    /// %Set depth compare.
     void SetDepthTest(CompareMode mode);
     void SetDepthTest(CompareMode mode);
-    /// Set depth write on/off.
+    /// %Set depth write on/off.
     void SetDepthWrite(bool enable);
     void SetDepthWrite(bool enable);
-    /// Set scissor test.
+    /// %Set scissor test.
     void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
     void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
-    /// Set scissor test.
+    /// %Set scissor test.
     void SetScissorTest(bool enable, const IntRect& rect);
     void SetScissorTest(bool enable, const IntRect& rect);
-    /// Set stencil test.
+    /// %Set stencil test.
     void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
     void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
-    /// Set vertex buffer stream frequency. No-op on OpenGL.
+    /// %Set vertex buffer stream frequency. No-op on OpenGL.
     void SetStreamFrequency(unsigned index, unsigned frequency);
     void SetStreamFrequency(unsigned index, unsigned frequency);
     /// Reset stream frequencies. No-op on OpenGL.
     /// Reset stream frequencies. No-op on OpenGL.
     void ResetStreamFrequencies();
     void ResetStreamFrequencies();
-    /// Set force Shader Model 2 flag. No effect on OpenGL.
+    /// %Set force Shader Model 2 flag. No-op on OpenGL.
     void SetForceSM2(bool enable);
     void SetForceSM2(bool enable);
 
 
     /// Return whether rendering initialized.
     /// Return whether rendering initialized.
     bool IsInitialized() const;
     bool IsInitialized() const;
     /// Return graphics implementation, which holds the actual API-specific resources.
     /// Return graphics implementation, which holds the actual API-specific resources.
     GraphicsImpl* GetImpl() const { return impl_; }
     GraphicsImpl* GetImpl() const { return impl_; }
+    /// Return OS-specific external window handle. Null if not in use.
+    void* GetExternalWindow() const { return externalWindow_; }
     /// Return window title.
     /// Return window title.
     const String& GetWindowTitle() const { return windowTitle_; }
     const String& GetWindowTitle() const { return windowTitle_; }
     /// Return window width.
     /// Return window width.
@@ -372,6 +376,8 @@ private:
     GraphicsImpl* impl_;
     GraphicsImpl* impl_;
     /// Window title.
     /// Window title.
     String windowTitle_;
     String windowTitle_;
+    /// External window, null if not in use (default.)
+    void* externalWindow_;
     /// Window width.
     /// Window width.
     int width_;
     int width_;
     /// Window height.
     /// Window height.