Browse Source

Added Graphics::GetPixelUVOffset() to get the half-pixel offset required by D3D9, avoids #ifdef'ing. Clean up shadow matrix calculation.

Lasse Öörni 11 years ago
parent
commit
0990fd72f2

+ 20 - 21
Source/Urho3D/Graphics/Batch.cpp

@@ -88,40 +88,39 @@ void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split
     float width = (float)shadowMap->GetWidth();
     float width = (float)shadowMap->GetWidth();
     float height = (float)shadowMap->GetHeight();
     float height = (float)shadowMap->GetHeight();
     
     
-    Vector2 offset(
+    Vector3 offset(
         (float)viewport.left_ / width,
         (float)viewport.left_ / width,
-        (float)viewport.top_ / height
+        (float)viewport.top_ / height,
+        0.0f
     );
     );
     
     
-    Vector2 scale(
+    Vector3 scale(
         0.5f * (float)viewport.Width() / width,
         0.5f * (float)viewport.Width() / width,
-        0.5f * (float)viewport.Height() / height
+        0.5f * (float)viewport.Height() / height,
+        1.0f
     );
     );
-    
+
+    // Add pixel-perfect offset if needed by the graphics API
+    const Vector2& pixelUVOffset = Graphics::GetPixelUVOffset();
+    offset.x_ += scale.x_ + pixelUVOffset.x_ / width;
+    offset.y_ += scale.y_ + pixelUVOffset.y_ / height;
+
     #ifdef URHO3D_OPENGL
     #ifdef URHO3D_OPENGL
-    offset.x_ += scale.x_;
-    offset.y_ += scale.y_;
+    offset.z_ = 0.5f;
+    scale.z_ = 0.5f;
     offset.y_ = 1.0f - offset.y_;
     offset.y_ = 1.0f - offset.y_;
-    // If using 4 shadow samples, offset the position diagonally by half pixel
-    if (renderer->GetShadowQuality() & SHADOWQUALITY_HIGH_16BIT)
-    {
-        offset.x_ -= 0.5f / width;
-        offset.y_ -= 0.5f / height;
-    }
-    texAdjust.SetTranslation(Vector3(offset.x_, offset.y_, 0.5f));
-    texAdjust.SetScale(Vector3(scale.x_, scale.y_, 0.5f));
     #else
     #else
-    offset.x_ += scale.x_ + 0.5f / width;
-    offset.y_ += scale.y_ + 0.5f / height;
+    scale.y_ = -scale.y_;
+    #endif
+
+    // If using 4 shadow samples, offset the position diagonally by half pixel
     if (renderer->GetShadowQuality() & SHADOWQUALITY_HIGH_16BIT)
     if (renderer->GetShadowQuality() & SHADOWQUALITY_HIGH_16BIT)
     {
     {
         offset.x_ -= 0.5f / width;
         offset.x_ -= 0.5f / width;
         offset.y_ -= 0.5f / height;
         offset.y_ -= 0.5f / height;
     }
     }
-    scale.y_ = -scale.y_;
-    texAdjust.SetTranslation(Vector3(offset.x_, offset.y_, 0.0f));
-    texAdjust.SetScale(Vector3(scale.x_, scale.y_, 1.0f));
-    #endif
+    texAdjust.SetTranslation(offset);
+    texAdjust.SetScale(scale);
     
     
     dest = texAdjust * shadowProj * shadowView * posAdjust;
     dest = texAdjust * shadowProj * shadowView * posAdjust;
 }
 }

+ 2 - 0
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -243,6 +243,8 @@ static HWND GetWindowHandle(SDL_Window* window)
 
 
 static unsigned readableDepthFormat = 0;
 static unsigned readableDepthFormat = 0;
 
 
+const Vector2 Graphics::pixelUVOffset(0.5f, 0.5f);
+
 Graphics::Graphics(Context* context) :
 Graphics::Graphics(Context* context) :
     Object(context),
     Object(context),
     impl_(new GraphicsImpl()),
     impl_(new GraphicsImpl()),

