[Scummvm-cvs-logs] SF.net SVN: scummvm:[53319] scummvm/trunk/engines/sword25/gfx

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Oct 13 01:36:25 CEST 2010


Revision: 53319
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53319&view=rev
Author:   sev
Date:     2010-10-12 23:36:25 +0000 (Tue, 12 Oct 2010)

Log Message:
-----------
SWORD25: Started rewriting vector renderer into proper one

Previous attempt was all wrong, as it completely incorrectly
interpreted SWF shape data.

Modified Paths:
--------------
    scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp
    scummvm/trunk/engines/sword25/gfx/image/vectorimage.h
    scummvm/trunk/engines/sword25/gfx/image/vectorimagerenderer.cpp
    scummvm/trunk/engines/sword25/gfx/opengl/glimage.cpp

Modified: scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp
===================================================================
--- scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp	2010-10-12 23:35:57 UTC (rev 53318)
+++ scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp	2010-10-12 23:36:25 UTC (rev 53319)
@@ -194,7 +194,8 @@
 	double x0, y0, x1, y1;
 
 	for (int j = vectorImageElement.getPathCount() - 1; j >= 0; j--) {
-		ArtVpath *vec = vectorImageElement.getPathInfo(j).getVec();
+		ArtBpath *bez = vectorImageElement.getPathInfo(j).getVec();
+		ArtVpath *vec = art_bez_path_to_vec(bez, 0.5);
 
 		if (vec[0].code == ART_END) {
 			continue;
@@ -208,6 +209,7 @@
 				if (vec[i].y > y1) y1 = vec[i].y;
 			}
 		}
+		art_free(vec);
 	}
 
 	return Common::Rect(static_cast<int>(x0), static_cast<int>(y0), static_cast<int>(x1) + 1, static_cast<int>(y1) + 1);
@@ -324,10 +326,13 @@
 	bez = ensureBezStorage(bez, *bezNodes, bezAllocated);
 	bez[*bezNodes].code = ART_END;
 
-	ArtVpath *vec = art_bez_path_to_vec(bez, BEZSMOOTHNESS);
+	ArtBpath *bez1 = art_new(ArtBpath, *bezNodes + 1);
 
-	_elements.back()._pathInfos.push_back(VectorPathInfo(vec, lineStyle, fillStyle0, fillStyle1));
+	for (int i = 0; i <= *bezNodes; i++)
+		bez1[i] = bez[i];
 
+	_elements.back()._pathInfos.push_back(VectorPathInfo(bez1, *bezNodes, lineStyle, fillStyle0, fillStyle1));
+
 	return bez;
 }
 

Modified: scummvm/trunk/engines/sword25/gfx/image/vectorimage.h
===================================================================
--- scummvm/trunk/engines/sword25/gfx/image/vectorimage.h	2010-10-12 23:35:57 UTC (rev 53318)
+++ scummvm/trunk/engines/sword25/gfx/image/vectorimage.h	2010-10-12 23:36:25 UTC (rev 53319)
@@ -60,17 +60,20 @@
 
 class VectorPathInfo {
 public:
-	VectorPathInfo(ArtVpath *vec, uint lineStyle, uint fillStyle0, uint fillStyle1) :
-		_vec(vec), _lineStyle(lineStyle), _fillStyle0(fillStyle0), _fillStyle1(fillStyle1) {}
+ VectorPathInfo(ArtBpath *vec, int len, uint lineStyle, uint fillStyle0, uint fillStyle1) :
+	_vec(vec), _lineStyle(lineStyle), _fillStyle0(fillStyle0), _fillStyle1(fillStyle1), _len(len) {}
 
 	VectorPathInfo() {
-		_lineStyle = _fillStyle0 = _fillStyle1 = 0;
+		_lineStyle = _fillStyle0 = _fillStyle1 = _len = 0;
 		_vec = 0;
 	}
 
-	ArtVpath *getVec() const {
+	ArtBpath *getVec() const {
 		return _vec;
 	}
+	int getVecLen() const {
+		return _len;
+	}
 	uint getLineStyle() const {
 		return _lineStyle;
 	}
@@ -82,13 +85,13 @@
 	}
 
 private:
-	ArtVpath *_vec;
+	ArtBpath *_vec;
 	uint _lineStyle;
 	uint _fillStyle0;
 	uint _fillStyle1;
+	uint _len;
 };
 
