diff options
Diffstat (limited to 'draw.cpp')
-rw-r--r-- | draw.cpp | 234 |
1 files changed, 95 insertions, 139 deletions
@@ -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; } |