aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorVicent Marti2008-05-16 20:40:24 +0000
committerVicent Marti2008-05-16 20:40:24 +0000
commitb999366ae911172b9a8ab8a0e8955b73b055cce2 (patch)
tree15715b40e4561abe126fc29cfc8606745fbc27e9 /graphics
parentf19480b74090159296be1aa608591123e917dd36 (diff)
downloadscummvm-rg350-b999366ae911172b9a8ab8a0e8955b73b055cce2.tar.gz
scummvm-rg350-b999366ae911172b9a8ab8a0e8955b73b055cce2.tar.bz2
scummvm-rg350-b999366ae911172b9a8ab8a0e8955b73b055cce2.zip
- Shadows revisited
- Gradients. svn-id: r32145
Diffstat (limited to 'graphics')
-rw-r--r--graphics/VectorRenderer.cpp202
-rw-r--r--graphics/VectorRenderer.h45
2 files changed, 175 insertions, 72 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp
index 6f6aa9b125..ad2ef2b250 100644
--- a/graphics/VectorRenderer.cpp
+++ b/graphics/VectorRenderer.cpp
@@ -30,12 +30,33 @@
#include "common/system.h"
#include "common/events.h"
-namespace Graphics {
+inline uint32 fp_sqroot(uint32 x) {
+ register uint32 root, remHI, remLO, testDIV, count;
+
+ root = 0;
+ remHI = 0;
+ remLO = x;
+ count = 23;
+
+ do {
+ remHI = (remHI << 2) | (remLO >> 30);
+ remLO <<= 2;
+ root <<= 1;
+ testDIV = (root << 1) + 1;
-inline uint32 fp_sqroot(uint32 x);
+ if (remHI >= testDIV) {
+ remHI -= testDIV;
+ root++;
+ }
+ } while (count--);
+
+ return root;
+}
+
+namespace Graphics {
VectorRenderer *createRenderer() {
- return new VectorRendererSpec<uint16, ColorMasks<565> >;
+ return new VectorRendererAA<uint16, ColorMasks<565> >;
}
@@ -59,19 +80,20 @@ void vector_renderer_test(OSystem *_system) {
_system->showOverlay();
while (true) { // draw!!
- vr->setFgColor(255, 255, 255);
+ vr->setFgColor(255, 0, 206);
vr->fillSurface();
- vr->setFgColor(255, 0, 0);
+ vr->setFgColor(255, 247, 222);
vr->setBgColor(25, 25, 175);
- vr->setFillMode(VectorRenderer::kForegroundFill);
- vr->setStrokeWidth(6);
+ vr->setGradientColors(206, 121, 99, 173, 40, 8);
+ vr->setFillMode(VectorRenderer::kGradientFill);
+ vr->setStrokeWidth(1);
vr->shadowEnable(1, 1);
vr->drawLine(25, 25, 125, 300);
vr->drawCircle(250, 250, 100);
vr->drawSquare(150, 25, 100, 75);
- vr->drawRoundedSquare(275, 25, 8, 100, 75);
+ vr->drawRoundedSquare(275, 25, 16, 128, 128);
_system->copyRectToOverlay((OverlayColor*)_screen.getBasePtr(0, 0), _screen.w, 0, 0, _screen.w, _screen.w);
_system->updateScreen();
@@ -90,21 +112,21 @@ template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
drawCircle(int x, int y, int r) {
if (Base::_fillMode != kNoFill && Base::_shadows) {
- drawCircleAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, r, 0, true);
+ drawCircleAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, r, 0, kForegroundFill);
}
switch(Base::_fillMode) {
case kNoFill:
- drawCircleAlg(x, y, r, _fgColor, false);
+ drawCircleAlg(x, y, r, _fgColor, kNoFill);
break;
case kForegroundFill:
- drawCircleAlg(x, y, r, _fgColor, true);
+ drawCircleAlg(x, y, r, _fgColor, kForegroundFill);
break;
case kBackgroundFill:
- VectorRendererSpec::drawCircleAlg(x, y, r, _bgColor, true);
- drawCircleAlg(x, y, r, _fgColor, false);
+ drawCircleAlg(x, y, r, _fgColor, kForegroundFill);
+ drawCircleAlg(x, y, r - Base::_strokeWidth, _bgColor, kBackgroundFill);
break;
case kGradientFill:
@@ -116,24 +138,26 @@ template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
drawSquare(int x, int y, int w, int h) {
if (Base::_fillMode != kNoFill && Base::_shadows) {
- drawSquareAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, w, h, 0, true);
+ drawSquareShadow(x, y, w, h);
}
switch(Base::_fillMode) {
case kNoFill:
- drawSquareAlg(x, y, w, h, _fgColor, false);
+ drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
break;
case kForegroundFill:
- drawSquareAlg(x, y, w, h, _fgColor, true);
+ drawSquareAlg(x, y, w, h, _fgColor, kForegroundFill);
break;
case kBackgroundFill:
- drawSquareAlg(x, y, w, h, _bgColor, true);
- drawSquareAlg(x, y, w, h, _fgColor, false);
+ drawSquareAlg(x, y, w, h, _bgColor, kBackgroundFill);
+ drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
break;
case kGradientFill:
+ VectorRendererSpec::drawSquareAlg(x, y, w, h, 0, kGradientFill);
+ drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
break;
}
}
@@ -142,37 +166,48 @@ template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
drawRoundedSquare(int x, int y, int r, int w, int h) {
if (Base::_fillMode != kNoFill && Base::_shadows) {
- drawRoundedSquareAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, r, w, h, 0, true);
+ drawRoundedSquareShadow(x, y, r, w, h);
}
switch(Base::_fillMode) {
case kNoFill:
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, false);
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
break;
case kForegroundFill:
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, true);
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kForegroundFill);
break;
case kBackgroundFill:
- VectorRendererSpec::drawRoundedSquareAlg(x, y, r, w, h, _bgColor, true);
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, false);
+ VectorRendererSpec::drawRoundedSquareAlg(x, y, r, w, h, _bgColor, kBackgroundFill);
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
break;
case kGradientFill:
+ if (Base::_strokeWidth > 1) {
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kForegroundFill);
+ VectorRendererSpec::drawRoundedSquareAlg(x + Base::_strokeWidth/2, y + Base::_strokeWidth/2,
+ r - Base::_strokeWidth/2, w - Base::_strokeWidth, h - Base::_strokeWidth, 0, kGradientFill);
+ } else {
+ VectorRendererSpec::drawRoundedSquareAlg(x, y, r, w, h, 0, kGradientFill);
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
+ }
break;
}
}
template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
-drawSquareAlg(int x, int y, int w, int h, PixelType color, bool fill) {
-
+drawSquareAlg(int x, int y, int w, int h, PixelType color, FillMode fill_m) {
PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
int pitch = Base::surfacePitch();
+ int max_h = h;
- if (fill) {
+ if (fill_m != kNoFill) {
while (h--) {
+ if (fill_m == kGradientFill)
+ color = calcGradient(max_h - h, max_h);
+
Common::set_to(ptr, ptr + w, color);
ptr += pitch;
}
@@ -194,6 +229,43 @@ drawSquareAlg(int x, int y, int w, int h, PixelType color, bool fill) {
}
template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType, PixelFormat>::
+drawSquareShadow(int x, int y, int w, int h) {
+ int blur = 8;
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + blur);
+ int pitch = Base::surfacePitch();
+ int i, j;
+
+ i = h - blur;
+
+ while (i--) {
+ j = blur;
+ while (j--)
+ blendPixelPtr(ptr + j, 0, ((blur - j) << 8) / blur);
+ ptr += pitch;
+ }
+
+ ptr = (PixelType *)_activeSurface->getBasePtr(x + blur, y + h - 1);
+
+ while (i++ < blur) {
+ j = w - blur;
+ while (j--)
+ blendPixelPtr(ptr + j, 0, ((blur - i) << 8) / blur);
+ ptr += pitch;
+ }
+
+ ptr = (PixelType *)_activeSurface->getBasePtr(x + w, y + h);
+
+ i = 0;
+ while (i++ < blur) {
+ j = blur - 1;
+ while (j--)
+ blendPixelPtr(ptr + j, 0, (((blur - j) * (blur - i)) << 8) / (blur * blur));
+ ptr += pitch;
+ }
+}
+
+template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType,PixelFormat>::
drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) {
PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1);
@@ -361,29 +433,6 @@ drawLine(int x1, int y1, int x2, int y2) {
}
}
-inline uint32 fp_sqroot(uint32 x) {
- register uint32 root, remHI, remLO, testDIV, count;
-
- root = 0;
- remHI = 0;
- remLO = x;
- count = 23;
-
- do {
- remHI = (remHI << 2) | (remLO >> 30);
- remLO <<= 2;
- root <<= 1;
- testDIV = (root << 1) + 1;
-
- if (remHI >= testDIV) {
- remHI -= testDIV;
- root++;
- }
- } while (count--);
-
- return root;
-}
-
#define __BE_ALGORITHM() { \
if (f >= 0) { \
y--; \
@@ -416,13 +465,13 @@ inline uint32 fp_sqroot(uint32 x) {
template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
-drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) {
+drawCircleAlg(int x1, int y1, int r, PixelType color, FillMode fill_m) {
int f, ddF_x, ddF_y;
int x, y, px, py, sw = 0;
int pitch = Base::surfacePitch();
PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (fill == false) {
+ if (fill_m == kNoFill) {
while (sw++ < Base::_strokeWidth) {
__BE_RESET();
r--;
@@ -458,7 +507,13 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) {
template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool fill) {
+drawRoundedSquareShadow(int x1, int y1, int r, int w, int h) {
+
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType, PixelFormat>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillMode fill_m) {
int f, ddF_x, ddF_y;
int x, y, px, py;
int pitch = Base::surfacePitch();
@@ -470,10 +525,11 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool
PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- int short_h = h - (2 * r) + 2;
int real_radius = r;
+ int short_h = h - (2 * r) + 2;
+ int long_h = h;
- if (fill == false) {
+ if (fill_m == kNoFill) {
while (sw++ < Base::_strokeWidth) {
Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
@@ -501,20 +557,34 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool
}
} else {
__BE_RESET();
- while (x++ < y) {
- __BE_ALGORITHM();
- Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
- Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
+ if (fill_m == kGradientFill) {
+ while (x++ < y) {
+ __BE_ALGORITHM();
+ Common::set_to(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h));
+ Common::set_to(ptr_tl - y - px, ptr_tr + y - px, calcGradient(real_radius - x, long_h));
- Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
- Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
+ Common::set_to(ptr_bl - x + py, ptr_br + x + py, calcGradient(long_h - r + y, long_h));
+ Common::set_to(ptr_bl - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h));
+ }
+ } else {
+ while (x++ < y) {
+ __BE_ALGORITHM();
+
+ Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
+ Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
+
+ Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
+ Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
- __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ }
}
ptr_fill += pitch * r;
while (short_h--) {
+ if (fill_m == kGradientFill)
+ color = calcGradient(real_radius++, long_h);
Common::set_to(ptr_fill, ptr_fill + w + 1, color);
ptr_fill += pitch;
}
@@ -545,7 +615,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool
template<typename PixelType, typename PixelFormat>
void VectorRendererAA<PixelType, PixelFormat>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool fill) {
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillMode fill_m) {
int x, y;
int p = Base::surfacePitch(), px, py;
int sw = 0, sp = 0, hp = h * p;
@@ -562,7 +632,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool
int short_h = h - 2 * r;
- if (fill == false) {
+ if (fill_m == kNoFill) {
while (sw++ < Base::_strokeWidth) {
Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
@@ -614,7 +684,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool
template<typename PixelType, typename PixelFormat>
void VectorRendererAA<PixelType, PixelFormat>::
-drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) {
+drawCircleAlg(int x1, int y1, int r, PixelType color, FillMode fill_m) {
int x, y, sw = 0;
int p = Base::surfacePitch(), px, py;
@@ -624,7 +694,7 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) {
PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (fill == false) {
+ if (fill_m == kNoFill) {
while (sw++ < Base::_strokeWidth) {
x = r - (sw - 1); y = 0; T = 0;
px = p * x; py = 0;
@@ -662,4 +732,4 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) {
}
}
-} // end of namespace Graphics
+} // end of namespace Graphics \ No newline at end of file
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index bed1e337ca..23653aa5fc 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -157,6 +157,8 @@ public:
*/
virtual void setBgColor(uint8 r, uint8 g, uint8 b) = 0;
+ virtual void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) = 0;
+
/**
* Sets the active drawing surface. All drawing from this
* point on will be done on that surface.
@@ -298,6 +300,15 @@ public:
this->_bgColor = RGBToColor<PixelFormat>(r, g, b);
}
+ void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) {
+ _gradientEnd = RGBToColor<PixelFormat>(r2, g2, b2);
+ _gradientStart = RGBToColor<PixelFormat>(r1, g1, b1);
+
+ _gradientBytes[0] = (_gradientEnd & PixelFormat::kRedMask) - (_gradientStart & PixelFormat::kRedMask);
+ _gradientBytes[1] = (_gradientEnd & PixelFormat::kGreenMask) - (_gradientStart & PixelFormat::kGreenMask);
+ _gradientBytes[2] = (_gradientEnd & PixelFormat::kBlueMask) - (_gradientStart & PixelFormat::kBlueMask);
+ }
+
/**
* @see VectorRenderer::fillSurface()
*/
@@ -342,6 +353,10 @@ protected:
putPixel(x, y, color);
}
+ virtual inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
+ *ptr = (PixelType)color;
+ }
+
/*
* "Bresenham's Line Algorithm", as described in Wikipedia.
* Based on the current implementation in "graphics/primitives.cpp".
@@ -350,12 +365,30 @@ protected:
* floating point operations and direct access to pixel buffer, assumes no special cases.
*/
virtual void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color);
- virtual void drawCircleAlg(int x, int y, int r, PixelType color, bool fill = false);
- virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool fill = false);
- virtual void drawSquareAlg(int x, int y, int w, int h, PixelType color, bool fill = false);
+ 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 drawSquareShadow(int x, int y, int w, int h);
+ virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h);
+
+ inline PixelType calcGradient(int pos, int max, int factor = 1) {
+ PixelType output = 0;
+ pos = (0x1000 * MIN(pos * factor, max)) / max;
+
+ output |= (_gradientStart + (_gradientBytes[0] * pos >> 12)) & PixelFormat::kRedMask;
+ output |= (_gradientStart + (_gradientBytes[1] * pos >> 12)) & PixelFormat::kGreenMask;
+ output |= (_gradientStart + (_gradientBytes[2] * pos >> 12)) & PixelFormat::kBlueMask;
+ output |= ~(PixelFormat::kRedMask | PixelFormat::kGreenMask | PixelFormat::kBlueMask);
+
+ return output;
+ }
PixelType _fgColor; /** Foreground color currently being used to draw on the renderer */
PixelType _bgColor; /** Background color currently being used to draw on the renderer */
+
+ PixelType _gradientStart;
+ PixelType _gradientEnd;
+ int _gradientBytes[3];
};
/**
@@ -396,7 +429,7 @@ protected:
* @param ptr Pointer to the pixel where we must draw
* @param alpha Intensity of the pixel (0-255).
*/
- inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
+ inline virtual void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
/**
* @see VectorRenderer::blendPixel()
@@ -420,9 +453,9 @@ protected:
*
* @see VectorRenderer::drawCircleAlg()
*/
- virtual void drawCircleAlg(int x, int y, int r, PixelType color, bool fill = false);
+ 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, bool fill = false);
+ virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillMode fill_m);
};
} // end of namespace Graphics