-
 /**
     @brief Ein Element eines Vektorbild. Ein BS_VectorImage besteht aus diesen Elementen, die jeweils einen Teil der Graphik definieren.
            Werden alle Elemente eines Vektorbildes \xFCbereinandergelegt, ergibt sich das komplette Bild.

Modified: scummvm/trunk/engines/sword25/gfx/image/vectorimagerenderer.cpp
===================================================================
--- scummvm/trunk/engines/sword25/gfx/image/vectorimagerenderer.cpp	2010-10-12 23:35:57 UTC (rev 53318)
+++ scummvm/trunk/engines/sword25/gfx/image/vectorimagerenderer.cpp	2010-10-12 23:36:25 UTC (rev 53319)
@@ -33,6 +33,7 @@
  */
 
 #include <libart_lgpl/art_vpath_bpath.h>
+#include <libart_lgpl/art_vpath_bpath.h>
 #include <libart_lgpl/art_svp_vpath.h>
 #include <libart_lgpl/art_svp_vpath_stroke.h>
 #include <libart_lgpl/art_svp_render_aa.h>
@@ -64,13 +65,13 @@
 
 	for (i = 0; i < n; i++) {
 		v = *buf;
-		*buf++ = v + (((alpha - v) * alpha + 0x80) >> 8);
+		*buf++ = v + (((b - v) * alpha + 0x80) >> 8);
 		v = *buf;
+		*buf++ = v + (((g - v) * alpha + 0x80) >> 8);
+		v = *buf;
 		*buf++ = v + (((r - v) * alpha + 0x80) >> 8);
 		v = *buf;
-		*buf++ = v + (((g - v) * alpha + 0x80) >> 8);
-		v = *buf;
-		*buf++ = v + (((b - v) * alpha + 0x80) >> 8);
+		*buf++ = v + (((alpha - v) * alpha + 0x80) >> 8);
 	}
 }
 
@@ -244,9 +245,63 @@
 		art_svp_render_aa(svp, x0, y0, x1, y1, art_rgb_svp_alpha_callback1, &data);
 }
 
