/* * Copyright (c) 2002-2006 Samit Basu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "GLRenderEngine.hpp" #include #include #include #include GLRenderEngine::GLRenderEngine(QGLWidget *widget, double x1, double y1, double width, double height) { m_x1 = x1; m_y1 = y1; m_width = width; m_height = height; m_widget = widget; glEnable(GL_TEXTURE_2D); } QGLWidget* GLRenderEngine::widget() { return m_widget; } GLRenderEngine::~GLRenderEngine() { } void GLRenderEngine::clear(std::vector color) { if (color[0] != -1) { glClearColor(color[0], color[1], color[2], 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } void GLRenderEngine::toPixels(double x, double y, double z, double &a, double &b, bool &clipped) { toPixels(x,y,z,a,b); clipped = ((a < viewp[0]) || (a > (viewp[0] + viewp[2])) || (b < viewp[1]) || (b > (viewp[1] + viewp[3]))); } void GLRenderEngine::toPixels(double x, double y, double z, double &a, double &b) { double c1, c2, c3; gluProject(x,y,z,model,proj,viewp,&c1,&c2,&c3); a = c1; b = c2; } void GLRenderEngine::unitx(double &x, double &y, double &z) { // we need a unitvector such that model*v = [1;0;0] double m00, m01, m02; double m10, m11, m12; double m20, m21, m22; double det; det = m00*(m11*m22-m12*m21) - m01*(m10*m22-m12*m21) + m02*(m10*m21-m11*m20); x = (m11*m21-m12*m21)/det; y = -(m10*m22-m12*m21)/det; z = (m10*m21-m11*m20)/det; } void GLRenderEngine::unity(double &x, double &y, double &z) { } void GLRenderEngine::toPixels(double x, double y, double z, int &a, int &b) { double c1, c2; toPixels(x,y,z,c1,c2); a = (int) c1; b = (int) c2; } void GLRenderEngine::scale(double sx, double sy, double sz) { glMatrixMode(GL_MODELVIEW); glScaled(sx,sy,sz); glGetDoublev(GL_MODELVIEW_MATRIX,model); } void GLRenderEngine::lookAt(double px, double py, double pz, double tx, double ty, double tz, double ux, double uy, double uz) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(px,py,pz,tx,ty,tz,ux,uy,uz); glGetDoublev(GL_MODELVIEW_MATRIX,model); } static void gluMultMatrixVecd(const double matrix[16], const double in[4], double out[4]) { int i; for (i=0; i<4; i++) { out[i] = in[0] * matrix[0*4+i] + in[1] * matrix[1*4+i] + in[2] * matrix[2*4+i] + in[3] * matrix[3*4+i]; } } void GLRenderEngine::mapPoint(double x, double y, double z, double &a, double &b, double &c) { double out[4]; double in[4]; in[0] = x; in[1] = y; in[2] = z; in[3] = 1.0; gluMultMatrixVecd(model,in,out); a = out[0]; b = out[1]; c = out[2]; } void GLRenderEngine::project(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(xmin,xmax,ymin,ymax,zmin,zmax); glGetDoublev(GL_PROJECTION_MATRIX,proj); } void GLRenderEngine::viewport(double x0, double y0, double width, double height) { glViewport((int)x0,(int)y0,(int)width,(int)height); glGetIntegerv(GL_VIEWPORT,viewp); } void GLRenderEngine::quad(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double x4, double y4, double z4) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_QUADS); glVertex3f(x1,y1,z1); glVertex3f(x2,y2,z2); glVertex3f(x3,y3,z3); glVertex3f(x4,y4,z4); glEnd(); } void GLRenderEngine::quadline(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double x4, double y4, double z4) { glBegin(GL_LINE_LOOP); glVertex3f(x1,y1,z1); glVertex3f(x2,y2,z2); glVertex3f(x3,y3,z3); glVertex3f(x4,y4,z4); glEnd(); } void GLRenderEngine::color(std::vector col) { glColor3f(col[0],col[1],col[2]); } void GLRenderEngine::setLineStyle(std::string style) { if (style == "-") { glDisable(GL_LINE_STIPPLE); return; } if (style == "--") { glEnable(GL_LINE_STIPPLE); glLineStipple(1,0x00FF); return; } if (style == ":") { glEnable(GL_LINE_STIPPLE); glLineStipple(1,0xDDDD); return; } if (style == "-.") { glEnable(GL_LINE_STIPPLE); glLineStipple(1,0xF0D0); return; } if (style == "none") { glEnable(GL_LINE_STIPPLE); glLineStipple(1,0x0000); return; } } void GLRenderEngine::lineWidth(double n) { glLineWidth(n); } void GLRenderEngine::line(double x1, double y1, double z1, double x2, double y2, double z2) { glBegin(GL_LINES); glVertex3f(x1,y1,z1); glVertex3f(x2,y2,z2); glEnd(); } void GLRenderEngine::line(double x1, double y1, double x2, double y2) { glBegin(GL_LINES); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } void GLRenderEngine::lineSeries(std::vector xs, std::vector ys, std::vector zs) { glBegin(GL_LINE_STRIP); for (int i=0;i color, AlignmentFlag xflag, AlignmentFlag yflag, QFont fnt, double rotation) { QFontMetrics fm(fnt); QRect sze(fm.boundingRect(txt.c_str())); int x0 = sze.left(); int y0 = sze.bottom(); int width = sze.width(); int height = sze.height(); // We now now the width and height. From this, // we can compute the radial length int radlength = (int) sqrt(width*width+height*height)*2; // We need a bitmap surface that is 2X this size. QImage img(radlength,radlength,QImage::Format_RGB32); QPainter pnt(&img); pnt.setRenderHint(QPainter::TextAntialiasing); pnt.setRenderHint(QPainter::Antialiasing); pnt.setBackground(QColor(255,255,255)); pnt.eraseRect(0,0,radlength,radlength); pnt.setFont(fnt); pnt.setPen(QColor(0,0,0)); // We translate to the center of the bitmap pnt.translate(radlength/2,radlength/2); pnt.rotate(-rotation); // pnt.drawText(-width/2,height/2,txt.c_str()); pnt.drawText(0,0,txt.c_str()); pnt.end(); // The next step is to trim the bitmap from the bottom up bool allempty = true; int row_offset = 0; while (allempty && (row_offset < (radlength/2-1))) { QRgb* dbits = (QRgb*) img.scanLine(radlength-1-row_offset); allempty = true; for (int i=0;allempty && (ibindTexture(pic); glColor3f(1,1,1); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glDisable(GL_LIGHTING); glBegin(GL_QUADS); glTexCoord2d(0,0); glVertex2f(x1,y1); glTexCoord2d(1,0); glVertex2f(x2,y1); glTexCoord2d(1,1); glVertex2f(x2,y2); glTexCoord2d(0,1); glVertex2f(x1,y2); glEnd(); // glEnable(GL_LIGHTING); m_widget->deleteTexture(texid); } void GLRenderEngine::quadStrips(std::vector > faces, bool flatfaces, std::vector > edges, bool flatedges) { glDisable(GL_CULL_FACE); glEnable(GL_POLYGON_OFFSET_FILL); if (flatfaces) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH); glPolygonOffset(2,2); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); for (int i=0;i qlist(faces[i]); glBegin(GL_QUAD_STRIP); for (int j=0;j qlist(edges[i]); glBegin(GL_QUAD_STRIP); for (int j=0;j