aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorEugene Sandulenko2010-09-04 22:29:36 +0000
committerEugene Sandulenko2010-10-12 23:36:25 +0000
commite844de5141a03692e74c892a35e55f1c9697719a (patch)
tree9b5684c192752dbb8f0c53e743b437fc3daa2b69 /engines
parent5f8739209b2cb637348954fd428594658daf2df4 (diff)
downloadscummvm-rg350-e844de5141a03692e74c892a35e55f1c9697719a.tar.gz
scummvm-rg350-e844de5141a03692e74c892a35e55f1c9697719a.tar.bz2
scummvm-rg350-e844de5141a03692e74c892a35e55f1c9697719a.zip
SWORD25: Started rewriting vector renderer into proper one
Previous attempt was all wrong, as it completely incorrectly interpreted SWF shape data. svn-id: r53319
Diffstat (limited to 'engines')
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp11
-rw-r--r--engines/sword25/gfx/image/vectorimage.h15
-rw-r--r--engines/sword25/gfx/image/vectorimagerenderer.cpp172
-rw-r--r--engines/sword25/gfx/opengl/glimage.cpp2
4 files changed, 149 insertions, 51 deletions
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index 4cb77692fe..6c79c3043a 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -194,7 +194,8 @@ Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement)
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 @@ Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement)
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,9 +326,12 @@ ArtBpath *VectorImage::storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, in
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;
}
diff --git a/engines/sword25/gfx/image/vectorimage.h b/engines/sword25/gfx/image/vectorimage.h
index ea9948fec7..ac53f031c5 100644
--- a/engines/sword25/gfx/image/vectorimage.h
+++ b/engines/sword25/gfx/image/vectorimage.h
@@ -60,17 +60,20 @@ class VectorImage;
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 @@ public:
}
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 übereinandergelegt, ergibt sich das komplette Bild.
diff --git a/engines/sword25/gfx/image/vectorimagerenderer.cpp b/engines/sword25/gfx/image/vectorimagerenderer.cpp
index e047935c15..2549f8c5d1 100644
--- a/engines/sword25/gfx/image/vectorimagerenderer.cpp
+++ b/engines/sword25/gfx/image/vectorimagerenderer.cpp
@@ -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 @@ void art_rgb_run_alpha1(art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int alpha, in
for (i = 0; i < n; i++) {
v = *buf;
- *buf++ = v + (((alpha - v) * alpha + 0x80) >> 8);
- v = *buf;
- *buf++ = v + (((r - v) * alpha + 0x80) >> 8);
+ *buf++ = v + (((b - v) * alpha + 0x80) >> 8);
v = *buf;
*buf++ = v + (((g - v) * alpha + 0x80) >> 8);
v = *buf;
- *buf++ = v + (((b - v) * alpha + 0x80) >> 8);
+ *buf++ = v + (((r - v) * alpha + 0x80) >> 8);
+ v = *buf;
+ *buf++ = v + (((alpha - v) * alpha + 0x80) >> 8);
}
}
@@ -244,9 +245,63 @@ void art_rgb_svp_alpha1(const ArtSVP *svp,
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 @@ void VectorImage::render(int width, int height) {
_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;
+
+ 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];
+ }
- 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;
+ // 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];
}
+ }
- vec1[k].code = ART_END;
+ // Close vectors
+ (*fill1pos).code = ART_END;
+ (*fill0pos).code = ART_END;
- vec = vec1;
- needfree = true;
- }
+ if (fill1len)
+ drawBez(fill1, _pixelData, width, height, scaleX, scaleY, -1, _elements[e].getFillStyleColor(s));
- ArtSVP *svp1 = art_svp_from_vpath(vec);
+ if (fill0len)
+ drawBez(fill0, _pixelData, width, height, scaleX, scaleY, -1, _elements[e].getFillStyleColor(s));
+ art_free(fill0);
+ art_free(fill1);
+ }
- 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);
+ //// 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);
}
+ }
+
}
diff --git a/engines/sword25/gfx/opengl/glimage.cpp b/engines/sword25/gfx/opengl/glimage.cpp
index cf8b294ea7..839bc44506 100644
--- a/engines/sword25/gfx/opengl/glimage.cpp
+++ b/engines/sword25/gfx/opengl/glimage.cpp
@@ -176,7 +176,7 @@ bool GLImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRect, ui
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;