#include "qwt3d_drawable.h" using namespace Qwt3D; Drawable::~Drawable() { detachAll(); } void Drawable::saveGLState() { glGetBooleanv(GL_LINE_SMOOTH, &ls); glGetBooleanv(GL_POLYGON_SMOOTH, &pols); glGetFloatv(GL_LINE_WIDTH, &lw); glGetIntegerv(GL_BLEND_SRC, &blsrc); glGetIntegerv(GL_BLEND_DST, &bldst); glGetDoublev(GL_CURRENT_COLOR, col); glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &pattern); glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &factor); glGetBooleanv(GL_LINE_STIPPLE, &sallowed); glGetBooleanv(GL_TEXTURE_2D, &tex2d); glGetIntegerv(GL_POLYGON_MODE, polmode); glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &poloffs[0]); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &poloffs[1]); glGetBooleanv(GL_POLYGON_OFFSET_FILL, &poloffsfill); } void Drawable::restoreGLState() { Enable(GL_LINE_SMOOTH, ls); Enable(GL_POLYGON_SMOOTH, pols); setDeviceLineWidth(lw); glBlendFunc(blsrc, bldst); glColor4dv(col); glLineStipple(factor,pattern); Enable(GL_LINE_STIPPLE,sallowed); Enable(GL_TEXTURE_2D,tex2d); glPolygonMode(polmode[0], polmode[1]); glMatrixMode(matrixmode); glPolygonOffset(poloffs[0], poloffs[1]); setDevicePolygonOffset(poloffs[0], poloffs[1]); Enable(GL_POLYGON_OFFSET_FILL, poloffsfill); } void Drawable::Enable(GLenum what, GLboolean val) { if (val) glEnable(what); else glDisable(what); } void Drawable::attach(Drawable* dr) { if ( dlist.end() == std::find( dlist.begin(), dlist.end(), dr ) ) if (dr) { dlist.push_back(dr); } } void Drawable::detach(Drawable* dr) { std::list::iterator it = std::find(dlist.begin(), dlist.end(), dr); if ( it != dlist.end() ) { dlist.erase(it); } } void Drawable::detachAll() { dlist.clear(); } //! simplified glut routine (glUnProject): windows coordinates_p --> object coordinates_p /** Don't rely on (use) this in display lists ! */ Triple Drawable::ViewPort2World(Triple win, bool* err) { Triple obj; getMatrices(modelMatrix, projMatrix, viewport); int res = gluUnProject(win.x, win.y, win.z, modelMatrix, projMatrix, viewport, &obj.x, &obj.y, &obj.z); if (err) *err = (res) ? false : true; return obj; } //! simplified glut routine (glProject): object coordinates_p --> windows coordinates_p /** Don't rely on (use) this in display lists ! */ Triple Drawable::World2ViewPort(Triple obj, bool* err) { Triple win; getMatrices(modelMatrix, projMatrix, viewport); int res = gluProject(obj.x, obj.y, obj.z, modelMatrix, projMatrix, viewport, &win.x, &win.y, &win.z); if (err) *err = (res) ? false : true; return win; } /** Don't rely on (use) this in display lists ! */ Triple Drawable::relativePosition(Triple rel) { return ViewPort2World(Triple((rel.x-viewport[0])*viewport[2],(rel.y-viewport[1])*viewport[3],rel.z)); } void Drawable::draw() { saveGLState(); for (std::list::iterator it = dlist.begin(); it!=dlist.end(); ++it) { (*it)->draw(); } restoreGLState(); } void Drawable::setColor(double r, double g, double b, double a) { color = RGBA(r,g,b,a); } void Drawable::setColor(RGBA rgba) { color = rgba; }