This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
neofx-zoomedit/draw.cpp

256 lines
6 KiB
C++
Raw Normal View History

2007-06-21 19:52:03 +00:00
#include "draw.h"
#include "edit.h"
#include "Rectangle.h"
2007-06-24 00:35:04 +00:00
#include <math.h>
2007-06-21 19:52:03 +00:00
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>
2007-06-21 19:52:03 +00:00
static float scale = 100.0;
static float xTranslate = 0.0, yTranslate = 0.0;
2007-06-21 19:52:03 +00:00
static void drawGrid(const Rectangle &rect) {
float depth = log10f(scale)-0.75f;
float depth2 = floorf(depth);
float step = powf(0.1f, depth2);
float f;
2007-06-24 00:35:04 +00:00
int i;
//gchar *string;
float x1 = rect.getVertex1().getX(), y1 = rect.getVertex1().getY();
float x2 = rect.getVertex2().getX(), y2 = rect.getVertex2().getY();
2007-06-24 00:35:04 +00:00
glBegin(GL_LINES);
//cairo_set_font_size(cr, 10.0/scale);
2007-06-24 17:33:00 +00:00
for(i = 0; 0.4f*(depth-depth2+i-1) < 0.5f; i++) {
f = fminf(0.4f*(depth-depth2+i), 0.5f);
glColor3f(f, f, f);
2007-06-24 17:33:00 +00:00
for(f = x1 - fmodf(x1, step) - step; f <= x2; f+=step) {
glVertex2f(f, y1);
glVertex2f(f, y2);
2007-06-24 00:35:04 +00:00
/*if(step > 0.005) {
if(step > 0.5)
string = g_strdup_printf("%i", (int)rint(d));
else
string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10);
2007-09-16 20:59:04 +00:00
cairo_move_to(cr, d+1/scale, y1+11/scale);
cairo_show_text(cr, string);
g_free(string);
}*/
2007-06-24 00:35:04 +00:00
}
for(f = y1 - fmodf(y1, step) - step; f <= y2; f+=step) {
glVertex2f(x1, f);
glVertex2f(x2, f);
2007-06-24 00:35:04 +00:00
/*if(step > 0.005) {
if(step > 0.5)
string = g_strdup_printf("%i", (int)rint(d));
else
string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10);
2007-09-16 20:59:04 +00:00
cairo_move_to(cr, x1+3/scale, d+11/scale);
cairo_show_text(cr, string);
g_free(string);
}*/
2007-06-24 00:35:04 +00:00
}
step *= 10;
}
glEnd();
2007-06-24 00:35:04 +00:00
}
static void fillPolygon(const Polygon &polygon) {
std::vector<Triangle> triangles;
2007-06-21 19:52:03 +00:00
polygon.triangulate(triangles);
2007-06-21 19:52:03 +00:00
glBegin(GL_TRIANGLES);
for(std::vector<Triangle>::iterator t = triangles.begin(); t != triangles.end(); t++) {
glVertex2f(t->getVertexA().getX(), t->getVertexA().getY());
glVertex2f(t->getVertexB().getX(), t->getVertexB().getY());
glVertex2f(t->getVertexC().getX(), t->getVertexC().getY());
}
2007-06-21 19:52:03 +00:00
glEnd();
}
static void drawPolygon(const Polygon &polygon, bool close) {
glBegin(GL_LINE_STRIP);
for(Polygon::const_iterator vertex = polygon.begin(); vertex != polygon.end(); vertex++)
glVertex2d(vertex->getX(), vertex->getY());
2007-06-21 19:52:03 +00:00
if(close)
glVertex2d(polygon.front().getX(), polygon.front().getY());
glEnd();
2007-06-21 19:52:03 +00:00
}
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
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);
2007-09-16 20:59:04 +00:00
Rectangle rect;
2007-06-21 19:52:03 +00:00
if(getLevel() == NULL) return FALSE;
2007-06-21 19:52:03 +00:00
2007-06-26 21:20:01 +00:00
viewToImage(&v1);
viewToImage(&v2);
2007-09-16 20:59:04 +00:00
rect.setVertex1(v1);
rect.setVertex2(v2);
2007-06-26 21:20:01 +00:00
if(!gdk_gl_drawable_gl_begin(drawable, context))
return FALSE;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLineWidth(1.0f);
glTranslatef(getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate, 0);
glScalef(scale, scale, 1);
drawGrid(rect);
for(Level::const_iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
if(&*room == getActiveRoom() && getEditMode() == EDIT_MODE_ADD) continue;
if(&*room == getActiveRoom())
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
else
glColor4f(0.0f, 0.7f, 1.0f, 0.3f);
2007-06-26 21:20:01 +00:00
fillPolygon(*room);
if(&*room == getActiveRoom()) {
glColor4f(1.0f, 1.0f, 1.0f, 0.9f);
glLineWidth(2.0f);
}
else if(&*room == getHoveredRoom() && getEditMode() != EDIT_MODE_ADD) {
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
glLineWidth(2.0f);
}
else {
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
glLineWidth(1.0f);
}
drawPolygon(*room, true);
}
2007-06-21 19:52:03 +00:00
if(getEditMode() == EDIT_MODE_ADD) {
if(isPolygonOk(getActiveRoom()))
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
else
glColor4f(1.0f, 0.3f, 0.3f, 0.2f);
fillPolygon(*getActiveRoom());
glLineWidth(2.0f);
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
drawPolygon(*getActiveRoom(), false);
if(!getActiveRoom()->empty() && getHoveredVertex()) {
if(!isVertexOk(getHoveredVertex()))
glColor4f(1.0f, 0.3f, 0.3f, 0.7f);
glBegin(GL_LINES);
glVertex2d(getActiveRoom()->back().getX(), getActiveRoom()->back().getY());
glVertex2d(getHoveredVertex()->getX(), getHoveredVertex()->getY());
glEnd();
}
}
glPopMatrix();
gdk_gl_drawable_swap_buffers(drawable);
gdk_gl_drawable_gl_end(drawable);
return TRUE;
2007-06-21 19:52:03 +00:00
}
float getScale() {
2007-06-21 19:52:03 +00:00
return scale;
}
void setScale(float s) {
scale = MAX(0.005, MIN(s, 10000));
}
2007-09-16 14:07:03 +00:00
void imageToView(Vertex *v) {
v->setX(v->getX()*scale+getImageWidth()/2-xTranslate);
v->setY(v->getY()*scale+getImageHeight()/2-yTranslate);
}
2007-09-16 14:07:03 +00:00
void viewToImage(Vertex *v) {
v->setX((v->getX()-getImageWidth()/2+xTranslate)/scale);
v->setY((v->getY()-getImageHeight()/2+yTranslate)/scale);
2007-06-21 19:52:03 +00:00
}
float getImageWidth() {
float min = 0.0, max = 0.0;
2007-09-16 19:06:02 +00:00
if(getLevel()) {
for(Level::iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
for(Room::iterator v = room->begin(); v != room->end(); v++) {
min = fminf(min, v->getX());
max = fmaxf(max, v->getX());
}
}
}
return (max-min+10)*scale;
2007-06-21 19:52:03 +00:00
}
float getImageHeight() {
float min = 0.0, max = 0.0;
if(getLevel()) {
for(Level::iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
for(Room::iterator v = room->begin(); v != room->end(); v++) {
min = fminf(min, v->getY());
max = fmaxf(max, v->getY());
}
}
}
return (max-min+10)*scale;
2007-06-21 19:52:03 +00:00
}
float getXTranslate() {
2007-06-21 19:52:03 +00:00
return xTranslate;
}
void setXTranslate(float x) {
2007-06-21 19:52:03 +00:00
xTranslate = x;
}
float getYTranslate() {
2007-06-21 19:52:03 +00:00
return yTranslate;
}
void setYTranslate(float y) {
2007-06-21 19:52:03 +00:00
yTranslate = y;
}