[Scummvm-cvs-logs] SF.net SVN: scummvm: [32164] scummvm/branches/gsoc2008-gui/graphics

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Sun May 18 02:18:17 CEST 2008


Revision: 32164
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32164&view=rev
Author:   Tanoku
Date:     2008-05-17 17:18:15 -0700 (Sat, 17 May 2008)

Log Message:
-----------
- Shadows revisited.
- Test rendering... starting to look like a GUI.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-05-17 23:59:56 UTC (rev 32163)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-05-18 00:18:15 UTC (rev 32164)
@@ -81,20 +81,26 @@
 
 	while (true) { // draw!!
 		vr->setFgColor(255, 0, 206);
-		vr->fillSurface();
+		vr->setGradientFactor(1);
+		vr->setGradientColors(214, 113, 8, 240, 200, 25);
+		vr->fillSurface(VectorRenderer::kGradientFill);
 
-		vr->setFgColor(255, 247, 222);
 		vr->setBgColor(25, 25, 175);
-		vr->setGradientColors(206, 121, 99, 173, 40, 8);
+		vr->shadowEnable(3);
+		vr->setFgColor(240, 204, 120);
+		vr->setStrokeWidth(1);
 		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, 16, 128, 128);
+		vr->setGradientFactor(3);
+		vr->setGradientColors(255, 231, 140, 255, 243, 206);	
+		vr->drawRoundedSquare(25, 95, 18, 465, 290);
 
+		vr->setGradientFactor(1);
+		vr->setGradientColors(206, 121, 99, 173, 40, 8);
+		vr->drawRoundedSquare(500, 95, 8, 120, 30);
+		vr->drawRoundedSquare(500, 135, 8, 120, 30);
+		vr->drawRoundedSquare(500, 175, 8, 120, 30);
+
 		_system->copyRectToOverlay((OverlayColor*)_screen.getBasePtr(0, 0), _screen.w, 0, 0, _screen.w, _screen.w);
 		_system->updateScreen();
 
@@ -111,13 +117,14 @@
 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, kForegroundFill);
+	if (Base::_fillMode != kNoFill && Base::_shadowOffset) {
+		drawCircleAlg(x + Base::_shadowOffset + 1, y + Base::_shadowOffset + 1, r, 0, kForegroundFill);
 	}
 
 	switch(Base::_fillMode) {
 	case kNoFill:
-		drawCircleAlg(x, y, r, _fgColor, kNoFill);
+		if (Base::_strokeWidth)
+			drawCircleAlg(x, y, r, _fgColor, kNoFill);
 		break;
 
 	case kForegroundFill:
@@ -125,8 +132,13 @@
 		break;
 
 	case kBackgroundFill:
-		drawCircleAlg(x, y, r, _fgColor, kForegroundFill);
-		drawCircleAlg(x, y, r - Base::_strokeWidth, _bgColor, kBackgroundFill);
+		if (Base::_strokeWidth > 1) {
+			drawCircleAlg(x, y, r, _fgColor, kForegroundFill);
+			drawCircleAlg(x, y, r - Base::_strokeWidth, _bgColor, kBackgroundFill);
+		} else {
+			drawCircleAlg(x, y, r, _bgColor, kBackgroundFill);
+			drawCircleAlg(x, y, r, _fgColor, kNoFill);
+		}
 		break;
 
 	case kGradientFill:
@@ -137,13 +149,14 @@
 template<typename PixelType, typename PixelFormat>
 void VectorRendererSpec<PixelType, PixelFormat>::
 drawSquare(int x, int y, int w, int h) {
-	if (Base::_fillMode != kNoFill && Base::_shadows) {
-		drawSquareShadow(x, y, w, h);
+	if (Base::_fillMode != kNoFill && Base::_shadowOffset) {
+		drawSquareShadow(x, y, w, h, Base::_shadowOffset);
 	}
 
 	switch(Base::_fillMode) {
 	case kNoFill:
-		drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
+		if (Base::_strokeWidth)
+			drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
 		break;
 
 	case kForegroundFill:
@@ -157,7 +170,8 @@
 
 	case kGradientFill:
 		VectorRendererSpec::drawSquareAlg(x, y, w, h, 0, kGradientFill);
-		drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
+		if (Base::_strokeWidth)
+			drawSquareAlg(x, y, w, h, _fgColor, kNoFill);
 		break;
 	}
 }
@@ -165,13 +179,14 @@
 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) {
-		drawRoundedSquareShadow(x, y, r, w, h);
+	if (Base::_fillMode != kNoFill && Base::_shadowOffset) {
+		drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset);
 	}
 
 	switch(Base::_fillMode) {
 	case kNoFill:
-		drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
+		if (Base::_strokeWidth)
+			drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
 		break;
 
 	case kForegroundFill:
@@ -190,7 +205,8 @@
 				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);
+			if (Base::_strokeWidth)
+				drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kNoFill);
 		}
 		break;
 	}
