summaryrefslogtreecommitdiff
path: root/src/glview.cc
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2011-07-30 23:58:51 (GMT)
committerMarius Kintel <marius@kintel.net>2011-07-30 23:58:51 (GMT)
commit6882228058d313bb7b98fddd90239bdb1a3e25ef (patch)
tree9e3f0077a319939df7496fc6b18350c44cc4b0ec /src/glview.cc
parentdd9dfcb4ece4dcd1ae7f3374ef03a4babdb91dd8 (diff)
parentc79ad5010e4ae8a612de5423cd52a518ed6b4d65 (diff)
Merge branch 'master' into visitor
Conflicts: src/GLView.h src/glview.cc src/mainwin.cc src/render-opencsg.cc
Diffstat (limited to 'src/glview.cc')
-rw-r--r--src/glview.cc219
1 files changed, 96 insertions, 123 deletions
diff --git a/src/glview.cc b/src/glview.cc
index 3daa064..896ff0a 100644
--- a/src/glview.cc
+++ b/src/glview.cc
@@ -26,6 +26,7 @@
#include "GLView.h"
#include "Preferences.h"
+#include "renderer.h"
#include <QApplication>
#include <QWheelEvent>
@@ -41,9 +42,13 @@
#include "mathc99.h"
#include <stdio.h>
+#ifdef ENABLE_OPENCSG
+# include <opencsg.h>
+#endif
+
#define FAR_FAR_AWAY 100000.0
-GLView::GLView(QWidget *parent) : QGLWidget(parent)
+GLView::GLView(QWidget *parent) : QGLWidget(parent), renderer(NULL)
{
init();
}
@@ -64,16 +69,13 @@ void GLView::init()
this->object_trans_z = 0;
this->mouse_drag_active = false;
- this->last_mouse_x = 0;
- this->last_mouse_y = 0;
+ this->showedges = false;
+ this->showfaces = true;
this->orthomode = false;
this->showaxes = false;
this->showcrosshairs = false;
- this->renderfunc = NULL;
- this->renderfunc_vp = NULL;
-
for (int i = 0; i < 10; i++)
this->shaderinfo[i] = 0;
@@ -87,10 +89,10 @@ void GLView::init()
#endif
}
-void GLView::setRenderFunc(void (*func)(void*), void *userdata)
+void GLView::setRenderer(Renderer *r)
{
- this->renderfunc = func;
- this->renderfunc_vp = userdata;
+ this->renderer = r;
+ updateGL();
}
void GLView::initializeGL()
@@ -101,6 +103,22 @@ void GLView::initializeGL()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0};
+ GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0};
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
+ glEnable(GL_LIGHT1);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_NORMALIZE);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+
#ifdef ENABLE_OPENCSG
GLenum err = glewInit();
if (GLEW_OK != err) {
@@ -266,43 +284,47 @@ void GLView::resizeGL(int w, int h)
#endif
glViewport(0, 0, w, h);
w_h_ratio = sqrt((double)w / (double)h);
+
+ setupPerspective();
}
-void GLView::paintGL()
+void GLView::setupPerspective()
{
- const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR);
- glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY);
+}
+void GLView::setupOrtho(double distance, bool offset)
+{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
+ if(offset)
+ glTranslated(-0.8, -0.8, 0);
+ double l = distance/10;
+ glOrtho(-w_h_ratio*l, +w_h_ratio*l,
+ -(1/w_h_ratio)*l, +(1/w_h_ratio)*l,
+ -FAR_FAR_AWAY, +FAR_FAR_AWAY);
+}
+
+void GLView::paintGL()
+{
+ glEnable(GL_LIGHTING);
+
if (orthomode)
- glOrtho(-w_h_ratio*viewer_distance/10, +w_h_ratio*viewer_distance/10,
- -(1/w_h_ratio)*viewer_distance/10, +(1/w_h_ratio)*viewer_distance/10,
- -FAR_FAR_AWAY, +FAR_FAR_AWAY);
- else
- glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY);
- gluLookAt(0.0, -viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+ setupOrtho(viewer_distance);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
- GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0};
- GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0};
+ const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR);
+ glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
- glEnable(GL_LIGHT1);
- glEnable(GL_LIGHTING);
- glEnable(GL_NORMALIZE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
+ gluLookAt(0.0, -viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+
+ glTranslated(object_trans_x, object_trans_y, object_trans_z);
glRotated(object_rot_x, 1.0, 0.0, 0.0);
glRotated(object_rot_y, 0.0, 1.0, 0.0);
@@ -325,8 +347,6 @@ void GLView::paintGL()
glEnd();
}
- glTranslated(object_trans_x, object_trans_y, object_trans_z);
-
// Large gray axis cross inline with the model
// FIXME: This is always gray - adjust color to keep contrast with background
if (showaxes)
@@ -334,12 +354,13 @@ void GLView::paintGL()
glLineWidth(1);
glColor3d(0.5, 0.5, 0.5);
glBegin(GL_LINES);
- glVertex3d(-viewer_distance/10, 0, 0);
- glVertex3d(+viewer_distance/10, 0, 0);
- glVertex3d(0, -viewer_distance/10, 0);
- glVertex3d(0, +viewer_distance/10, 0);
- glVertex3d(0, 0, -viewer_distance/10);
- glVertex3d(0, 0, +viewer_distance/10);
+ double l = viewer_distance/10;
+ glVertex3d(-l, 0, 0);
+ glVertex3d(+l, 0, 0);
+ glVertex3d(0, -l, 0);
+ glVertex3d(0, +l, 0);
+ glVertex3d(0, 0, -l);
+ glVertex3d(0, 0, +l);
glEnd();
}
@@ -350,20 +371,21 @@ void GLView::paintGL()
glLineWidth(2);
glColor3d(1.0, 0.0, 0.0);
- if (renderfunc)
- renderfunc(renderfunc_vp);
+ if (this->renderer) {
+#if defined(ENABLE_MDI) && defined(ENABLE_OPENCSG)
+ // FIXME: This belongs in the OpenCSG renderer, but it doesn't know about this ID yet
+ OpenCSG::setContext(this->opencsg_id);
+#endif
+ this->renderer->draw(showfaces, showedges);
+ }
// Small axis cross in the lower left corner
if (showaxes)
{
glDepthFunc(GL_ALWAYS);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glTranslated(-0.8, -0.8, 0);
- glOrtho(-w_h_ratio*1000/10, +w_h_ratio*1000/10,
- -(1/w_h_ratio)*1000/10, +(1/w_h_ratio)*1000/10,
- -FAR_FAR_AWAY, +FAR_FAR_AWAY);
+ setupOrtho(1000,true);
+
gluLookAt(0.0, -1000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
@@ -428,6 +450,10 @@ void GLView::paintGL()
glVertex3d(zlabel_x-3, zlabel_y+3, 0); glVertex3d(zlabel_x+3, zlabel_y+3, 0);
glVertex3d(zlabel_x-3, zlabel_y-3, 0); glVertex3d(zlabel_x+3, zlabel_y+3, 0);
glEnd();
+
+ //Restore perspective for next paint
+ if(!orthomode)
+ setupPerspective();
}
if (statusLabel) {
@@ -462,101 +488,48 @@ void GLView::wheelEvent(QWheelEvent *event)
void GLView::mousePressEvent(QMouseEvent *event)
{
mouse_drag_active = true;
- last_mouse_x = event->globalX();
- last_mouse_y = event->globalY();
+ last_mouse = event->globalPos();
grabMouse();
setFocus();
}
-static void mat_id(double *trg)
-{
- for (int i = 0; i < 16; i++)
- trg[i] = i%5 == 0;
-}
-static void mat_mul(double *trg, const double *m1, const double *m2)
+void GLView::normalizeAngle(GLdouble& angle)
{
- double m[16];
- for (int x = 0; x < 4; x++)
- for (int y = 0; y < 4; y++)
- {
- m[x+y*4] = 0;
- for (int i = 0; i < 4; i++)
- m[x+y*4] += m1[i+y*4] * m2[x+i*4];
- }
- for (int i = 0; i < 16; i++)
- trg[i] = m[i];
-}
-
-static void mat_rot(double *trg, double angle, double x, double y, double z)
-{
- double s = sin(M_PI*angle/180), c = cos(M_PI*angle/180);
- double cc = 1 - c;
- double m[16] = {
- x*x*cc+c, x*y*cc-z*s, x*z*cc+y*s, 0,
- y*x*cc+z*s, y*y*cc+c, y*z*cc-x*s, 0,
- x*z*cc-y*s, y*z*cc+x*s, z*z*cc+c, 0,
- 0, 0, 0, 1
- };
- for (int i = 0; i < 16; i++)
- trg[i] = m[i];
+ while(angle < 0)
+ angle += 360;
+ while(angle > 360)
+ angle -= 360;
}
void GLView::mouseMoveEvent(QMouseEvent *event)
{
- int this_mouse_x = event->globalX();
- int this_mouse_y = event->globalY();
+ QPoint this_mouse = event->globalPos();
+ double dx = (this_mouse.x()-last_mouse.x()) * 0.7;
+ double dy = (this_mouse.y()-last_mouse.y()) * 0.7;
if (mouse_drag_active) {
if ((event->buttons() & Qt::LeftButton) != 0) {
- object_rot_x += (this_mouse_y-last_mouse_y) * 0.7;
+ object_rot_x += dy;
if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0)
- object_rot_y += (this_mouse_x-last_mouse_x) * 0.7;
+ object_rot_y += dx;
else
- object_rot_z += (this_mouse_x-last_mouse_x) * 0.7;
- while (object_rot_x < 0)
- object_rot_x += 360;
- while (object_rot_x >= 360)
- object_rot_x -= 360;
- while (object_rot_y < 0)
- object_rot_y += 360;
- while (object_rot_y >= 360)
- object_rot_y -= 360;
- while (object_rot_z < 0)
- object_rot_z += 360;
- while (object_rot_z >= 360)
- object_rot_z -= 360;
+ object_rot_z += dx;
+
+ normalizeAngle(object_rot_x);
+ normalizeAngle(object_rot_y);
+ normalizeAngle(object_rot_z);
} else {
- double mx = +(this_mouse_x-last_mouse_x) * viewer_distance/1000;
- double my = -(this_mouse_y-last_mouse_y) * viewer_distance/1000;
- double rx[16], ry[16], rz[16], tm[16];
- mat_rot(rx, -object_rot_x, 1.0, 0.0, 0.0);
- mat_rot(ry, -object_rot_y, 0.0, 1.0, 0.0);
- mat_rot(rz, -object_rot_z, 0.0, 0.0, 1.0);
- mat_id(tm);
- mat_mul(tm, rx, tm);
- mat_mul(tm, ry, tm);
- mat_mul(tm, rz, tm);
- double vec[16] = {
- 0, 0, 0, mx,
- 0, 0, 0, 0,
- 0, 0, 0, my,
- 0, 0, 0, 1
- };
if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) {
- vec[3] = 0;
- vec[7] = my;
- vec[11] = 0;
+ viewer_distance += (GLdouble)dy;
+ } else {
+ object_trans_x += dx;
+ object_trans_z -= dy;
}
- mat_mul(tm, tm, vec);
- object_trans_x += tm[3];
- object_trans_y += tm[7];
- object_trans_z += tm[11];
}
updateGL();
emit doAnimateUpdate();
}
- last_mouse_x = this_mouse_x;
- last_mouse_y = this_mouse_y;
+ last_mouse = this_mouse;
}
void GLView::mouseReleaseEvent(QMouseEvent*)
contact: Jan Huwald // Impressum