+ 6 - 1
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h

@@ -427,7 +427,9 @@ public:
     static unsigned GetReadableDepthFormat();
     static unsigned GetReadableDepthFormat();
     /// Return the API-specific texture format from a textual description, for example "rgb".
     /// Return the API-specific texture format from a textual description, for example "rgb".
     static unsigned GetFormat(const String& formatName);
     static unsigned GetFormat(const String& formatName);
-    
+    /// Return UV offset required for pixel perfect rendering.
+    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
+
 private:
 private:
     /// Create the application window.
     /// Create the application window.
     bool OpenWindow(int width, int height, bool resizable, bool borderless);
     bool OpenWindow(int width, int height, bool resizable, bool borderless);
@@ -608,6 +610,9 @@ private:
     SharedPtr<ShaderPrecache> shaderPrecache_;
     SharedPtr<ShaderPrecache> shaderPrecache_;
     /// Allowed screen orientations.
     /// Allowed screen orientations.
     String orientations_;
     String orientations_;
+
+    /// Pixel perfect UV offset.
+    static const Vector2 pixelUVOffset;
 };
 };
 
 
 /// Register Graphics library objects.
 /// Register Graphics library objects.

+ 3 - 0
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -215,6 +215,9 @@ static void GetGLPrimitiveType(unsigned elementCount, PrimitiveType type, unsign
         break;
         break;
     }
     }
 }
 }
+
+const Vector2 Graphics::pixelUVOffset(0.0f, 0.0f);
+
 Graphics::Graphics(Context* context_) :
 Graphics::Graphics(Context* context_) :
     Object(context_),
     Object(context_),
     impl_(new GraphicsImpl()),
     impl_(new GraphicsImpl()),

+ 6 - 1
Source/Urho3D/Graphics/OpenGL/OGLGraphics.h

@@ -443,7 +443,9 @@ public:
     static unsigned GetReadableDepthFormat();
     static unsigned GetReadableDepthFormat();
     /// Return the API-specific texture format from a textual description, for example "rgb".
     /// Return the API-specific texture format from a textual description, for example "rgb".
     static unsigned GetFormat(const String& formatName);
     static unsigned GetFormat(const String& formatName);
-    
+    /// Return UV offset required for pixel perfect rendering.
+    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
+
 private:
 private:
     /// Create the application window icon.
     /// Create the application window icon.
     void CreateWindowIcon();
     void CreateWindowIcon();
@@ -618,6 +620,9 @@ private:
     SharedPtr<ShaderPrecache> shaderPrecache_;
     SharedPtr<ShaderPrecache> shaderPrecache_;
     /// Allowed screen orientations.
     /// Allowed screen orientations.
     String orientations_;
     String orientations_;
+
+    /// Pixel perfect UV offset.
+    static const Vector2 pixelUVOffset;
 };
 };
 
 
 /// Register Graphics library objects.
 /// Register Graphics library objects.

+ 5 - 7
Source/Urho3D/Graphics/View.cpp