@@ -230,8 +246,7 @@
 
 template<typename PixelType, typename PixelFormat>
 void VectorRendererSpec<PixelType, PixelFormat>::
-drawSquareShadow(int x, int y, int w, int h) {
-	int blur = 8;
+drawSquareShadow(int x, int y, int w, int h, int blur) {
 	PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + blur);
 	int pitch = Base::surfacePitch();
 	int i, j;
@@ -314,7 +329,7 @@
 
 
 template<typename PixelType, typename PixelFormat>
-void VectorRendererAA<PixelType, PixelFormat>::
+void VectorRendererSpec<PixelType, PixelFormat>::
 blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
 	if (alpha == 255) {
 		*ptr = color;
@@ -404,6 +419,9 @@
 	if (dy == 0 && dx == 0) 
 		return;
 
+	if (Base::_strokeWidth == 0)
+		return;
+
 	PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1);
 	int pitch = Base::surfacePitch();
 
@@ -507,8 +525,57 @@
 
 template<typename PixelType, typename PixelFormat>
 void VectorRendererSpec<PixelType, PixelFormat>::
-drawRoundedSquareShadow(int x1, int y1, int r, int w, int h) {
+drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
+	int f, ddF_x, ddF_y;
+	int x, y, px, py;
+	int pitch = Base::surfacePitch();
+	int sw = 0, sp = 0, hp = h * pitch;
+	int alpha = 102;
 
+	x1 += blur;
+	y1 += blur;
+
+	PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+	PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+	PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+	PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - blur, y1 + r);
+
+	int short_h = h - (2 * r) + 1;
+
+	__BE_RESET();
+
+	// HACK: As we are drawing circles exploting 8-axis symmetry,
+	// there are 4 pixels on each circle which are drawn twice.
+	// this is ok on filled circles, but when blending on surfaces,
+	// we cannot let it blend twice. awful.
+	bool *hb = new bool[r];
+
+	int i = 0;
+	while (i < r)
+		hb[i++] = false;
+
+	while (x++ < y) {
+		__BE_ALGORITHM();
+
+		if (!hb[x]) {
+			blendFill(ptr_tr - px - r, ptr_tr + y - px, 0, alpha);
+			blendFill(ptr_bl - y + px, ptr_br + y + px, 0, alpha);
+			hb[x] = true;
+		}
+
+		if (!hb[y]) {
+			blendFill(ptr_tr - r - py, ptr_tr + x - py, 0, alpha);
+			blendFill(ptr_bl - x + py, ptr_br + x + py, 0, alpha);
+			hb[y] = true;
+		}
+	}
+
+	delete[] hb;
+
+	while (short_h--) {
+		blendFill(ptr_fill - r, ptr_fill + blur, 0, alpha);
+		ptr_fill += pitch;
+	}
 }
 
 template<typename PixelType, typename PixelFormat>
@@ -577,6 +644,7 @@
 				Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
 				Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
 
