diff options
author | Vicent Marti | 2008-06-01 00:28:16 +0000 |
---|---|---|
committer | Vicent Marti | 2008-06-01 00:28:16 +0000 |
commit | 5d2d18421386021eb7754684edf908e02276add5 (patch) | |
tree | ed1498a4bd66a9307498fdaab86991d5abbbbb19 /graphics | |
parent | 8a83eafbf3119c4acec8e294b883da4c500efeeb (diff) | |
download | scummvm-rg350-5d2d18421386021eb7754684edf908e02276add5.tar.gz scummvm-rg350-5d2d18421386021eb7754684edf908e02276add5.tar.bz2 scummvm-rg350-5d2d18421386021eb7754684edf908e02276add5.zip |
- Triangles!
svn-id: r32451
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/VectorRenderer.cpp | 145 | ||||
-rw-r--r-- | graphics/VectorRenderer.h | 20 |
2 files changed, 162 insertions, 3 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index aba940e386..b9d44a224e 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -166,6 +166,28 @@ inline uint32 fp_sqroot(uint32 x) { a1 = ~a2; \ } +#define __TRIANGLE_MAINX() \ + if (error_term >= 0) { \ + ptr_right += pitch; \ + ptr_left += pitch; \ + error_term += dysub; \ + } else { \ + error_term += ddy; \ + } \ + ptr_right++; \ + ptr_left--; + +#define __TRIANGLE_MAINY() \ + if (error_term >= 0) { \ + ptr_right++; \ + ptr_left--; \ + error_term += dxsub; \ + } else { \ + error_term += ddx; \ + } \ + ptr_right += pitch; \ + ptr_left += pitch; + /******************************************************************** * Primitive shapes drawing - Public API calls - VectorRendererSpec ********************************************************************/ @@ -235,7 +257,7 @@ drawCircle(int x, int y, int r) { drawCircleAlg(x + Base::_shadowOffset + 1, y + Base::_shadowOffset + 1, r, 0, kFillForeground); } - switch(Base::_fillMode) { + switch (Base::_fillMode) { case kFillDisabled: if (Base::_strokeWidth) drawCircleAlg(x, y, r, _fgColor, kFillDisabled); @@ -273,7 +295,7 @@ drawSquare(int x, int y, int w, int h) { drawSquareShadow(x, y, w, h, Base::_shadowOffset); } - switch(Base::_fillMode) { + switch (Base::_fillMode) { case kFillDisabled: if (Base::_strokeWidth) drawSquareAlg(x, y, w, h, _fgColor, kFillDisabled); @@ -309,7 +331,7 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset); } - switch(Base::_fillMode) { + switch (Base::_fillMode) { case kFillDisabled: if (Base::_strokeWidth) drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillDisabled); @@ -338,6 +360,41 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { } } +template<typename PixelType, typename PixelFormat> +void VectorRendererSpec<PixelType, PixelFormat>:: +drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { + if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h) + return; + + PixelType color = 0; + + if (Base::_strokeWidth <= 1) { + if (Base::_fillMode == kFillForeground) + color = _fgColor; + else if (Base::_fillMode == kFillBackground) + color = _bgColor; + } else { + if (Base::_fillMode == kFillDisabled) + return; + color = _fgColor; + } + + switch(orient) { + case kTriangleUp: + case kTriangleDown: + drawTriangleVertAlg(x, y, w, h, (orient == kTriangleDown), color, Base::_fillMode); + break; + + case kTriangleLeft: + case kTriangleRight: + break; + } + + if (Base::_strokeWidth > 0) + if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) + drawTriangleVertAlg(x, y, w, h, (orient == kTriangleDown), _fgColor, kFillDisabled); +} + /******************************************************************** * Aliased Primitive drawing ALGORITHMS - VectorRendererSpec ********************************************************************/ @@ -422,6 +479,88 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { *ptr = (PixelType)color; } +/** VERTICAL TRIANGLE DRAWING ALGORITHM **/ +template<typename PixelType, typename PixelFormat> +void VectorRendererSpec<PixelType,PixelFormat>:: +drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) { + int dx = w >> 1, dy = h, gradient_h = 0; + int pitch = Base::surfacePitch(); + PixelType *ptr_right = 0, *ptr_left = 0; + + if (inverted) { + ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1); + ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + w, y1); + } else { + ptr_right = ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + dx, y1); + } + + if (dx > dy) { + int ddy = dy * 2; + int dysub = ddy - (dx * 2); + int error_term = ddy - dx; + + switch(fill_m) { + case kFillDisabled: + while (dx--) { + __TRIANGLE_MAINX(); + *ptr_right = color; + *ptr_left = color; + } + colorFill(ptr_left, ptr_right, color); + break; + + case kFillForeground: + case kFillBackground: + while (dx--) { + __TRIANGLE_MAINX(); + if (inverted) colorFill(ptr_right, ptr_left, color); + else colorFill(ptr_left, ptr_right, color); + } + break; + + case kFillGradient: + while (dx--) { + __TRIANGLE_MAINX(); + if (inverted) colorFill(ptr_right, ptr_left, calcGradient(gradient_h++, h)); + else colorFill(ptr_left, ptr_right, calcGradient(gradient_h++, h)); + } + break; + } + } else { + int ddx = dx * 2; + int dxsub = ddx - (dy * 2); + int error_term = ddx - dy; + + switch(fill_m) { + case kFillDisabled: + while (dy--) { + __TRIANGLE_MAINY(); + *ptr_right = color; + *ptr_left = color; + } + colorFill(ptr_left, ptr_right, color); + break; + + case kFillForeground: + case kFillBackground: + while (dy--) { + __TRIANGLE_MAINY(); + if (inverted) colorFill(ptr_right, ptr_left, color); + else colorFill(ptr_left, ptr_right, color); + } + break; + case kFillGradient: + while (dy--) { + __TRIANGLE_MAINY(); + if (inverted) colorFill(ptr_right, ptr_left, calcGradient(gradient_h++, h)); + else colorFill(ptr_left, ptr_right, calcGradient(gradient_h++, h)); + } + break; + } + } +} + + /** ROUNDED SQUARE ALGORITHM **/ template<typename PixelType, typename PixelFormat> void VectorRendererSpec<PixelType, PixelFormat>:: diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 98bb25a2cb..b6c72425d7 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -97,6 +97,13 @@ public: kFillGradient = 3 }; + enum TriangleOrientation { + kTriangleUp, + kTriangleDown, + kTriangleLeft, + kTriangleRight + }; + /** * Draws a line by considering the special cases for optimization. * @@ -138,6 +145,8 @@ public: */ virtual void drawRoundedSquare(int x, int y, int r, int w, int h) = 0; + virtual void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient) = 0; + /** * Gets the pixel pitch for the current drawing surface. * Note: This is a real pixel-pitch, not a byte-pitch. @@ -360,6 +369,11 @@ public: void drawRoundedSquare(int x, int y, int r, int w, int h); /** + * @see VectorRenderer::drawTriangle() + */ + void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient); + + /** * @see VectorRenderer::setFgColor() */ void setFgColor(uint8 r, uint8 g, uint8 b) { @@ -498,6 +512,7 @@ protected: virtual void drawCircleAlg(int x, int y, int r, PixelType color, FillMode fill_m); virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillMode fill_m); virtual void drawSquareAlg(int x, int y, int w, int h, PixelType color, FillMode fill_m); + virtual void drawTriangleVertAlg(int x, int y, int w, int h, bool inverted, PixelType color, FillMode fill_m); /** * SHADOW DRAWING ALGORITHMS @@ -565,6 +580,11 @@ protected: * @param color Color of the pixel */ virtual inline void colorFill(PixelType *first, PixelType *last, PixelType color) { + if (first == last) { + *first = color; + return; + } + register PixelType *ptr = first; register int count = (last - first); register int n = (count + 7) >> 3; |