Permalink
Browse files

GLVideoDriver: new implementation of DrawPolyLine

  • Loading branch information...
1 parent bdfd94b commit b91e4f93da363ec918ed36acfc6b10151ef76bb9 @BehoIder BehoIder committed with lynxlynxlynx Feb 5, 2014
@@ -11,14 +11,13 @@
#pragma comment(lib, "libGLESv2")
#endif
#endif
-
+#include <algorithm>
#include "SDL20GLVideo.h"
#include "Interface.h"
#include "Game.h" // for GetGlobalTint
#include "GLTextureSprite2D.h"
#include "GLPaletteManager.h"
#include "GLSLProgram.h"
-#include "Triangulation.h"
#include "Matrix.h"
using namespace GemRB;
@@ -632,34 +631,64 @@ void GLVideoDriver::DrawLine(short x1, short y1, short x2, short y2, const Color
void GLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fill)
{
if (poly->count == 0) return;
+ if (poly->BBox.x > Viewport.x + Viewport.w) return;
+ if (poly->BBox.y > Viewport.y + Viewport.h) return;
+ if (poly->BBox.x + poly->BBox.w < Viewport.x) return;
+ if (poly->BBox.y + poly->BBox.h < Viewport.y) return;
+
Point* ajustedPoints = new Point[poly->count];
- bool clipped = true;
- for(unsigned int i=0; i<poly->count; i++)
+ for (unsigned int i=0; i<poly->count; i++)
{
- if (Viewport.PointInside(poly->points[i])) clipped = false;
ajustedPoints[i] = Point(poly->points[i].x + xCorr - Viewport.x, poly->points[i].y + yCorr - Viewport.y);
}
- if (clipped)
- {
- delete[] ajustedPoints;
- return;
- }
- if (!fill)
- {
- drawPolygon(ajustedPoints, poly->count, color, LineLoop);
- }
- else
+ drawPolygon(ajustedPoints, poly->count, color, LineLoop);
+ delete[] ajustedPoints;
+ if (fill)
{
// not a good to do this here, will be right to do it in game
Color c = color;
c.a = c.a/2;
// end of bad code
- std::vector<Point> triangles = Triangulation::TriangulatePolygon(ajustedPoints, poly->count);
- //drawPolygon(&triangles[0], (short)triangles.size(), c, FilledTriangulation);
- for(int i=0; i<triangles.size(); i+=3)
- drawPolygon(&triangles[i], 3, color, LineLoop);
+ std::vector<Point> triangulation;
+ std::list<Trapezoid>::iterator iter;
+ for (iter = poly->trapezoids.begin(); iter != poly->trapezoids.end(); ++iter)
+ {
+ int y_top = iter->y1;
+ int y_bot = iter->y2;
+
+ int ledge = iter->left_edge;
+ int redge = iter->right_edge;
+ Point& a = poly->points[ledge];
+ Point& b = poly->points[(ledge+1)%(poly->count)];
+ Point& c = poly->points[redge];
+ Point& d = poly->points[(redge+1)%(poly->count)];
+
+ Point topleft, topright, bottomleft, bottomright;
+ topleft.y = topright.y = y_top + yCorr - Viewport.y;
+ bottomleft.y = bottomright.y = y_bot + yCorr - Viewport.y;
+
+ int lt, rt, py;
+ py = y_top;
+ lt = (b.x * (py - a.y) + a.x * (b.y - py))/(b.y - a.y);
+ rt = (d.x * (py - c.y) + c.x * (d.y - py))/(d.y - c.y);
+ topleft.x = lt + xCorr - Viewport.x;
+ topright.x = rt + xCorr - Viewport.x;
+
+ py = y_bot;
+ lt = (b.x * (py - a.y) + a.x * (b.y - py))/(b.y - a.y);
+ rt = (d.x * (py - c.y) + c.x * (d.y - py))/(d.y - c.y);
+ bottomleft.x = lt + xCorr - Viewport.x;
+ bottomright.x = rt + xCorr - Viewport.x;
+
+ triangulation.push_back(bottomleft);
+ triangulation.push_back(topleft);
+ triangulation.push_back(topright);
+ triangulation.push_back(bottomleft);
+ triangulation.push_back(topright);
+ triangulation.push_back(bottomright);
+ }
+ drawPolygon(&triangulation[0], triangulation.size(), c, FilledTriangulation);
}
- delete[] ajustedPoints;
}
void GLVideoDriver::DrawEllipse(short cx, short cy, unsigned short xr, unsigned short yr, const Color& color, bool clipped)
@@ -48,7 +48,6 @@ namespace GemRB
void clearRect(const Region& rgn, const Color& color);
void drawEllipse(int cx, int cy, unsigned short xr, unsigned short yr, float thickness, const Color& color);
void drawPolygon(Point* points, unsigned int count, const Color& color, PointDrawingMode mode);
- GLfloat* triangulatePolygon(Point* points, unsigned int count, unsigned int &trCount);
public:
~GLVideoDriver();
@@ -1,79 +0,0 @@
-#include <vector>
-#include "Triangulation.h"
-#include "Region.h" // for Point
-
-using namespace GemRB;
-
-short vectorMultiplication(const Point &p1, const Point &p2, const Point &p3)
-{
- return p1.x*p2.y - p1.x*p3.y - p2.x*p1.y + p2.x*p3.y + p3.x*p1.y - p3.x*p2.y;
-}
-
-short Triangulation::getDirection(std::vector<Point> polygon)
-{
- short min = polygon[0].x;
- Point p0, p1, p2;
- for (int i=0; i<polygon.size()-2; i++)
- {
- if (polygon[i].x <= min)
- {
- p0 = polygon[i];
- p1 = polygon[i+1];
- p2 = polygon[i+2];
- }
- }
- if (vectorMultiplication(p0, p1, p2) > 0) return 1;
- return -1;
-}
-
-bool Triangulation::pointInTriangle(const Point &pt, const Point &t0, const Point &t1, const Point &t2)
-{
- short a = vectorMultiplication(pt, t0, t1);
- short b = vectorMultiplication(pt, t1, t2);
- short c = vectorMultiplication(pt, t2, t0);
- return (a < 0 && b < 0 && c < 0) || (a > 0 && b > 0 && c > 0);
-}
-
-std::vector<Point> Triangulation::TriangulatePolygon(Point* points, unsigned int count)
-{
- std::vector<Point> triangles;
- std::vector<Point> polygon = std::vector<Point>(points, points + count);
- short direction = getDirection(polygon);
- int i = 0;
- int prevIterationCount = polygon.size();
- while (polygon.size() != 3)
- {
- if (vectorMultiplication(polygon[i+1], polygon[i], polygon[i+2]) * direction < 0)
- {
- bool rightEar = true;
- for (int j=0; j<polygon.size(); j++)
- {
- if (pointInTriangle(polygon[j], polygon[i], polygon[i+1], polygon[i+2]))
- {
- i++;
- rightEar = false;
- break;
- }
- }
- if (rightEar)
- {
- triangles.push_back(polygon[i]);
- triangles.push_back(polygon[i+1]);
- triangles.push_back(polygon[i+2]);
- polygon.erase(polygon.begin()+i+1);
- }
- }
- else i++;
- if (i == polygon.size() - 3)
- {
- if (prevIterationCount == polygon.size())
- break; // damn
- i = 0;
- prevIterationCount = polygon.size();
- }
- }
- triangles.push_back(polygon[0]);
- triangles.push_back(polygon[1]);
- triangles.push_back(polygon[2]);
- return triangles;
-}
@@ -1,17 +0,0 @@
-#ifndef TRIANGULATION_H
-#define TRIANGULATION_H
-
-namespace GemRB
-{
- class Point;
-
- class Triangulation
- {
- public:
- static std::vector<Point> TriangulatePolygon(Point* points, unsigned int count);
- private:
- static bool pointInTriangle(const Point &pt, const Point &t0, const Point &t1, const Point &t2);
- static short getDirection(std::vector<Point> polygon);
- };
-}
-#endif

0 comments on commit b91e4f9

Please sign in to comment.