+				// FIXME: maybe not needed at all?
 				__BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
 			}
 		}

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-05-17 23:59:56 UTC (rev 32163)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-05-18 00:18:15 UTC (rev 32164)
@@ -53,7 +53,7 @@
 class VectorRenderer {
 
 public:
-	VectorRenderer() : _shadows(false), _fillMode(kNoFill), _activeSurface(NULL), _strokeWidth(1) {}
+	VectorRenderer() : _shadowOffset(0), _fillMode(kNoFill), _activeSurface(NULL), _strokeWidth(1), _gradientFactor(1) {}
 	virtual ~VectorRenderer() {}
 
 	enum FillMode {
@@ -63,10 +63,10 @@
 		kGradientFill = 3
 	};
 
-	enum ColorMode {
+/*	enum ColorMode {
 		kForegroundColor,
 		kBackgroundColor
-	};
+	}; */
 
 	/**
 	 * Draws a line by considering the special cases for optimization.
@@ -175,7 +175,7 @@
 	 *
 	 * @param mode Color mode (bg or fg color) used to fill.
 	 */
-	virtual void fillSurface(ColorMode mode = kForegroundColor) = 0;
+	virtual void fillSurface(FillMode mode = kForegroundFill) = 0;
 
 	/**
 	 * Clears the active surface.
@@ -202,7 +202,7 @@
 	 * @param width Witdh of the stroke in pixels.
 	 */
 	virtual void setStrokeWidth(int width) {
-		if (width > 0) _strokeWidth = width;
+		_strokeWidth = width;
 	}
 
 	/**
@@ -214,10 +214,9 @@
 	 * @param y_offset Vertical offset for the shadows.
 	 * @see shadowDisable()
 	 */
-	virtual void shadowEnable(int x_offset, int y_offset) {
-		_shadows = true;
-		_shadowXOffset = x_offset;
-		_shadowYOffset = y_offset;
+	virtual void shadowEnable(int offset) {
+		if (offset > 0)
+			_shadowOffset = offset;
 	}
 
 	/**
@@ -226,19 +225,24 @@
 	 * @see shadowEnable()
 	 */
 	virtual void shadowDisable() {
-		_shadows = false;
+		_shadowOffset = 0;
 	}
 
+	virtual void setGradientFactor(int factor) {
+		if (factor > 0)
+			_gradientFactor = factor;
+	}
+
 protected:
 	Surface *_activeSurface; /** Pointer to the surface currently being drawn */
 
 	FillMode _fillMode; /** Defines in which way (if any) are filled the drawn shapes */
 	
-	bool _shadows; /** Defines if shadows are automatically added to drawn shapes */
-	int _shadowXOffset; /** Horizontal offset for drawn shadows */
-	int _shadowYOffset; /** Vertical offset for drawn shadows */
-
+	int _shadowOffset; /** offset for drawn shadows */
 	int _strokeWidth; /** Width of the stroke of all drawn shapes */
+
+	int _gradientFactor;
+	int _gradientBytes[3];
 };
 
 
@@ -304,22 +308,32 @@
 		_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);
+		Base::_gradientBytes[0] = (_gradientEnd & PixelFormat::kRedMask) - (_gradientStart & PixelFormat::kRedMask);
+		Base::_gradientBytes[1] = (_gradientEnd & PixelFormat::kGreenMask) - (_gradientStart & PixelFormat::kGreenMask);
+		Base::_gradientBytes[2] = (_gradientEnd & PixelFormat::kBlueMask) - (_gradientStart & PixelFormat::kBlueMask);
 	}
 
 	/**
 	 * @see VectorRenderer::fillSurface()
 	 */