@@ -735,8 +735,9 @@ void View::SetGBufferShaderParameters(const IntVector2& texSize, const IntRect&
     Vector4 bufferUVOffset(((float)viewRect.left_) / texWidth + widthRange,
     Vector4 bufferUVOffset(((float)viewRect.left_) / texWidth + widthRange,
         1.0f - (((float)viewRect.top_) / texHeight + heightRange), widthRange, heightRange);
         1.0f - (((float)viewRect.top_) / texHeight + heightRange), widthRange, heightRange);
     #else
     #else
-    Vector4 bufferUVOffset((0.5f + (float)viewRect.left_) / texWidth + widthRange,
-        (0.5f + (float)viewRect.top_) / texHeight + heightRange, widthRange, heightRange);
+    const Vector2& pixelUVOffset = Graphics::GetPixelUVOffset();
+    Vector4 bufferUVOffset((pixelUVOffset.x_ + (float)viewRect.left_) / texWidth + widthRange,
+        (pixelUVOffset.y_ + (float)viewRect.top_) / texHeight + heightRange, widthRange, heightRange);
     #endif
     #endif
     graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
     graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
     
     
@@ -1788,12 +1789,9 @@ void View::RenderQuad(RenderPathCommand& command)
         float width = (float)renderTargets_[nameHash]->GetWidth();
         float width = (float)renderTargets_[nameHash]->GetWidth();
         float height = (float)renderTargets_[nameHash]->GetHeight();
         float height = (float)renderTargets_[nameHash]->GetHeight();
         
         
+        const Vector2& pixelUVOffset = Graphics::GetPixelUVOffset();
         graphics_->SetShaderParameter(invSizeName, Vector2(1.0f / width, 1.0f / height));
         graphics_->SetShaderParameter(invSizeName, Vector2(1.0f / width, 1.0f / height));
-        #ifdef URHO3D_OPENGL
-        graphics_->SetShaderParameter(offsetsName, Vector2::ZERO);
-        #else
-        graphics_->SetShaderParameter(offsetsName, Vector2(0.5f / width, 0.5f / height));
-        #endif
+        graphics_->SetShaderParameter(offsetsName, Vector2(pixelUVOffset.x_ / width, pixelUVOffset.y_ / height));
     }
     }
     
     
     graphics_->SetBlendMode(BLEND_REPLACE);
     graphics_->SetBlendMode(BLEND_REPLACE);

+ 1 - 0
Source/Urho3D/UI/UI.cpp

@@ -691,6 +691,7 @@ void UI::Initialize()
     PROFILE(InitUI);
     PROFILE(InitUI);
 
 
     graphics_ = graphics;
     graphics_ = graphics;
+    UIBatch::posAdjust = Vector3(Graphics::GetPixelUVOffset(), 0.0f);
 
 
     rootElement_->SetSize(graphics->GetWidth(), graphics->GetHeight());
     rootElement_->SetSize(graphics->GetWidth(), graphics->GetHeight());
     rootModalElement_->SetSize(rootElement_->GetSize());
     rootModalElement_->SetSize(rootElement_->GetSize());

+ 7 - 13
Source/Urho3D/UI/UIBatch.cpp

@@ -31,13 +31,7 @@
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
-#ifdef URHO3D_OPENGL
-static const float posAdjust = 0.0f;
-#else
-static const float posAdjust = 0.5f;
-#endif
-
-static const Vector3 posAdjustVec(posAdjust, posAdjust, 0.0f);
+Vector3 UIBatch::posAdjust(0.0f, 0.0f, 0.0f);
 
 
 UIBatch::UIBatch() :
 UIBatch::UIBatch() :
     element_(0),
     element_(0),
@@ -112,9 +106,9 @@ void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int t
     
     
     const IntVector2& screenPos = element_->GetScreenPosition();
     const IntVector2& screenPos = element_->GetScreenPosition();
     
     
-    float left = (float)(x + screenPos.x_) - posAdjust;
+    float left = (float)(x + screenPos.x_) - posAdjust.x_;
     float right = left + (float)width;
     float right = left + (float)width;
-    float top = (float)(y + screenPos.y_) - posAdjust;
+    float top = (float)(y + screenPos.y_) - posAdjust.x_;
     float bottom = top + (float)height;
     float bottom = top + (float)height;
     
     
     float leftUV = texOffsetX * invTextureSize_.x_;
     float leftUV = texOffsetX * invTextureSize_.x_;
@@ -178,10 +172,10 @@ void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int h
         bottomRightColor = GetInterpolatedColor(x + width, y + height);
         bottomRightColor = GetInterpolatedColor(x + width, y + height);
     }
     }
     
     
