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) :
     Object(context),
     impl_(new GraphicsImpl()),
+    externalWindow_(0),
     width_(0),
     height_(0),
     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)
 {
     windowTitle_ = windowTitle;
@@ -328,6 +337,8 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
             multiSample = 1;
     }
     
+    AdjustWindow(width, height, fullscreen);
+    
     if (fullscreen)
     {
         impl_->presentParams_.BackBufferFormat = fullscreenFormat;
@@ -365,8 +376,6 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
     vsync_ = vsync;
     tripleBuffer_ = tripleBuffer;
     
-    AdjustWindow(width, height, fullscreen);
-    
     if (!impl_->device_)
     {
         unsigned adapter = D3DADAPTER_DEFAULT;
@@ -528,6 +537,16 @@ bool Graphics::BeginFrame()
     if (!IsInitialized())
         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
     HRESULT hr = impl_->device_->TestCooperativeLevel();
     if (hr != D3D_OK)
@@ -1915,7 +1934,10 @@ unsigned Graphics::GetDepthStencilFormat()
 
 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_)
     {
@@ -1926,10 +1948,19 @@ bool Graphics::OpenWindow(int width, int height)
     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()
@@ -2144,10 +2175,9 @@ void Graphics::OnDeviceReset()
     else
     {
         if (!depthTexture_)
-        {
             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();
         systemDepthStencil_ = false;

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

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

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

@@ -133,6 +133,7 @@ bool CheckExtension(const String& name)
 Graphics::Graphics(Context* context_) :
     Object(context_),
     impl_(new GraphicsImpl()),
+    externalWindow_(0),
     width_(0),
     height_(0),
     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)
 {
     windowTitle_ = windowTitle;
@@ -269,7 +278,13 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
         if (fullscreen)
             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_)
         {
             LOGERROR("Could not open window");
@@ -389,6 +404,16 @@ bool Graphics::BeginFrame()
     if (!IsInitialized() || IsDeviceLost())
         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
     ResetRenderTargets();
     

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

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