-	void fillSurface(ColorMode mode = kForegroundColor) {
+	void fillSurface(FillMode mode = kForegroundFill) {
 		PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, 0);
-		int s = _activeSurface->w * _activeSurface->h;
 
-		if (mode == kBackgroundColor)
-			Common::set_to(ptr, ptr + s, _bgColor);
-		else if (mode == kForegroundColor)
-			Common::set_to(ptr, ptr + s, _fgColor);
+		int w = _activeSurface->w;
+		int h = _activeSurface->h ;
+		int pitch = surfacePitch();
+
+		if (mode == kBackgroundFill)
+			Common::set_to(ptr, ptr + w*h, _bgColor);
+		else if (mode == kForegroundFill)
+			Common::set_to(ptr, ptr + w*h, _fgColor);
+		else if (mode == kGradientFill) {
+			int i = h;
+			while (i--) {
+				Common::set_to(ptr, ptr + w, calcGradient(h - i, h));
+				ptr += pitch;
+			}
+		}
 	}
 
 protected:
@@ -341,21 +355,19 @@
 	 * Blends a single pixel on the surface with the given coordinates, color
 	 * and Alpha intensity.
 	 *
-	 * Note: Pixel blending is currently disabled on the Specialized Renderer
-	 * because of performance issues.
-	 *
 	 * @param x Horizontal coordinate of the pixel.
 	 * @param y Vertical coordinate of the pixel.
 	 * @param color Color of the pixel
 	 * @param alpha Alpha intensity of the pixel (0-255)
 	 */
 	virtual inline void blendPixel(int x, int y, PixelType color, uint8 alpha) {
-		putPixel(x, y, color);
+		if (alpha == 255)
+			putPixel(x, y, color);
+		else if (alpha > 0)
+			blendPixelPtr((PixelType*)Base::_activeSurface->getBasePtr(x, y), color, alpha);
 	}
 
-	virtual inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
-		*ptr = (PixelType)color;
-	}
+	virtual inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
 
 	/*
 	 * "Bresenham's Line Algorithm", as described in Wikipedia.
@@ -368,27 +380,31 @@
 	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);
+	virtual void drawSquareShadow(int x, int y, int w, int h, int blur);
+	virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur);
 
-	inline PixelType calcGradient(int pos, int max, int factor = 1) {
+	inline PixelType calcGradient(uint32 pos, uint32 max) {
 		PixelType output = 0;
-		pos = (0x1000 * MIN(pos * factor, max)) / max;
+		pos = (MIN(pos * Base::_gradientFactor, max) << 12) / 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 |= (_gradientStart + ((Base::_gradientBytes[0] * pos) >> 12)) & PixelFormat::kRedMask;
+		output |= (_gradientStart + ((Base::_gradientBytes[1] * pos) >> 12)) & PixelFormat::kGreenMask;
+		output |= (_gradientStart + ((Base::_gradientBytes[2] * pos) >> 12)) & PixelFormat::kBlueMask;
 		output |= ~(PixelFormat::kRedMask | PixelFormat::kGreenMask | PixelFormat::kBlueMask);
 	
 		return output;
 	}
 
+	inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) {
+		while (first != last)
+			blendPixelPtr(first++, color, alpha);
+	}	
+
 	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];
 };
 
 /**
@@ -419,32 +435,6 @@
 	void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color);
 
 	/**
-	 * Perform alpha blending on top of a given pixel, not on a given
-	 * coordinate (just so we don't have to recalculate the surface
-	 * pointer while we are blending consecutive pixels).
-	 *
-	 * Everything from blendPixel() applies here.
-	 *
-	 * @see VectorRenderer::blendPixel()
-	 * @param ptr Pointer to the pixel where we must draw
-	 * @param alpha Intensity of the pixel (0-255).
-	 */
-	inline virtual void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
-
-	/**
-	 * @see VectorRenderer::blendPixel()
-	 *
-	 * The AA renderer does support alpha blending. Special cases are
-	 * handled separately.
-	 */
-	inline void blendPixel(int x, int y, PixelType color, uint8 alpha) {
-		if (alpha == 255)
-			putPixel(x, y, color);
-		else if (alpha > 0)
-			blendPixelPtr((PixelType*)Base::_activeSurface->getBasePtr(x, y), color, alpha);
-	}
-
-	/**
 	 * "Wu's Circle Antialiasing Algorithm" as published by Xiaolin Wu, July 1991
 	 * Based on the theoretical concept of the algorithm.
 	 *


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list