summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorneoraider <devnull@localhost>2007-09-21 23:47:05 +0200
committerneoraider <devnull@localhost>2007-09-21 23:47:05 +0200
commit62e42408485e9e1b7e939925b650a4b2e90ecddb (patch)
tree9305aa0f7b2d79c35250939beca2c268dd61e23d
parent1bce1d8ad7c32ce7b6723a284842b6890cf5209f (diff)
downloadzoomedit-62e42408485e9e1b7e939925b650a4b2e90ecddb.tar
zoomedit-62e42408485e9e1b7e939925b650a4b2e90ecddb.zip
zoomedit: Big transition Ciaro -> OpenGL, enormous speedup!
-rw-r--r--Makefile.am8
-rw-r--r--Makefile.in46
-rw-r--r--Polygon.cpp205
-rw-r--r--Polygon.h22
-rw-r--r--Rectangle.h10
-rw-r--r--Triangle.cpp36
-rw-r--r--Triangle.h39
-rw-r--r--aclocal.m4231
-rwxr-xr-xconfigure334
-rw-r--r--configure.in1
-rw-r--r--draw.cpp234
-rw-r--r--draw.h4
-rw-r--r--edit.cpp19
-rw-r--r--edit.h1
-rw-r--r--geometry.cpp80
-rw-r--r--geometry.h11
-rw-r--r--window.cpp168
-rw-r--r--window.h3
-rw-r--r--zoomedit.cpp12
19 files changed, 1114 insertions, 350 deletions
diff --git a/Makefile.am b/Makefile.am
index 4ae72e8..94ded86 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS = zoomedit
-zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp edit.cpp geometry.cpp \
- Vertex.cpp Line.cpp Polygon.cpp Rectangle.cpp Room.cpp
-zoomedit_CPPFLAGS = @GTK_CFLAGS@
-zoomedit_LDADD = @GTK_LIBS@ \ No newline at end of file
+zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp edit.cpp Vertex.cpp \
+ Line.cpp Polygon.cpp Rectangle.cpp Room.cpp Triangle.cpp
+zoomedit_CPPFLAGS = @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@
+zoomedit_LDADD = @GTK_LIBS@ @GTKGLEXT_LIBS@ \ No newline at end of file
diff --git a/Makefile.in b/Makefile.in
index ef8432a..9762995 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -51,9 +51,9 @@ PROGRAMS = $(bin_PROGRAMS)
am_zoomedit_OBJECTS = zoomedit-zoomedit.$(OBJEXT) \
zoomedit-window.$(OBJEXT) zoomedit-ui.$(OBJEXT) \
zoomedit-draw.$(OBJEXT) zoomedit-edit.$(OBJEXT) \
- zoomedit-geometry.$(OBJEXT) zoomedit-Vertex.$(OBJEXT) \
- zoomedit-Line.$(OBJEXT) zoomedit-Polygon.$(OBJEXT) \
- zoomedit-Rectangle.$(OBJEXT) zoomedit-Room.$(OBJEXT)
+ zoomedit-Vertex.$(OBJEXT) zoomedit-Line.$(OBJEXT) \
+ zoomedit-Polygon.$(OBJEXT) zoomedit-Rectangle.$(OBJEXT) \
+ zoomedit-Room.$(OBJEXT) zoomedit-Triangle.$(OBJEXT)
zoomedit_OBJECTS = $(am_zoomedit_OBJECTS)
zoomedit_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -102,6 +102,8 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
+GTKGLEXT_CFLAGS = @GTKGLEXT_CFLAGS@
+GTKGLEXT_LIBS = @GTKGLEXT_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
INSTALL = @INSTALL@
@@ -171,11 +173,11 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp edit.cpp geometry.cpp \
- Vertex.cpp Line.cpp Polygon.cpp Rectangle.cpp Room.cpp
+zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp edit.cpp Vertex.cpp \
+ Line.cpp Polygon.cpp Rectangle.cpp Room.cpp Triangle.cpp
-zoomedit_CPPFLAGS = @GTK_CFLAGS@
-zoomedit_LDADD = @GTK_LIBS@
+zoomedit_CPPFLAGS = @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@
+zoomedit_LDADD = @GTK_LIBS@ @GTKGLEXT_LIBS@
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -268,10 +270,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Polygon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Rectangle.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Room.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Triangle.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Vertex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-draw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-edit.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-geometry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-ui.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-window.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-zoomedit.Po@am__quote@
@@ -360,20 +362,6 @@ zoomedit-edit.obj: edit.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-edit.obj `if test -f 'edit.cpp'; then $(CYGPATH_W) 'edit.cpp'; else $(CYGPATH_W) '$(srcdir)/edit.cpp'; fi`
-zoomedit-geometry.o: geometry.cpp
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-geometry.o -MD -MP -MF $(DEPDIR)/zoomedit-geometry.Tpo -c -o zoomedit-geometry.o `test -f 'geometry.cpp' || echo '$(srcdir)/'`geometry.cpp
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-geometry.Tpo $(DEPDIR)/zoomedit-geometry.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='geometry.cpp' object='zoomedit-geometry.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-geometry.o `test -f 'geometry.cpp' || echo '$(srcdir)/'`geometry.cpp
-
-zoomedit-geometry.obj: geometry.cpp
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-geometry.obj -MD -MP -MF $(DEPDIR)/zoomedit-geometry.Tpo -c -o zoomedit-geometry.obj `if test -f 'geometry.cpp'; then $(CYGPATH_W) 'geometry.cpp'; else $(CYGPATH_W) '$(srcdir)/geometry.cpp'; fi`
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-geometry.Tpo $(DEPDIR)/zoomedit-geometry.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='geometry.cpp' object='zoomedit-geometry.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-geometry.obj `if test -f 'geometry.cpp'; then $(CYGPATH_W) 'geometry.cpp'; else $(CYGPATH_W) '$(srcdir)/geometry.cpp'; fi`
-
zoomedit-Vertex.o: Vertex.cpp
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Vertex.o -MD -MP -MF $(DEPDIR)/zoomedit-Vertex.Tpo -c -o zoomedit-Vertex.o `test -f 'Vertex.cpp' || echo '$(srcdir)/'`Vertex.cpp
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Vertex.Tpo $(DEPDIR)/zoomedit-Vertex.Po
@@ -444,6 +432,20 @@ zoomedit-Room.obj: Room.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-Room.obj `if test -f 'Room.cpp'; then $(CYGPATH_W) 'Room.cpp'; else $(CYGPATH_W) '$(srcdir)/Room.cpp'; fi`
+zoomedit-Triangle.o: Triangle.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Triangle.o -MD -MP -MF $(DEPDIR)/zoomedit-Triangle.Tpo -c -o zoomedit-Triangle.o `test -f 'Triangle.cpp' || echo '$(srcdir)/'`Triangle.cpp
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Triangle.Tpo $(DEPDIR)/zoomedit-Triangle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Triangle.cpp' object='zoomedit-Triangle.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-Triangle.o `test -f 'Triangle.cpp' || echo '$(srcdir)/'`Triangle.cpp
+
+zoomedit-Triangle.obj: Triangle.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Triangle.obj -MD -MP -MF $(DEPDIR)/zoomedit-Triangle.Tpo -c -o zoomedit-Triangle.obj `if test -f 'Triangle.cpp'; then $(CYGPATH_W) 'Triangle.cpp'; else $(CYGPATH_W) '$(srcdir)/Triangle.cpp'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Triangle.Tpo $(DEPDIR)/zoomedit-Triangle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Triangle.cpp' object='zoomedit-Triangle.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-Triangle.obj `if test -f 'Triangle.cpp'; then $(CYGPATH_W) 'Triangle.cpp'; else $(CYGPATH_W) '$(srcdir)/Triangle.cpp'; fi`
+
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
diff --git a/Polygon.cpp b/Polygon.cpp
index 9340135..3425727 100644
--- a/Polygon.cpp
+++ b/Polygon.cpp
@@ -1,8 +1,9 @@
#include "Polygon.h"
+#include <list>
#include <math.h>
-double Polygon::area() const {
+double Polygon::signedArea() const {
double d = 0.0;
for(const_iterator it = begin(); it != end(); it++) {
@@ -12,7 +13,17 @@ double Polygon::area() const {
d += (it2->getX()+it->getX())*(it2->getY()-it->getY());
}
- return fabs(d/2);
+ return d/2;
+}
+
+Polygon::Direction Polygon::getDirection() const {
+ double area = signedArea();
+
+ return (area > 0) ? Triangle::CW : (area < 0) ? Triangle::CCW : Triangle::Unknown;
+}
+
+double Polygon::area() const {
+ return fabs(signedArea());
}
double Polygon::perimeter() const {
@@ -103,8 +114,8 @@ bool Polygon::contains(const Vertex &v) const {
bool Polygon::intersects(const Line &l) const {
Line line;
- for(Polygon::const_iterator it = begin(); it != end(); it++) {
- Polygon::const_iterator it2 = it+1;
+ for(const_iterator it = begin(); it != end(); it++) {
+ const_iterator it2 = it+1;
if(it2 == end()) it2 = begin();
line.setVertex1(*it);
@@ -116,3 +127,189 @@ bool Polygon::intersects(const Line &l) const {
return false;
}
+
+bool Polygon::isConcave(const Direction &dir, const Vertex &v1, const Vertex &v2, const Vertex &v3) const {
+ switch(dir) {
+ case Triangle::CW:
+ return (v1.getX()-v2.getX())*(v3.getY()-v2.getY()) > (v3.getX()-v2.getX())*(v1.getY()-v2.getY());
+ case Triangle::CCW:
+ return (v1.getX()-v2.getX())*(v3.getY()-v2.getY()) < (v3.getX()-v2.getX())*(v1.getY()-v2.getY());
+ }
+
+ return false;
+}
+
+bool Polygon::intersections(std::vector<Intersection> *intersections) const {
+ bool ret = false;
+ size_t s = size();
+
+ for(size_t i = 0; i+2 < s; i++) {
+ Line l(at(i), at(i+1));
+
+ for(size_t j = i+2; j < s; j++) {
+ if(i == (j+1)%s) continue;
+
+ Line l2(at(j), at((j+1)%s));
+
+ Vertex v;
+ if(l.intersects(l2, &v) == INTERSECTION_SEGMENT_SEGMENT) {
+ if(intersections) {
+ Intersection in = {i, i+1, j, ((j+1)%s), v};
+
+ intersections->push_back(in);
+ ret = true;
+ }
+ else {
+ return true;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+bool Polygon::isSimple() const {
+ return !intersections();
+}
+
+bool Polygon::simplify(Polygon &polygon) const {
+ std::vector<Intersection> ins;
+
+ if(!intersections(&ins)) return false;
+
+ int s = size();
+ int start = 0;
+
+ for(int i = 1; i < s; i++) {
+ if(at(i).getX() < at(start).getX())
+ start = i;
+ else if(at(i).getX() == at(start).getX() && at(i).getY() < at(start).getY())
+ start = i;
+ }
+
+ int dir = Triangle(at((s+start-1)%s), at(start), at((start+1)%s)).getDirection();
+
+ int i2 = start;
+ const Vertex *v2 = &at(i2);
+ bool intersected;
+
+ do {
+ intersected = false;
+
+ int i = i2;
+
+ if(dir == Triangle::CW)
+ i2 = (i2+1)%s;
+ else
+ i2 = (s+i2-1)%s;
+
+ const Vertex *v1 = v2;
+ v2 = &at(i2);
+
+ Vertex *v = NULL;
+ int v3, v4;
+
+ for(std::vector<Intersection>::iterator in = ins.begin(); in != ins.end(); ++in) {
+ if(v2->distanceSq(in->v) >= v2->distanceSq(*v1) || v1 == &in->v)
+ continue;
+
+ if(v) {
+ if(v1->distanceSq(in->v) >= v1->distanceSq(*v))
+ continue;
+ }
+
+ if((i == in->va1 && i2 == in->va2) || (i == in->va2 && i2 == in->va1)) {
+ v = &in->v;
+ v3 = in->vb1;
+ v4 = in->vb2;
+ }
+ else if((i == in->vb1 && i2 == in->vb2) || (i == in->vb2 && i2 == in->vb1)) {
+ v = &in->v;
+ v3 = in->va1;
+ v4 = in->va2;
+ }
+ }
+
+ if(v) {
+ v2 = v;
+ intersected = true;
+
+ if(isConcave(Triangle::CW, *v1, *v2, at(v4))) {
+ i2 = v3;
+ dir = Triangle::CW;
+ }
+ else {
+ i2 = v4;
+ dir = Triangle::CCW;
+ }
+ }
+
+ polygon.push_back(*v2);
+ } while(i2 != start || intersected);
+
+ return true;
+}
+
+// FIXME: has still some problems...
+void Polygon::doTriangulate(std::vector<Triangle> &triangles) const {
+ size_t s = size();
+
+ if(s < 3) return;
+
+ std::vector<size_t> p;
+ std::list<size_t> concave;
+ Direction dir = getDirection();
+
+ for(size_t i = 0; i < s; i++) {
+ p.push_back((i+1)%s);
+
+ if(isConcave(dir, at(i), at((i+1)%s), at((i+2)%s)))
+ concave.push_back((i+1)%s);
+ }
+
+ for(size_t i = 0; i < p.size() && p.size() > 3; i++) {
+ size_t s2 = p.size();
+
+ const Vertex *v0 = &at(p[i]);
+ const Vertex *v1 = &at(p[(i+1)%s2]);
+ const Vertex *v2 = &at(p[(i+2)%s2]);
+ const Vertex *v3 = &at(p[(i+3)%s2]);
+ const Vertex *v4 = &at(p[(i+4)%s2]);
+
+ if(isConcave(dir, *v1, *v2, *v3))
+ continue;
+
+ Triangle t(*v1, *v2, *v3);
+
+ std::list<size_t>::iterator it = concave.begin();
+ for(; it != concave.end(); it++) {
+ if(*it != p[(i+1)%s2] && *it != p[(i+3)%s2] && t.contains(at(*it)))
+ break;
+ }
+
+ if(it != concave.end())
+ continue;
+
+ triangles.push_back(t);
+
+ if(isConcave(dir, *v2, *v3, *v4) && !isConcave(dir, *v1, *v3, *v4))
+ concave.remove(p[(i+3)%s2]);
+
+ if(isConcave(dir, *v0, *v1, *v2) && !isConcave(dir, *v0, *v1, *v3)) {
+ concave.remove(p[(i+1)%s2]);
+ }
+
+ p.erase(p.begin()+(i+2)%s2);
+ i = 0;
+ }
+
+ triangles.push_back(Triangle(at(p[0]), at(p[1]), at(p[2])));
+}
+
+void Polygon::triangulate(std::vector<Triangle> &triangles) const {
+ Polygon p;
+
+ if(simplify(p)) p.doTriangulate(triangles);
+ else doTriangulate(triangles);
+}
diff --git a/Polygon.h b/Polygon.h
index 093a160..6e36bee 100644
--- a/Polygon.h
+++ b/Polygon.h
@@ -3,17 +3,39 @@
#include "Vertex.h"
#include "Line.h"
+#include "Triangle.h"
#include <vector>
class Polygon : public std::vector<Vertex> {
private:
+ struct Intersection {
+ size_t va1, va2, vb1, vb2;
+ Vertex v;
+ };
+
+ typedef Triangle::Direction Direction;
+
int quadrant(const Vertex &v) const;
+
+ double signedArea() const;
+
+ Triangle::Direction getDirection() const;
+ bool isConcave(const Triangle::Direction &dir, const Vertex &v1, const Vertex &v2, const Vertex &v3) const;
+
+ bool intersections(std::vector<Intersection> *intersections = NULL) const;
+
+ void doTriangulate(std::vector<Triangle> &triangles) const;
public:
double area() const;
double perimeter() const;
bool contains(const Vertex &v) const;
bool intersects(const Line &l) const;
+
+ bool isSimple() const;
+ bool simplify(Polygon &polygon) const;
+
+ void triangulate(std::vector<Triangle> &triangles) const;
};
#endif /*POLYGON_H_*/
diff --git a/Rectangle.h b/Rectangle.h
index 8a61321..5e7bb94 100644
--- a/Rectangle.h
+++ b/Rectangle.h
@@ -18,13 +18,9 @@ class Rectangle {
Vertex v1, v2;
public:
Rectangle() {}
- Rectangle(const Vertex& v1, const Vertex& v2) {
- this->v1 = v1; this->v2 = v2;
- }
- Rectangle(double x, double y, double width, double height) {
- v1.setLocation(x, y);
- v2.setLocation(x+width, y+height);
- }
+ Rectangle(const Vertex& vertex1, const Vertex& vertex2) : v1(vertex1), v2(vertex2) {}
+ Rectangle(double x, double y, double width, double height)
+ : v1(x, y), v2(x+width, y+height) {}
Vertex &getVertex1() {return v1;}
const Vertex &getVertex1() const {return v1;}
diff --git a/Triangle.cpp b/Triangle.cpp
new file mode 100644
index 0000000..e367629
--- /dev/null
+++ b/Triangle.cpp
@@ -0,0 +1,36 @@
+#include "Triangle.h"
+#include <math.h>
+
+
+Triangle::Direction Triangle::getDirection() const {
+ double c = (va.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(va.getY()-vb.getY());
+
+ return (c < 0) ? CW : (c > 0) ? CCW : Unknown;
+}
+
+double Triangle::area() const {
+ double a = vb.distanceSq(vc);
+ double b = vc.distanceSq(va);
+ double c = va.distanceSq(vb);
+
+ return sqrt((a+b+c)*a+b+c - 2*(a*a+b*b+c*c))/4;
+}
+
+double Triangle::perimeter() const {
+ return va.distance(vb) + vb.distance(vc) + vc.distance(va);
+}
+
+bool Triangle::contains(const Vertex &v) const {
+ double a = (v.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(v.getY()-vb.getY());
+ double b = (v.getX()-vc.getX())*(va.getY()-vc.getY()) - (va.getX()-vc.getX())*(v.getY()-vc.getY());
+ double c = (v.getX()-va.getX())*(vb.getY()-va.getY()) - (vb.getX()-va.getX())*(v.getY()-va.getY());
+
+ switch(getDirection()) {
+ case CW:
+ return ((a < 0) && (b < 0) && (c < 0));
+ case CCW:
+ return ((a > 0) && (b > 0) && (c > 0));
+ }
+
+ return false;
+}
diff --git a/Triangle.h b/Triangle.h
new file mode 100644
index 0000000..b0a7a2e
--- /dev/null
+++ b/Triangle.h
@@ -0,0 +1,39 @@
+#ifndef TRIANGLE_H_
+#define TRIANGLE_H_
+
+
+#include "Vertex.h"
+
+class Triangle {
+ private:
+ Vertex va, vb, vc;
+ public:
+ enum Direction {
+ CW, CCW, Unknown
+ };
+
+ Triangle() {}
+ Triangle(const Vertex& vertexa, const Vertex& vertexb, const Vertex& vertexc)
+ : va(vertexa), vb(vertexb), vc(vertexc) {}
+
+ Vertex &getVertexA() {return va;}
+ const Vertex &getVertexA() const {return va;}
+ void setVertexA(const Vertex &v) {va = v;}
+
+ Vertex &getVertexB() {return vb;}
+ const Vertex &getVertexB() const {return vb;}
+ void setVertexB(const Vertex &v) {vb = v;}
+
+ Vertex &getVertexC() {return vc;}
+ const Vertex &getVertexC() const {return vc;}
+ void setVertexC(const Vertex &v) {vc = v;}
+
+ Direction getDirection() const;
+
+ double area() const;
+ double perimeter() const;
+
+ bool contains(const Vertex &v) const;
+};
+
+#endif /*TRIANGLE_H_*/
diff --git a/aclocal.m4 b/aclocal.m4
index 4353dd4..680d62e 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -213,6 +213,237 @@ main ()
rm -f conf.gtktest
])
+# Configure paths for GtkGLExt
+# Naofumi Yasufuku
+#
+# Shamelessly stolen from gtk-2.0.m4
+# Configure paths for GTK+
+# Owen Taylor 1997-2001
+
+dnl AM_PATH_GTKGLEXT_1_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for GtkGLExt, and define GTKGLEXT_CFLAGS and GTKGLEXT_LIBS.
+dnl
+AC_DEFUN([AM_PATH_GTKGLEXT_1_0],
+[ no_gtkglext=""
+ GTKGLEXT_CFLAGS=""
+ GTKGLEXT_LIBS=""
+
+ # GtkGLExt pkg-config module
+ gtkglext_module=gtkglext-1.0
+
+ # minimum GtkGLExt version
+ gtkglext_min_version=ifelse([$1], ,1.0.0,$1)
+
+ # minimum pkg-config version
+ pkgconfig_min_version=0.7
+
+AC_ARG_ENABLE(gtkglext-test,
+[ --disable-gtkglext-test do not try to compile and run a test GtkGLExt program],
+, enable_gtkglext_test=yes)
+
+dnl
+dnl Get the cflags and libraries from pkg-config
+dnl
+ pkg_config_modules=$gtkglext_module
+
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+ if test x$PKG_CONFIG != xno ; then
+ if pkg-config --atleast-pkgconfig-version $pkgconfig_min_version ; then
+ :
+ else
+ echo ""
+ echo "*** pkg-config too old; version $pkgconfig_min_version or better required."
+ no_gtkglext=yes
+ PKG_CONFIG=no
+ fi
+ else
+ no_gtkglext=yes
+ fi
+
+ AC_MSG_CHECKING(for GtkGLExt - version >= $gtkglext_min_version)
+
+ if test x$PKG_CONFIG != xno ; then
+ ## don't try to run the test against uninstalled libtool libs
+ if $PKG_CONFIG --uninstalled $pkg_config_modules; then
+ echo ""
+ echo "Will use uninstalled version of GtkGLExt found in PKG_CONFIG_PATH"
+ enable_gtkglext_test=no
+ fi
+
+ if $PKG_CONFIG --atleast-version $gtkglext_min_version $pkg_config_modules; then
+ :
+ else
+ echo ""
+ echo "*** pkg-config cannot find $gtkglext_module >= $gtkglext_min_version"
+ echo "*** Set the environment variable PKG_CONFIG_PATH to point to the correct"
+ echo "*** configuration files."
+ no_gtkglext=yes
+ enable_gtkglext_test=no
+ fi
+ fi
+
+ if test x"$no_gtkglext" = x ; then
+ GTKGLEXT_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_modules`
+ GTKGLEXT_LIBS=`$PKG_CONFIG --libs $pkg_config_modules`
+ gtkglext_config_major_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ gtkglext_config_minor_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ gtkglext_config_micro_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ if test "x$enable_gtkglext_test" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $GTKGLEXT_CFLAGS"
+ LIBS="$GTKGLEXT_LIBS $LIBS"
+dnl
+dnl Now check if the installed GtkGLExt is sufficiently new. (Also sanity
+dnl checks the results of pkg-config to some extent)
+dnl
+ rm -f conf.gtkgltest
+ AC_TRY_RUN([
+#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ int major, minor, micro;
+ char *tmp_version;
+
+ system ("touch conf.gtkgltest");
+
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = g_strdup ("$gtkglext_min_version");
+ if (sscanf (tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3)
+ {
+ printf ("%s, bad version string\n", "$gtkglext_min_version");
+ exit (1);
+ }
+
+ if ((gtkglext_major_version != $gtkglext_config_major_version) ||
+ (gtkglext_minor_version != $gtkglext_config_minor_version) ||
+ (gtkglext_micro_version != $gtkglext_config_micro_version))
+ {
+ printf ("\n*** 'pkg-config --modversion $gtkglext_module' returned %d.%d.%d, but GtkGLExt\n",
+ $gtkglext_config_major_version, $gtkglext_config_minor_version, $gtkglext_config_micro_version);
+ printf ("*** library %d.%d.%d was found!\n",
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ printf ("***\n");
+ printf ("*** If pkg-config was correct, then it is best to remove the old version\n");
+ printf ("*** of GtkGLExt. You may also be able to fix the error by modifying your\n");
+ printf ("*** LD_LIBRARY_PATH enviroment variable, or by editing /etc/ld.so.conf.\n");
+ printf ("*** Make sure you have run ldconfig if that is required on your system.\n");
+ printf ("***\n");
+ printf ("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n");
+ printf ("*** to point to the correct configuration files.\n");
+ }
+ else if ((gtkglext_major_version != GTKGLEXT_MAJOR_VERSION) ||
+ (gtkglext_minor_version != GTKGLEXT_MINOR_VERSION) ||
+ (gtkglext_micro_version != GTKGLEXT_MICRO_VERSION))
+ {
+ printf ("\n*** GtkGLExt header files (version %d.%d.%d) do not match library (version %d.%d.%d).\n",
+ GTKGLEXT_MAJOR_VERSION, GTKGLEXT_MINOR_VERSION, GTKGLEXT_MICRO_VERSION,
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ }
+ else
+ {
+ if ((gtkglext_major_version > major) ||
+ ((gtkglext_major_version == major) && (gtkglext_minor_version > minor)) ||
+ ((gtkglext_major_version == major) && (gtkglext_minor_version == minor) && (gtkglext_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf ("\n*** An old version of GtkGLExt library (%d.%d.%d) was found.\n",
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ printf ("*** You need a version of GtkGLExt newer than %d.%d.%d. The latest version of\n",
+ major, minor, micro);
+ printf ("*** GtkGLExt is always available from http://gtkglext.sourceforge.net/.\n");
+ printf ("***\n");
+ printf ("*** If you have already installed a sufficiently new version, this error\n");
+ printf ("*** probably means that the wrong copy of the pkg-config shell script is\n");
+ printf ("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf ("*** of GtkGLExt, but you can also set the PKG_CONFIG environment to point\n");
+ printf ("*** to the correct copy of pkg-config. (In this case, you will have to\n");
+ printf ("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ printf ("*** so that the correct libraries are found at run-time)\n");
+ }
+ }
+ return 1;
+}
+],, no_gtkglext=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ if test "x$no_gtkglext" = x ; then
+ AC_MSG_RESULT(yes (version $gtkglext_config_major_version.$gtkglext_config_minor_version.$gtkglext_config_micro_version))
+ ifelse([$2], , :, [$2])
+ else
+ AC_MSG_RESULT(no)
+ if test "$PKG_CONFIG" = "no" ; then
+ echo "*** A new enough version of pkg-config was not found."
+ echo "*** See http://www.freedesktop.org/software/pkgconfig/."
+ elif test "x$enable_gtkglext_test" = "xyes" ; then
+ if test -f conf.gtkgltest ; then
+ :
+ else
+ echo "*** Could not run GtkGLExt test program, checking why..."
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $GTKGLEXT_CFLAGS"
+ LIBS="$LIBS $GTKGLEXT_LIBS"
+ AC_TRY_LINK([
+#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <stdio.h>
+], [ return ((gtkglext_major_version) || (gtkglext_minor_version) || (gtkglext_micro_version)); ],
+ [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding GtkGLExt or finding the wrong"
+ echo "*** version of GtkGLExt. If it is not finding GtkGLExt, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+ [ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means GtkGLExt is incorrectly installed."])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ GTKGLEXT_CFLAGS=""
+ GTKGLEXT_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(GTKGLEXT_CFLAGS)
+ AC_SUBST(GTKGLEXT_LIBS)
+ rm -f conf.gtkgltest
+])
+
+dnl AC_GTKGLEXT_SUPPORTS_MULTIHEAD([ACTION-IF-SUPPORTED [, ACTION-IF-NOT-SUPPORTED]])
+dnl Checks whether GtkGLExt supports multihead.
+dnl
+AC_DEFUN([AC_GTKGLEXT_SUPPORTS_MULTIHEAD],
+[ AC_CACHE_CHECK([whether GtkGLExt supports multihead],
+ [ac_cv_gtkglext_supports_multihead],
+ [AC_TRY_LINK([#include <gdk/gdkglquery.h>],
+ [gdk_gl_query_extension_for_display(gdk_display_get_default());],
+ [ac_cv_gtkglext_supports_multihead=yes],
+ [ac_cv_gtkglext_supports_multihead=no])])
+ if test "x$ac_cv_gtkglext_supports_multihead" = "xyes" ; then
+ ifelse([$1], , :, [$1])
+ else
+ ifelse([$2], , :, [$2])
+ fi
+])
+
# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
diff --git a/configure b/configure
index 53ed2f0..535b686 100755
--- a/configure
+++ b/configure
@@ -702,6 +702,8 @@ am__fastdepCC_FALSE
PKG_CONFIG
GTK_CFLAGS
GTK_LIBS
+GTKGLEXT_CFLAGS
+GTKGLEXT_LIBS
CPP
GREP
EGREP
@@ -1300,6 +1302,7 @@ Optional Features:
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
--disable-gtktest do not try to compile and run a test GTK+ program
+ --disable-gtkglext-test do not try to compile and run a test GtkGLExt program
Some influential environment variables:
CXX C++ compiler command
@@ -4260,6 +4263,333 @@ echo "$as_me: error: zoomedit needs GTK+ 2.8.0" >&2;}
rm -f conf.gtktest
+ no_gtkglext=""
+ GTKGLEXT_CFLAGS=""
+ GTKGLEXT_LIBS=""
+
+ # GtkGLExt pkg-config module
+ gtkglext_module=gtkglext-1.0
+
+ # minimum GtkGLExt version
+ gtkglext_min_version=1.0.0
+
+ # minimum pkg-config version
+ pkgconfig_min_version=0.7
+
+# Check whether --enable-gtkglext-test was given.
+if test "${enable_gtkglext_test+set}" = set; then
+ enableval=$enable_gtkglext_test;
+else
+ enable_gtkglext_test=yes
+fi
+
+
+ pkg_config_modules=$gtkglext_module
+
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
+echo "${ECHO_T}$PKG_CONFIG" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+ if test x$PKG_CONFIG != xno ; then
+ if pkg-config --atleast-pkgconfig-version $pkgconfig_min_version ; then
+ :
+ else
+ echo ""
+ echo "*** pkg-config too old; version $pkgconfig_min_version or better required."
+ no_gtkglext=yes
+ PKG_CONFIG=no
+ fi
+ else
+ no_gtkglext=yes
+ fi
+
+ { echo "$as_me:$LINENO: checking for GtkGLExt - version >= $gtkglext_min_version" >&5
+echo $ECHO_N "checking for GtkGLExt - version >= $gtkglext_min_version... $ECHO_C" >&6; }
+
+ if test x$PKG_CONFIG != xno ; then
+ ## don't try to run the test against uninstalled libtool libs
+ if $PKG_CONFIG --uninstalled $pkg_config_modules; then
+ echo ""
+ echo "Will use uninstalled version of GtkGLExt found in PKG_CONFIG_PATH"
+ enable_gtkglext_test=no
+ fi
+
+ if $PKG_CONFIG --atleast-version $gtkglext_min_version $pkg_config_modules; then
+ :
+ else
+ echo ""
+ echo "*** pkg-config cannot find $gtkglext_module >= $gtkglext_min_version"
+ echo "*** Set the environment variable PKG_CONFIG_PATH to point to the correct"
+ echo "*** configuration files."
+ no_gtkglext=yes
+ enable_gtkglext_test=no
+ fi
+ fi
+
+ if test x"$no_gtkglext" = x ; then
+ GTKGLEXT_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_modules`
+ GTKGLEXT_LIBS=`$PKG_CONFIG --libs $pkg_config_modules`
+ gtkglext_config_major_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+ gtkglext_config_minor_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+ gtkglext_config_micro_version=`$PKG_CONFIG --modversion $gtkglext_module | \
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+ if test "x$enable_gtkglext_test" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $GTKGLEXT_CFLAGS"
+ LIBS="$GTKGLEXT_LIBS $LIBS"
+ rm -f conf.gtkgltest
+ if test "$cross_compiling" = yes; then
+ echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ int major, minor, micro;
+ char *tmp_version;
+
+ system ("touch conf.gtkgltest");
+
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = g_strdup ("$gtkglext_min_version");
+ if (sscanf (tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3)
+ {
+ printf ("%s, bad version string\n", "$gtkglext_min_version");
+ exit (1);
+ }
+
+ if ((gtkglext_major_version != $gtkglext_config_major_version) ||
+ (gtkglext_minor_version != $gtkglext_config_minor_version) ||
+ (gtkglext_micro_version != $gtkglext_config_micro_version))
+ {
+ printf ("\n*** 'pkg-config --modversion $gtkglext_module' returned %d.%d.%d, but GtkGLExt\n",
+ $gtkglext_config_major_version, $gtkglext_config_minor_version, $gtkglext_config_micro_version);
+ printf ("*** library %d.%d.%d was found!\n",
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ printf ("***\n");
+ printf ("*** If pkg-config was correct, then it is best to remove the old version\n");
+ printf ("*** of GtkGLExt. You may also be able to fix the error by modifying your\n");
+ printf ("*** LD_LIBRARY_PATH enviroment variable, or by editing /etc/ld.so.conf.\n");
+ printf ("*** Make sure you have run ldconfig if that is required on your system.\n");
+ printf ("***\n");
+ printf ("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n");
+ printf ("*** to point to the correct configuration files.\n");
+ }
+ else if ((gtkglext_major_version != GTKGLEXT_MAJOR_VERSION) ||
+ (gtkglext_minor_version != GTKGLEXT_MINOR_VERSION) ||
+ (gtkglext_micro_version != GTKGLEXT_MICRO_VERSION))
+ {
+ printf ("\n*** GtkGLExt header files (version %d.%d.%d) do not match library (version %d.%d.%d).\n",
+ GTKGLEXT_MAJOR_VERSION, GTKGLEXT_MINOR_VERSION, GTKGLEXT_MICRO_VERSION,
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ }
+ else
+ {
+ if ((gtkglext_major_version > major) ||
+ ((gtkglext_major_version == major) && (gtkglext_minor_version > minor)) ||
+ ((gtkglext_major_version == major) && (gtkglext_minor_version == minor) && (gtkglext_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf ("\n*** An old version of GtkGLExt library (%d.%d.%d) was found.\n",
+ gtkglext_major_version, gtkglext_minor_version, gtkglext_micro_version);
+ printf ("*** You need a version of GtkGLExt newer than %d.%d.%d. The latest version of\n",
+ major, minor, micro);
+ printf ("*** GtkGLExt is always available from http://gtkglext.sourceforge.net/.\n");
+ printf ("***\n");
+ printf ("*** If you have already installed a sufficiently new version, this error\n");
+ printf ("*** probably means that the wrong copy of the pkg-config shell script is\n");
+ printf ("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf ("*** of GtkGLExt, but you can also set the PKG_CONFIG environment to point\n");
+ printf ("*** to the correct copy of pkg-config. (In this case, you will have to\n");
+ printf ("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ printf ("*** so that the correct libraries are found at run-time)\n");
+ }
+ }
+ return 1;
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+no_gtkglext=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ if test "x$no_gtkglext" = x ; then
+ { echo "$as_me:$LINENO: result: yes (version $gtkglext_config_major_version.$gtkglext_config_minor_version.$gtkglext_config_micro_version)" >&5
+echo "${ECHO_T}yes (version $gtkglext_config_major_version.$gtkglext_config_minor_version.$gtkglext_config_micro_version)" >&6; }
+ :
+ else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ if test "$PKG_CONFIG" = "no" ; then
+ echo "*** A new enough version of pkg-config was not found."
+ echo "*** See http://www.freedesktop.org/software/pkgconfig/."
+ elif test "x$enable_gtkglext_test" = "xyes" ; then
+ if test -f conf.gtkgltest ; then
+ :
+ else
+ echo "*** Could not run GtkGLExt test program, checking why..."
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $GTKGLEXT_CFLAGS"
+ LIBS="$LIBS $GTKGLEXT_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ return ((gtkglext_major_version) || (gtkglext_minor_version) || (gtkglext_micro_version));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding GtkGLExt or finding the wrong"
+ echo "*** version of GtkGLExt. If it is not finding GtkGLExt, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means GtkGLExt is incorrectly installed."
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ GTKGLEXT_CFLAGS=""
+ GTKGLEXT_LIBS=""
+ { { echo "$as_me:$LINENO: error: zoomedit needs GtkGLExt" >&5
+echo "$as_me: error: zoomedit needs GtkGLExt" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+
+ rm -f conf.gtkgltest
+
# Checks for header files.
#AC_HEADER_STDC
@@ -6123,6 +6453,8 @@ am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
PKG_CONFIG!$PKG_CONFIG$ac_delim
GTK_CFLAGS!$GTK_CFLAGS$ac_delim
GTK_LIBS!$GTK_LIBS$ac_delim
+GTKGLEXT_CFLAGS!$GTKGLEXT_CFLAGS$ac_delim
+GTKGLEXT_LIBS!$GTKGLEXT_LIBS$ac_delim
CPP!$CPP$ac_delim
GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim
@@ -6130,7 +6462,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 92; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 1fd6e99..9b98a75 100644
--- a/configure.in
+++ b/configure.in
@@ -16,6 +16,7 @@ AM_PROG_CC_C_O
# Checks for libraries.
#AC_CHECK_LIB(m, [sqrt])
AM_PATH_GTK_2_0(2.8.0,,AC_MSG_ERROR(zoomedit needs GTK+ 2.8.0))
+AM_PATH_GTKGLEXT_1_0(1.0.0,,AC_MSG_ERROR(zoomedit needs GtkGLExt))
# Checks for header files.
#AC_HEADER_STDC
diff --git a/draw.cpp b/draw.cpp
index ab21bd3..be67364 100644
--- a/draw.cpp
+++ b/draw.cpp
@@ -1,39 +1,39 @@
#include "draw.h"
#include "edit.h"
-#include "geometry.h"
+#include "Rectangle.h"
#include <math.h>
#include <gtk/gtk.h>
-#include <cairo/cairo.h>
-#include <stdlib.h>
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
static double scale = 100.0;
static double xTranslate = 0.0, yTranslate = 0.0;
-static gboolean repaint = FALSE;
-static void drawGrid(cairo_t *cr, const Rectangle *rect) {
+static void drawGrid(const Rectangle &rect) {
double depth = log10(scale)-0.75;
double depth2 = floor(depth);
double step = pow(0.1, depth2);
double d;
int i;
- gchar *string;
- double x1 = rect->getVertex1().getX(), y1 = rect->getVertex1().getY();
- double x2 = rect->getVertex2().getX(), y2 = rect->getVertex2().getY();
+ //gchar *string;
+ double x1 = rect.getVertex1().getX(), y1 = rect.getVertex1().getY();
+ double x2 = rect.getVertex2().getX(), y2 = rect.getVertex2().getY();
- cairo_set_font_size(cr, 10.0/scale);
+ glBegin(GL_LINES);
+ //cairo_set_font_size(cr, 10.0/scale);
for(i = 0; 0.4*(depth-depth2+i-1) < 0.5; i++) {
d = MIN(0.4*(depth-depth2+i), 0.5);
- cairo_set_source_rgb(cr, d, d, d);
+ glColor3d(d, d, d);
for(d = x1 - fmod(x1, step) - step; d <= x2; d+=step) {
- cairo_move_to(cr, d, y1);
- cairo_line_to(cr, d, y2);
+ glVertex2d(d, y1);
+ glVertex2d(d, y2);
- if(step > 0.005) {
+ /*if(step > 0.005) {
if(step > 0.5)
string = g_strdup_printf("%i", (int)rint(d));
else
@@ -43,14 +43,14 @@ static void drawGrid(cairo_t *cr, const Rectangle *rect) {
cairo_show_text(cr, string);
g_free(string);
- }
+ }*/
}
for(d = y1 - fmod(y1, step) - step; d <= y2; d+=step) {
- cairo_move_to(cr, x1, d);
- cairo_line_to(cr, x2, d);
+ glVertex2d(x1, d);
+ glVertex2d(x2, d);
- if(step > 0.005) {
+ /*if(step > 0.005) {
if(step > 0.5)
string = g_strdup_printf("%i", (int)rint(d));
else
@@ -60,48 +60,48 @@ static void drawGrid(cairo_t *cr, const Rectangle *rect) {
cairo_show_text(cr, string);
g_free(string);
- }
+ }*/
}
- cairo_stroke(cr);
-
step *= 10;
}
+
+ glEnd();
}
-static void polygon2path(cairo_t *cr, const Polygon *polygon, const Rectangle *rect, gboolean close) {
- Polygon polygon2;
+static void fillPolygon(const Polygon &polygon) {
+ std::vector<Triangle> triangles;
- // no vertices
- if(polygon->empty()) return;
+ polygon.triangulate(triangles);
- if(rect)
- simplifyPolygon(polygon, rect, &polygon2);
- else
- polygon2 = *polygon;
+ glBegin(GL_TRIANGLES);
- if(polygon2.empty()) return;
+ for(std::vector<Triangle>::iterator t = triangles.begin(); t != triangles.end(); t++) {
+ glVertex2d(t->getVertexA().getX(), t->getVertexA().getY());
+ glVertex2d(t->getVertexB().getX(), t->getVertexB().getY());
+ glVertex2d(t->getVertexC().getX(), t->getVertexC().getY());
+ }
- cairo_new_sub_path(cr);
+ glEnd();
+}
+
+static void drawPolygon(const Polygon &polygon, bool close) {
+ glBegin(GL_LINE_STRIP);
- for(Polygon::iterator it = polygon2.begin(); it != polygon2.end(); it++) {
- cairo_line_to(cr, it->getX(), it->getY());
- }
+ for(Polygon::const_iterator vertex = polygon.begin(); vertex != polygon.end(); vertex++)
+ glVertex2d(vertex->getX(), vertex->getY());
if(close)
- cairo_close_path(cr);
+ glVertex2d(polygon.front().getX(), polygon.front().getY());
+
+ glEnd();
}
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
- cairo_t *cr;
- Vertex v1(-1, -1), v2(widget->allocation.width+1, widget->allocation.height+1);
+ GdkGLContext *context = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *drawable = gtk_widget_get_gl_drawable(widget);
+ Vertex v1(0, 0), v2(widget->allocation.width, widget->allocation.height);
Rectangle rect;
- gboolean vertexOk;
- static GdkPixmap *pixmap = NULL;
- static double lastImageWidth = 0.0, lastImageHeight = 0.0;
- static gint lastWidth = 0, lastHeight = 0;
- static int lastEditMode = 0;
- int i;
if(getLevel() == NULL) return FALSE;
@@ -112,116 +112,79 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
rect.setVertex1(v1);
rect.setVertex2(v2);
- if(pixmap == NULL || fabs(lastImageWidth - getImageWidth()) >= 0.000001 || fabs(lastImageHeight - getImageHeight()) >= 0.000001 ||
- lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || lastEditMode != getEditMode() || repaint)
- {
- if(pixmap != NULL)
- g_object_unref(G_OBJECT(pixmap));
-
- pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1);
-
- lastImageWidth = getImageWidth();
- lastImageHeight = getImageHeight();
- lastWidth = widget->allocation.width;
- lastHeight = widget->allocation.height;
- lastEditMode = getEditMode();
- repaint = FALSE;
-
-
- cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
-
- cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate);
- cairo_scale(cr, scale, scale);
-
- cairo_set_line_width(cr, 1.0/scale);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
+ if(!gdk_gl_drawable_gl_begin(drawable, context))
+ return FALSE;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ glLineWidth(1.0);
+
+ glTranslated(getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate, 0);
+ glScaled(scale, scale, 1);
+
+ drawGrid(rect);
+
+ for(Level::const_iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
+ if(&*room == getActiveRoom() && getEditMode() == EDIT_MODE_ADD) continue;
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_paint(cr);
+ if(&*room == getActiveRoom())
+ glColor4d(0.0, 0.7, 1.0, 0.2);
+ else
+ glColor4d(0.0, 0.7, 1.0, 0.3);
- drawGrid(cr, &rect);
+ fillPolygon(*room);
- for(Level::iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
- if(&*room != getActiveRoom()) {
- polygon2path(cr, &*room, &rect, TRUE);
- }
+ if(&*room == getActiveRoom()) {
+ glColor4d(1.0, 1.0, 1.0, 0.9);
+ glLineWidth(2.0);
}
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.3);
- cairo_fill_preserve(cr);
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
- cairo_stroke(cr);
-
- if(getEditMode() == EDIT_MODE_SELECTED) {
- polygon2path(cr, getActiveRoom(), &rect, TRUE);
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.2);
- cairo_fill_preserve(cr);
-
- cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.9);
- cairo_set_line_width(cr, 2.0/scale);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
- cairo_stroke(cr);
+ else if(&*room == getHoveredRoom() && getEditMode() != EDIT_MODE_ADD) {
+ glColor4d(0.0, 0.7, 1.0, 0.7);
+ glLineWidth(2.0);
+ }
+ else {
+ glColor4d(0.0, 0.7, 1.0, 0.7);
+ glLineWidth(1.0);
}
- cairo_destroy (cr);
+ drawPolygon(*room, true);
}
- gdk_draw_drawable(GDK_DRAWABLE(widget->window), widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GDK_DRAWABLE(pixmap), 0, 0, 0, 0, -1, -1);
-
- cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
-
- cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate);
- cairo_scale(cr, scale, scale);
-
- cairo_set_line_width(cr, 2.0/scale);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
-
- if(getHoveredRoom() != NULL && getHoveredRoom() != getActiveRoom() &&
- (getEditMode() == EDIT_MODE_VIEW || getEditMode() == EDIT_MODE_SELECTED))
- {
- polygon2path(cr, getHoveredRoom(), &rect, TRUE);
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
- cairo_stroke(cr);
- }
- else if(getEditMode() == EDIT_MODE_ADD) {
- polygon2path(cr, getActiveRoom(), NULL, FALSE);
-
+ if(getEditMode() == EDIT_MODE_ADD) {
if(isPolygonOk(getActiveRoom()))
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.2);
+ glColor4d(0.0, 0.7, 1.0, 0.2);
else
- cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.2);
- cairo_fill_preserve(cr);
+ glColor4d(1.0, 0.3, 0.3, 0.2);
+ fillPolygon(*getActiveRoom());
+
+ glLineWidth(2.0);
+ glColor4d(0.0, 0.7, 1.0, 0.7);
+ drawPolygon(*getActiveRoom(), false);
if(!getActiveRoom()->empty() && getHoveredVertex()) {
- vertexOk = isVertexOk(getHoveredVertex());
+ if(!isVertexOk(getHoveredVertex()))
+ glColor4d(1.0, 0.3, 0.3, 0.7);
- if(vertexOk)
- cairo_line_to(cr, getHoveredVertex()->getX(), getHoveredVertex()->getY());
- }
-
- cairo_set_line_width(cr, 2.0/scale);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
- cairo_stroke(cr);
-
- if(!getActiveRoom()->empty() && getHoveredVertex() && !vertexOk) {
- cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.7);
+ glBegin(GL_LINES);
- cairo_move_to(cr, getActiveRoom()->back().getX(), getActiveRoom()->back().getY());
- cairo_line_to(cr, getHoveredVertex()->getX(), getHoveredVertex()->getY());
+ glVertex2d(getActiveRoom()->back().getX(), getActiveRoom()->back().getY());
+ glVertex2d(getHoveredVertex()->getX(), getHoveredVertex()->getY());
- cairo_stroke(cr);
+ glEnd();
}
}
- cairo_destroy (cr);
+ glPopMatrix();
+
+ gdk_gl_drawable_swap_buffers(drawable);
+
+ gdk_gl_drawable_gl_end(drawable);
- return FALSE;
+ return TRUE;
}
@@ -231,7 +194,6 @@ double getScale() {
void setScale(double s) {
scale = MAX(0.005, MIN(s, 10000));
- repaint = TRUE;
}
void imageToView(Vertex *v) {
@@ -282,7 +244,6 @@ double getXTranslate() {
void setXTranslate(double x) {
xTranslate = x;
- repaint = TRUE;
}
double getYTranslate() {
@@ -291,9 +252,4 @@ double getYTranslate() {
void setYTranslate(double y) {
yTranslate = y;
- repaint = TRUE;
-}
-
-void redraw() {
- repaint = TRUE;
}
diff --git a/draw.h b/draw.h
index 0fcac61..3b6b974 100644
--- a/draw.h
+++ b/draw.h
@@ -2,7 +2,7 @@
#define DRAW_H_
#include <gtk/gtk.h>
-#include "geometry.h"
+#include "Vertex.h"
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data);
@@ -21,6 +21,4 @@ void setXTranslate(double x);
double getYTranslate();
void setYTranslate(double y);
-void redraw();
-
#endif /*DRAW_H_*/
diff --git a/edit.cpp b/edit.cpp
index ab19969..3023dc5 100644
--- a/edit.cpp
+++ b/edit.cpp
@@ -1,6 +1,5 @@
#include "Level.h"
#include "edit.h"
-#include "geometry.h"
static int editMode = EDIT_MODE_VIEW;
@@ -145,6 +144,9 @@ bool isPolygonOk(Polygon *polygon) {
if(polygon->size() == 1)
return true;
+ if(!polygon->isSimple())
+ return false;
+
for(Polygon::const_iterator it = polygon->begin(); it != polygon->end(); it++) {
Polygon::const_iterator it2 = it+1;
if(it2 == polygon->end()) it2 = polygon->begin();
@@ -156,21 +158,6 @@ bool isPolygonOk(Polygon *polygon) {
if(room->intersects(l))
return false;
}
-
- if(it2 != polygon->begin()) {
- for(Polygon::const_iterator it3 = it2+1; it3 != polygon->end(); it3++) {
- Polygon::const_iterator it4 = it3+1;
- if(it4 == polygon->end()) it4 = polygon->begin();
-
- if(it == polygon->begin() && it4 == polygon->begin()) continue;
-
- l2.setVertex1(*it3);
- l2.setVertex2(*it4);
-
- if(l.intersects(l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
- return false;
- }
- }
}
return true;
diff --git a/edit.h b/edit.h
index 460fb89..1216624 100644
--- a/edit.h
+++ b/edit.h
@@ -2,7 +2,6 @@
#define EDIT_H_
#include "Level.h"
-#include "geometry.h"
#define EDIT_MODE_VIEW 0
#define EDIT_MODE_SELECTED 1
diff --git a/geometry.cpp b/geometry.cpp
deleted file mode 100644
index 0967119..0000000
--- a/geometry.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "geometry.h"
-
-
-static void edgeVertex(Vertex *v, int edge, const Rectangle *rect) {
- if(edge == EDGE_NONE)
- edge = rect->edges(*v);
-
- if(edge & EDGE_LEFT) v->setX(rect->getVertex1().getX());
- else if(edge & EDGE_RIGHT) v->setX(rect->getVertex2().getX());
-
- if(edge & EDGE_TOP) v->setY(rect->getVertex1().getY());
- else if(edge & EDGE_BOTTOM) v->setY(rect->getVertex2().getY());
-}
-
-static int simplifyVertex(Vertex *v, const Vertex *to, const Rectangle *rect) {
- Line l(*v, *to);
- int edge, edge2;
-
-
- edge = rect->edges(*v);
- if(edge == EDGE_NONE) return EDGE_NONE;
-
- edge2 = rect->intersects(l, v, edge);
- if(edge2 != EDGE_NONE) return edge2;
-
- edgeVertex(v, edge, rect);
- return edge;
-}
-
-static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const Rectangle *rect, int last, Polygon *out) {
- const Line d1(rect->getVertex1(), rect->getVertex2());
- const Line d2(rect->getVertex1().getX(), rect->getVertex2().getY(), rect->getVertex2().getX(), rect->getVertex1().getY());
-
- Line l(*v1, *v2);
- Vertex v, vi;
- int edge1, edge2;
-
-
- v = *v1;
- if((edge1 = simplifyVertex(&v, v2, rect)) != EDGE_NONE)
- out->push_back(v);
-
- v = *v2;
- edge2 = simplifyVertex(&v, v1, rect);
-
- if(edge1 != EDGE_NONE && edge2 != EDGE_NONE && !(edge1 & edge2)) {
- if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) {
- edgeVertex(&vi, 0, rect);
- out->push_back(vi);
- }
- else if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) {
- edgeVertex(&vi, 0, rect);
- out->push_back(vi);
- }
- }
-
- if(!last)
- out->push_back(v);
-}
-
-void simplifyPolygon(const Polygon *in, const Rectangle *rect, Polygon *out) {
- Vertex v;
-
- if(in->empty()) return;
- else if(in->size() == 1) {
- out->push_back(in->front());
- return;
- }
-
- v = in->front();
- simplifyVertex(&v, &in->back(), rect);
- out->push_back(v);
-
- for(Polygon::const_iterator v2 = in->begin(); v2 != in->end(); v2++) {
- Polygon::const_iterator v3 = v2+1;
- if(v3 == in->end()) v3 = in->begin();
-
- addSimplifiedLine(&*v2, &*v3, rect, (v3 == in->begin()), out);
- }
-}
diff --git a/geometry.h b/geometry.h
deleted file mode 100644
index 633a5b4..0000000
--- a/geometry.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef GEOMETRY_H_
-#define GEOMETRY_H_
-
-
-#include "Polygon.h"
-#include "Rectangle.h"
-
-
-void simplifyPolygon(const Polygon *in, const Rectangle *rect, Polygon *out);
-
-#endif /*GEOMETRY_H_*/
diff --git a/window.cpp b/window.cpp
index d347964..ff570ce 100644
--- a/window.cpp
+++ b/window.cpp
@@ -2,10 +2,9 @@
#include "ui.h"
#include "edit.h"
#include "draw.h"
-#include "geometry.h"
#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <string.h>
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
static GtkWidget *drawingArea = NULL, *sidebarView = NULL, *sidebarAdd = NULL;
@@ -14,10 +13,111 @@ static GtkAdjustment *hAdjustment = NULL, *vAdjustment = NULL;
static GtkWidget *entryName, *labelArea = NULL, *labelPerimeter = NULL, *buttonAdd = NULL, *buttonAddDo = NULL;
+static void refreshScrolling() {
+ if(getImageWidth() < drawingArea->allocation.width)
+ setXTranslate((getImageWidth()-drawingArea->allocation.width)/2);
+ else
+ setXTranslate(gtk_adjustment_get_value(hAdjustment));
+
+ if(getImageHeight() < drawingArea->allocation.height)
+ setYTranslate((getImageHeight()-drawingArea->allocation.height)/2);
+ else
+ setYTranslate(gtk_adjustment_get_value(vAdjustment));
+
+ gtk_widget_queue_draw(drawingArea);
+}
+
+static void updateScrollbars(double x, double y) {
+ const gdouble imageWidth = getImageWidth(), imageHeight = getImageHeight();
+ const gdouble width = drawingArea->allocation.width, height = drawingArea->allocation.height;
+ gdouble upper, pageSize, value;
+
+ gdk_window_freeze_updates(drawingArea->window);
+
+ g_object_get(G_OBJECT(hAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
+ g_object_set(G_OBJECT(hAdjustment), "upper", imageWidth, "page_size", width, NULL);
+ gtk_adjustment_changed(hAdjustment);
+
+ if((pageSize > upper && width < imageWidth) || upper == 0)
+ value = (imageWidth-width)/2;
+ else
+ value = (gtk_adjustment_get_value(hAdjustment)+pageSize*x)/upper*imageWidth-width*x;
+ gtk_adjustment_set_value(hAdjustment, MAX(MIN(value, imageWidth-width), 0));
+
+ g_object_get(G_OBJECT(vAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
+ g_object_set(G_OBJECT(vAdjustment), "upper", imageHeight, "page_size", height, NULL);
+ gtk_adjustment_changed(vAdjustment);
+
+ if((pageSize > upper && height < imageHeight) || upper == 0)
+ value = (imageHeight-height)/2;
+ else
+ value = (gtk_adjustment_get_value(vAdjustment)+pageSize*y)/upper*imageHeight-height*y;
+ gtk_adjustment_set_value(vAdjustment, MAX(MIN(value, imageHeight-height), 0));
+
+ gdk_window_thaw_updates(drawingArea->window);
+
+ refreshScrolling();
+}
+
static gboolean deleteEvent(GtkWidget *widget, GdkEvent *event, gpointer data) {
return FALSE;
}
+static void realize(GtkWidget *widget, gpointer data) {
+ GdkGLContext *context = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *drawable = gtk_widget_get_gl_drawable(widget);
+
+ if(!gdk_gl_drawable_gl_begin(drawable, context))
+ return;
+
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glEnable(GL_LINE_SMOOTH);
+
+ glViewport(0, 0, widget->allocation.width, widget->allocation.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ if(widget->allocation.width != 0 && widget->allocation.height != 0) {
+ glTranslated(-1, 1, 0);
+ glScaled(2.0/widget->allocation.width, -2.0/widget->allocation.height, 1);
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ gdk_gl_drawable_gl_end(drawable);
+}
+
+static gboolean configureEvent(GtkWidget *widget, GdkEventConfigure *event, gpointer data) {
+ GdkGLContext *context = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *drawable = gtk_widget_get_gl_drawable(widget);
+
+ if(!gdk_gl_drawable_gl_begin(drawable, context))
+ return FALSE;
+
+ glViewport(0, 0, widget->allocation.width, widget->allocation.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ if(widget->allocation.width != 0 && widget->allocation.height != 0) {
+ glTranslated(-1, 1, 0);
+ glScaled(2.0/widget->allocation.width, -2.0/widget->allocation.height, 1);
+ }
+
+ gdk_gl_drawable_gl_end(drawable);
+
+ updateScrollbars(0.5, 0.5);
+
+ return TRUE;
+}
+
+
static gboolean scrollEvent(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) {
const gdouble x = event->x/widget->allocation.width, y = event->y/widget->allocation.height;
@@ -44,8 +144,6 @@ static gboolean buttonEvent(GtkWidget *widget, GdkEventButton *event, gpointer u
updateSidebar();
- redraw();
-
break;
case EDIT_MODE_ADD:
viewToImage(&v);
@@ -66,8 +164,6 @@ static gboolean buttonEvent(GtkWidget *widget, GdkEventButton *event, gpointer u
gboolean crossingNotifyEvent(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data) {
Vertex v(event->x, event->y);
-
-
switch(event->type) {
case GDK_ENTER_NOTIFY:
viewToImage(&v);
@@ -99,56 +195,6 @@ static void destroy(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
-static void refreshScrolling() {
- if(getImageWidth() < drawingArea->allocation.width)
- setXTranslate((getImageWidth()-drawingArea->allocation.width)/2);
- else
- setXTranslate(gtk_adjustment_get_value(hAdjustment));
-
- if(getImageHeight() < drawingArea->allocation.height)
- setYTranslate((getImageHeight()-drawingArea->allocation.height)/2);
- else
- setYTranslate(gtk_adjustment_get_value(vAdjustment));
-
- gtk_widget_queue_draw(drawingArea);
-}
-
-static void updateScrollbars(double x, double y) {
- const gdouble imageWidth = getImageWidth(), imageHeight = getImageHeight();
- const gdouble width = drawingArea->allocation.width, height = drawingArea->allocation.height;
- gdouble upper, pageSize, value;
-
- gdk_window_freeze_updates(drawingArea->window);
-
- g_object_get(G_OBJECT(hAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
- g_object_set(G_OBJECT(hAdjustment), "upper", imageWidth, "page_size", width, NULL);
- gtk_adjustment_changed(hAdjustment);
-
- if((pageSize > upper && width < imageWidth) || upper == 0)
- value = (imageWidth-width)/2;
- else
- value = (gtk_adjustment_get_value(hAdjustment)+pageSize*x)/upper*imageWidth-width*x;
- gtk_adjustment_set_value(hAdjustment, MAX(MIN(value, imageWidth-width), 0));
-
- g_object_get(G_OBJECT(vAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
- g_object_set(G_OBJECT(vAdjustment), "upper", imageHeight, "page_size", height, NULL);
- gtk_adjustment_changed(vAdjustment);
-
- if((pageSize > upper && height < imageHeight) || upper == 0)
- value = (imageHeight-height)/2;
- else
- value = (gtk_adjustment_get_value(vAdjustment)+pageSize*y)/upper*imageHeight-height*y;
- gtk_adjustment_set_value(vAdjustment, MAX(MIN(value, imageHeight-height), 0));
-
- gdk_window_thaw_updates(drawingArea->window);
-
- refreshScrolling();
-}
-
-static void updateScrollbarsCentered() {
- updateScrollbars(0.5, 0.5);
-}
-
static void sidebarNameChanged(GtkEditable *editable, gpointer user_data) {
if(getActiveRoom() == NULL) return;
@@ -242,7 +288,7 @@ static GtkWidget* createSidebar() {
return sidebar;
}
-GtkWidget* createMainWindow() {
+GtkWidget* createMainWindow(GdkGLConfig *glconfig) {
GtkWidget *window, *hPaned, *vbox, *table, *vScroll, *hScroll, *sidebar;
GdkColor color = {0, 0, 0, 0};
@@ -267,8 +313,10 @@ GtkWidget* createMainWindow() {
gtk_paned_pack1(GTK_PANED(hPaned), table, TRUE, TRUE);
drawingArea = gtk_drawing_area_new();
- gtk_widget_modify_bg(drawingArea, (GtkStateType)GTK_WIDGET_STATE(drawingArea), &color);
- g_signal_connect(G_OBJECT(drawingArea), "configure-event", G_CALLBACK(updateScrollbarsCentered), NULL);
+ gtk_widget_set_gl_capability(drawingArea, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
+ gtk_widget_set_double_buffered(drawingArea, FALSE);
+ g_signal_connect(G_OBJECT(drawingArea), "realize", G_CALLBACK(realize), NULL);
+ g_signal_connect(G_OBJECT(drawingArea), "configure-event", G_CALLBACK(configureEvent), NULL);
g_signal_connect(G_OBJECT(drawingArea), "expose-event", G_CALLBACK(drawTopView), NULL);
g_signal_connect(G_OBJECT(drawingArea), "button-press-event", G_CALLBACK(buttonEvent), NULL);
g_signal_connect(G_OBJECT(drawingArea), "button-release-event", G_CALLBACK(buttonEvent), NULL);
diff --git a/window.h b/window.h
index 396c014..8e9265a 100644
--- a/window.h
+++ b/window.h
@@ -2,9 +2,10 @@
#define WINDOW_H_
#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
-GtkWidget* createMainWindow();
+GtkWidget* createMainWindow(GdkGLConfig *glconfig);
void updateSidebar();
diff --git a/zoomedit.cpp b/zoomedit.cpp
index 37b6159..580e224 100644
--- a/zoomedit.cpp
+++ b/zoomedit.cpp
@@ -1,4 +1,5 @@
#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
#include <stdlib.h>
#include "Level.h"
#include "window.h"
@@ -6,13 +7,22 @@
int main(int argc, char *argv[]) {
+ GdkGLConfig *glconfig;
GtkWidget *window;
setLevel(new Level());
gtk_init(&argc, &argv);
+ gtk_gl_init(&argc, &argv);
- window = createMainWindow();
+ glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DOUBLE));
+ if(!glconfig) glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB);
+ if(!glconfig) {
+ g_print ("*** No appropriate OpenGL-capable visual found.\n");
+ exit (1);
+ }
+
+ window = createMainWindow(glconfig);
gtk_widget_show(window);