+void drawBez(ArtBpath *bez, art_u8 *buffer, int width, int height, double scaleX, double scaleY, double penWidth, unsigned int color) {
+	ArtVpath *vec = NULL;
+	ArtSVP *svp = NULL;
+
+#if 0
+	const char *codes[] = {"ART_MOVETO", "ART_MOVETO_OPEN", "ART_CURVETO", "ART_LINETO", "ART_END"};
+	for (int i = 0;; i++) {
+		printf("    bez[%d].code = %s;\n", i, codes[bez[i].code]);
+		if (bez[i].code == ART_END)
+			break;
+		if (bez[i].code == ART_CURVETO) {
+			printf("    bez[%d].x1 = %f; bez[%d].y1 = %f;\n", i, bez[i].x1, i, bez[i].y1);
+			printf("    bez[%d].x2 = %f; bez[%d].y2 = %f;\n", i, bez[i].x2, i, bez[i].y2);
+		}
+		printf("    bez[%d].x3 = %f; bez[%d].y3 = %f;\n", i, bez[i].x3, i, bez[i].y3);
+	}
+
+	printf("    drawBez(bez, buffer, 1.0, 1.0, %f, 0x%08x);\n", penWidth, color);
+#endif
+
+	vec = art_bez_path_to_vec(bez, 0.5);
+
+	if (scaleX != 1.0 || scaleY != 1.0) {
+		ArtVpath *vec1;
+		int size;
+
+		for (size = 0; vec[size].code != ART_END; size++);
+
+		vec1 = art_new(ArtVpath, size + 1);
+
+		int k;
+		for (k = 0; k < size; k++) {
+			vec1[k].code = vec[k].code;
+			vec1[k].x = vec[k].x * scaleX;
+			vec1[k].y = vec[k].y * scaleY;
+		}
+		vec1[k].code = ART_END;
+		art_free(vec);
+
+		vec = vec1;
+	}
+
+	if (penWidth != -1) {
+		svp = art_svp_vpath_stroke(vec, ART_PATH_STROKE_JOIN_ROUND, ART_PATH_STROKE_CAP_ROUND, penWidth, 1.0, 0.5);
+	} else {
+		svp = art_svp_from_vpath(vec);
+	}
+
+	art_rgb_svp_alpha1(svp, 0, 0, width, height, color, buffer, width * 4, NULL);
+
+	art_free(svp);
+	art_free(vec);
+}
+
 void VectorImage::render(int width, int height) {
-	float scaleFactorX = (width == - 1) ? 1 : static_cast<float>(width) / static_cast<float>(getWidth());
-	float scaleFactorY = (height == - 1) ? 1 : static_cast<float>(height) / static_cast<float>(getHeight());
+	double scaleX = (width == - 1) ? 1 : static_cast<double>(width) / static_cast<double>(getWidth());
+	double scaleY = (height == - 1) ? 1 : static_cast<double>(height) / static_cast<double>(getHeight());
 
 	if (_pixelData)
 		free(_pixelData);
@@ -254,60 +309,95 @@
 	_pixelData = (byte *)malloc(width * height * 4);
 	memset(_pixelData, 0, width * height * 4);
 
-	for (int j = _elements.size() - 1; j >= 0; j--)
-		for (int i = _elements[j].getPathCount() - 1; i >= 0; i--) {
-			if (!_elements[j].getPathInfo(i).getVec())
-				continue;
+	for (uint e = 0; e < _elements.size(); e++) {
 
-			bool needfree = false;
-			ArtVpath *vec = _elements[j].getPathInfo(i).getVec();
+		//// Draw shapes
+		for (uint s = 0; s < _elements[e].getFillStyleCount(); s++) {
+			int fill0len = 0;
+			int fill1len = 0;
 
-			// Upscale vector
-			if (scaleFactorX != 1.0 || scaleFactorY != 1.0) {
-				ArtVpath *vec1;
-				int size;
+			// Count vector sizes in order to minimize memory
+			// fragmentation
+			for (uint p = 0; p < _elements[e].getPathCount(); p++) {
+				if (_elements[e].getPathInfo(p).getFillStyle0() == s + 1)
+					fill1len += _elements[e].getPathInfo(p).getVecLen();
 
-				for (size = 0; vec[size].code != ART_END; size++);
+				if (_elements[e].getPathInfo(p).getFillStyle1() == s + 1)
+					fill0len += _elements[e].getPathInfo(p).getVecLen();
+			}
 
-				vec1 = art_new(ArtVpath, size + 1);
+			// Now lump together vectors
+			ArtBpath *fill1 = art_new(ArtBpath, fill1len + 1);
+			ArtBpath *fill0 = art_new(ArtBpath, fill0len + 1);
+			ArtBpath *fill1pos = fill1;
+			ArtBpath *fill0pos = fill0;
 
-				int k;
-				for (k = 0; k < size; k++) {
-					vec1[k].code = vec[k].code;
-					vec1[k].x = vec[k].x * scaleFactorX;
-					vec1[k].y = vec[k].y * scaleFactorY;
+			for (uint p = 0; p < _elements[e].getPathCount(); p++) {
+				// Normal order
+				if (_elements[e].getPathInfo(p).getFillStyle0() == s + 1) {
+					for (int i = 0; i < _elements[e].getPathInfo(p).getVecLen(); i++)
+						*fill1pos++ = _elements[e].getPathInfo(p).getVec()[i];
 				}
 
-				vec1[k].code = ART_END;
-
-				vec = vec1;
-				needfree = true;
+				// Reverse order
+				if (_elements[e].getPathInfo(p).getFillStyle1() == s + 1) {
+					for (int i = _elements[e].getPathInfo(p).getVecLen() - 1; i >= 0; i--)
+						*fill0pos++ = _elements[e].getPathInfo(p).getVec()[i];
+				}
 			}
 
-			ArtSVP *svp1 = art_svp_from_vpath(vec);
+			// Close vectors
+			(*fill1pos).code = ART_END;
+			(*fill0pos).code = ART_END;
 
+			if (fill1len)
+				drawBez(fill1, _pixelData, width, height, scaleX, scaleY, -1, _elements[e].getFillStyleColor(s));
 
-			if (_elements[j].getPathInfo(i).getFillStyle0()) {
-				int color1 = _elements[j].getFillStyleColor(_elements[j].getPathInfo(i).getFillStyle0() - 1);
-				art_rgb_svp_alpha1(svp1, 0, 0, width, height, color1, _pixelData, width * 4, NULL);
-				art_free(svp1);
+			if (fill0len)
+				drawBez(fill0, _pixelData, width, height, scaleX, scaleY, -1, _elements[e].getFillStyleColor(s));
+
+			art_free(fill0);
+			art_free(fill1);
+		}
+
+		//// Draw strokes
+		for (uint s = 0; s < _elements[e].getLineStyleCount(); s++) {
+			int strokelen = 0;
+
+			// Count vector sizes in order to minimize memory
+			// fragmentation
+			for (uint p = 0; p < _elements[e].getPathCount(); p++) {
+				if (_elements[e].getPathInfo(p).getLineStyle() == s + 1)
+					strokelen += _elements[e].getPathInfo(p).getVecLen();
 			}
 
-			if (_elements[j].getPathInfo(i).getLineStyle()) {
-				double penWidth = _elements[j].getLineStyleWidth(_elements[j].getPathInfo(i).getLineStyle() - 1);
-				penWidth = sqrt(fabs(scaleFactorX * scaleFactorY));
-				ArtSVP *svp2 = art_svp_vpath_stroke(vec, ART_PATH_STROKE_JOIN_ROUND, ART_PATH_STROKE_CAP_ROUND, penWidth, 1.0, 0.5);
-				int color2 = _elements[j].getLineStyleColor(_elements[j].getPathInfo(i).getLineStyle() - 1);
+			if (strokelen == 0)
+				continue;
 
-				art_rgb_svp_alpha1(svp2, 0, 0, width, height, color2, _pixelData, width * 4, NULL);
+			// Now lump together vectors
+			ArtBpath *stroke = art_new(ArtBpath, strokelen + 1);
+			ArtBpath *strokepos = stroke;
 
-				art_free(svp2);
+			for (uint p = 0; p < _elements[e].getPathCount(); p++) {
+				// Normal order
+				if (_elements[e].getPathInfo(p).getLineStyle() == s + 1) {
+					for (int i = 0; i < _elements[e].getPathInfo(p).getVecLen(); i++)
+						*strokepos++ = _elements[e].getPathInfo(p).getVec()[i];
+				}
 			}
 
-			if (needfree)
-				art_free(vec);
+			// Close vector
+			(*strokepos).code = ART_END;
 
+			double penWidth = _elements[e].getLineStyleWidth(s);
+			penWidth *= sqrt(fabs(scaleX * scaleY));
+
+			drawBez(stroke, _pixelData, width, height, scaleX, scaleY, penWidth, _elements[e].getLineStyleColor(s));
+
+			art_free(stroke);
 		}
+	}
+
 }
 
 

Modified: scummvm/trunk/engines/sword25/gfx/opengl/glimage.cpp
===================================================================
--- scummvm/trunk/engines/sword25/gfx/opengl/glimage.cpp	2010-10-12 23:35:57 UTC (rev 53318)
+++ scummvm/trunk/engines/sword25/gfx/opengl/glimage.cpp	2010-10-12 23:36:25 UTC (rev 53319)
@@ -176,7 +176,7 @@
 		h = pPartRect->bottom - pPartRect->top;
 	}
 
-	debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %d, %d, %d)", posX, posY, flipping, x1, y1, w, h, color, width, height);
+	debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, x1, y1, w, h, color, width, height);
 
 	// Skalierungen berechnen
 	float scaleX, scaleY;


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