-    Vector3 v1 = (transform * Vector3((float)x, (float)y, 0.0f)) - posAdjustVec;
-    Vector3 v2 = (transform * Vector3((float)x + (float)width, (float)y, 0.0f)) - posAdjustVec;
-    Vector3 v3 = (transform * Vector3((float)x, (float)y + (float)height, 0.0f)) - posAdjustVec;
-    Vector3 v4 = (transform * Vector3((float)x + (float)width, (float)y + (float)height, 0.0f)) - posAdjustVec;
+    Vector3 v1 = (transform * Vector3((float)x, (float)y, 0.0f)) - posAdjust;
+    Vector3 v2 = (transform * Vector3((float)x + (float)width, (float)y, 0.0f)) - posAdjust;
+    Vector3 v3 = (transform * Vector3((float)x, (float)y + (float)height, 0.0f)) - posAdjust;
+    Vector3 v4 = (transform * Vector3((float)x + (float)width, (float)y + (float)height, 0.0f)) - posAdjust;
     
     
     float leftUV = ((float)texOffsetX) * invTextureSize_.x_;
     float leftUV = ((float)texOffsetX) * invTextureSize_.x_;
     float topUV = ((float)texOffsetY) * invTextureSize_.y_;
     float topUV = ((float)texOffsetY) * invTextureSize_.y_;

+ 4 - 1
Source/Urho3D/UI/UIBatch.h

@@ -63,7 +63,7 @@ public:
     
     
     /// Add or merge a batch.
     /// Add or merge a batch.
     static void AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches);
     static void AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches);
-    
+
     /// Element this batch represents.
     /// Element this batch represents.
     UIElement* element_;
     UIElement* element_;
     /// Blending mode.
     /// Blending mode.
@@ -84,6 +84,9 @@ public:
     unsigned vertexEnd_;
     unsigned vertexEnd_;
     /// Gradient flag.
     /// Gradient flag.
     bool useGradient_;
     bool useGradient_;
+
+    /// Position adjustment vector for pixel-perfect rendering. Initialized by UI.
+    static Vector3 posAdjust;
 };
 };
 
 
 }
 }

+ 2 - 8
Source/Urho3D/Urho2D/StaticSprite2D.cpp

@@ -24,6 +24,7 @@
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 #include "../Urho2D/Sprite2D.h"
 #include "../Urho2D/Sprite2D.h"
 #include "../Urho2D/StaticSprite2D.h"
 #include "../Urho2D/StaticSprite2D.h"
+#include "../Graphics/Graphics.h"
 #include "../Graphics/Texture2D.h"
 #include "../Graphics/Texture2D.h"
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
@@ -231,18 +232,11 @@ void StaticSprite2D::UpdateVertices()
         hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;
         hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;
     }
     }
 
 
-#ifdef URHO3D_OPENGL
-    float leftX = -width * hotSpotX;
-    float rightX = width * (1.0f - hotSpotX);
-    float bottomY = -height * hotSpotY;
-    float topY = height * (1.0f - hotSpotY);
-#else
-    const float halfPixelOffset = 0.5f * PIXEL_SIZE;
+    const float halfPixelOffset = Graphics::GetPixelUVOffset().x_ * PIXEL_SIZE;
     float leftX = -width * hotSpotX + halfPixelOffset;
     float leftX = -width * hotSpotX + halfPixelOffset;
     float rightX = width * (1.0f - hotSpotX) + halfPixelOffset;
     float rightX = width * (1.0f - hotSpotX) + halfPixelOffset;
     float bottomY = -height * hotSpotY + halfPixelOffset;
     float bottomY = -height * hotSpotY + halfPixelOffset;
     float topY = height * (1.0f - hotSpotY) + halfPixelOffset;
     float topY = height * (1.0f - hotSpotY) + halfPixelOffset;
-#endif
 
 
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     const Matrix3x4& worldTransform = node_->GetWorldTransform();