Permalink
Browse files

GLVideoDriver: some shader fixes (thanks wjp), Triangulation class

  • Loading branch information...
1 parent 222f998 commit bdfd94bf691b2a37f8fff575dc73d7fc78e51957 @BehoIder BehoIder committed with lynxlynxlynx Jan 31, 2014
@@ -40,13 +40,13 @@ GLuint GLPaletteManager::CreatePaletteTexture(Palette* palette, unsigned int col
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Color* colors = new Color[256];
memcpy(colors, palette->col, sizeof(Color)*256);
- for(unsigned int i=0; i<256; i++)
+ for (unsigned int i=0; i<256; i++)
{
- if(colors[i].a == 0)
+ if (colors[i].a == 0)
{
colors[i].a = 0xFF;
}
- if(i == colorKey) colors[i].a = 0;
+ if (i == colorKey) colors[i].a = 0;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
#ifdef USE_GL
@@ -18,6 +18,7 @@
#include "GLTextureSprite2D.h"
#include "GLPaletteManager.h"
#include "GLSLProgram.h"
+#include "Triangulation.h"
#include "Matrix.h"
using namespace GemRB;
@@ -422,12 +423,14 @@ void GLVideoDriver::drawPolygon(Point* points, unsigned int count, const Color&
programRect->SetUniformValue("u_color", COLOR_SIZE, (GLfloat)color.r/255, (GLfloat)color.g/255, (GLfloat)color.b/255, (GLfloat)color.a/255);
glEnableVertexAttribArray(a_position);
- if (mode == PointDrawingMode::LineLoop)
+ if (mode == LineLoop)
glDrawArrays(GL_LINE_LOOP, 0, count);
- else if (mode == PointDrawingMode::LineStrip)
+ else if (mode == LineStrip)
glDrawArrays(GL_LINE_STRIP, 0, count);
- else
+ else if (mode == ConvexFilledPolygon)
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
+ else if (mode == FilledTriangulation)
+ glDrawArrays(GL_TRIANGLES, 0, count);
glDisableVertexAttribArray(a_position);
glDeleteBuffers(1, &buffer);
@@ -598,9 +601,9 @@ void GLVideoDriver::DrawRect(const Region& rgn, const Color& color, bool fill, b
}
}
if (fill)
- return drawPolygon(pt, 4, color, PointDrawingMode::FilledPolygon);
+ return drawPolygon(pt, 4, color, ConvexFilledPolygon);
else
- return drawPolygon(pt, 4, color, PointDrawingMode::LineLoop);
+ return drawPolygon(pt, 4, color, LineLoop);
}
void GLVideoDriver::DrawHLine(short x1, short y, short x2, const Color& color, bool clipped)
@@ -623,24 +626,38 @@ void GLVideoDriver::DrawLine(short x1, short y1, short x2, short y2, const Color
pt[0].y += yCorr - Viewport.y;
pt[1].y += yCorr - Viewport.y;
}
- return drawPolygon(pt, 2, color, PointDrawingMode::LineStrip);
+ return drawPolygon(pt, 2, color, LineStrip);
}
void GLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fill)
{
if (poly->count == 0) return;
Point* ajustedPoints = new Point[poly->count];
+ bool clipped = true;
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, PointDrawingMode::LineLoop);
+ {
+ drawPolygon(ajustedPoints, poly->count, color, LineLoop);
+ }
else
{
// 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
- drawPolygon(ajustedPoints, poly->count, c, PointDrawingMode::FilledPolygon);
+ 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);
}
delete[] ajustedPoints;
}
@@ -713,6 +730,7 @@ Sprite2D* GLVideoDriver::GetScreenshot(Region r)
return screenshot;
}
+
#include "plugindef.h"
GEMRB_PLUGIN(0xDBAAB50, "SDL Video Driver")
@@ -21,7 +21,8 @@ namespace GemRB
{
LineStrip,
LineLoop,
- FilledPolygon
+ ConvexFilledPolygon,
+ FilledTriangulation
};
class GLVideoDriver : public SDL20VideoDriver
@@ -47,6 +48,7 @@ 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();
@@ -9,6 +9,6 @@ void main()
{
float alphaModifier = v_alphaModifier * texture2D(s_mask, v_texCoord).a;
float index = texture2D(s_texture, v_texCoord).a;
- vec4 color = texture2D(s_palette, vec2(index, 0.0));
+ vec4 color = texture2D(s_palette, vec2((0.5 + index*255.0)/256.0, 0.5));
gl_FragColor = vec4(color.r*v_tint.r, color.g*v_tint.g, color.b*v_tint.b, color.a * alphaModifier);
}
@@ -9,7 +9,7 @@ void main()
{
float alphaModifier = v_alphaModifier * texture2D(s_mask, v_texCoord).a;
float index = texture2D(s_texture, v_texCoord).a;
- vec4 color = texture2D(s_palette, vec2(index, 0.0));
+ vec4 color = texture2D(s_palette, vec2((0.5 + index*255.0)/256.0, 0.5));
float gray = (color.r + color.g + color.b)*0.333333;
gl_FragColor = vec4(gray, gray, gray, color.a * alphaModifier);
}
@@ -11,7 +11,7 @@ void main()
{
float alphaModifier = v_alphaModifier * texture2D(s_mask, v_texCoord).a;
float index = texture2D(s_texture, v_texCoord).a;
- vec4 color = texture2D(s_palette, vec2(index, 0.0));
+ vec4 color = texture2D(s_palette, vec2((0.5 + index*255.0)/256.0, 0.5));
float gray = (color.r + color.g + color.b)*0.333333;
vec3 sepia = darkColor*(1.0 - gray) + lightColor*gray;
gl_FragColor = vec4(sepia, color.a * alphaModifier);
@@ -0,0 +1,79 @@
+#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;
+}
@@ -0,0 +1,17 @@
+#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 bdfd94b

Please sign in to comment.