From e8d15277465c850fbad56b7ee3757e7b5cee0b2a Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Sat, 26 Jul 2008 22:58:02 +0000 Subject: Convolution filters for the vector renderer. Pretty cool. svn-id: r33319 --- graphics/VectorRenderer.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ graphics/VectorRenderer.h | 26 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 352ab971a3..a708d5ac1f 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -50,6 +50,15 @@ VectorRenderer *createRenderer(int mode) { } } +const VectorRenderer::ConvolutionDataSet VectorRenderer::_convolutionData[VectorRenderer::kConvolutionMAX] = { + { {{1, 1, 1}, {1, 8, 1}, {1, 1, 1}}, 16, 0 }, // soft blur matrix + { {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}, 18, 0 }, // hard blur matrix + { {{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}, 16, 0 }, // gaussian blur matrix + { {{2, 0, 0}, {0, -1, 0}, {0, 0, -1}}, 1, 127}, // emboss matrix + { {{-1, -1, -1}, {-1, 9, -1}, {-1, -1, -1}}, 1, 0}, // sharpen matrix + { {{1, 1, 1}, {1, -7, 1}, {1, 1, 1}}, 1, 0} // edge find matrix +}; + /******************************************************************** * DRAWSTEP handling functions ********************************************************************/ @@ -159,6 +168,39 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect & /******************************************************************** * MISCELANEOUS functions ********************************************************************/ +template +void VectorRendererSpec:: +areaConvolution(const Common::Rect &area, const int filter[3][3], int filterDiv, int offset) { + PixelType *ptr = 0; + int newR, newG, newB; + uint8 r, g, b; + int yVal; + + for (int y = area.top; y < area.bottom; ++y) { + for (int x = area.left; x < area.right; ++x) { + for (int j = 0; j < 3; ++j) { + yVal = MIN(MAX(y - 1 + j, 0), area.bottom - 1); + + for (int i = 0; i < 3; ++i) { + ptr = (PixelType *)Base::_activeSurface->getBasePtr(MIN(MAX(x - 1 + j, 0), area.right - 1), yVal); + colorToRGB((uint32)*ptr, r, g, b); + + newR += r * filter[j][i]; + newG += g * filter[j][i]; + newB += b * filter[j][i]; + } + } + + newR = (newR / filterDiv) + offset; + newG = (newG / filterDiv) + offset; + newB = (newB / filterDiv) + offset; + + ptr = (PixelType *)Base::_activeSurface->getBasePtr(x, y); + *ptr = RGBToColor(CLIP(newR, 0, 255), CLIP(newG, 0, 255), CLIP(newB, 0, 255)); + } + } +} + /** Fixed point SQUARE ROOT **/ inline uint32 fp_sqroot(uint32 x) { register uint32 root, remHI, remLO, testDIV, count; diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 88072da923..8a02d7fc21 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -113,6 +113,22 @@ public: kTriangleLeft, kTriangleRight }; + + enum ConvolutionData { + kConvolutionSoftBlur, + kConvolutionHardBlur, + kConvolutionGaussianBlur, + kConvolutionEmboss, + kConvolutionSharpen, + kConvolutionEdgeDetect, + kConvolutionMAX + }; + + struct ConvolutionDataSet { + int matrix[3][3]; + int divisor; + int offset; + }; /** * Draws a line by considering the special cases for optimization. @@ -412,6 +428,12 @@ public: virtual void disableShadows() { _disableShadows = true; } virtual void enableShadows() { _disableShadows = false; } + + virtual void areaConvolution(const Common::Rect &area, const int filter[3][3], int filterDiv, int offset) = 0; + + virtual void applyConvolutionMatrix(const ConvolutionData id, const Common::Rect &area) { + areaConvolution(area, _convolutionData[id].matrix, _convolutionData[id].divisor, _convolutionData[id].offset); + } protected: Surface *_activeSurface; /** Pointer to the surface currently being drawn */ @@ -425,6 +447,8 @@ protected: int _gradientFactor; /** Multiplication factor of the active gradient */ int _gradientBytes[3]; /** Color bytes of the active gradient, used to speed up calculation */ + + static const ConvolutionDataSet _convolutionData[kConvolutionMAX]; }; /** @@ -776,6 +800,8 @@ protected: } while (--n > 0); } } + + virtual void areaConvolution(const Common::Rect &area, const int filter[3][3], int filterDiv, int offset); PixelType _fgColor; /** Foreground color currently being used to draw on the renderer */ PixelType _bgColor; /** Background color currently being used to draw on the renderer */ -- cgit v1.2.3