00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <GL/glew.h>
00030 #include <wrap/gl/space.h>
00031 #include <wrap/gl/picking.h>
00032
00033 #include "rubberband.h"
00034
00035 using namespace vcg;
00036
00037 Rubberband::Rubberband(Color4b c)
00038 :color(c),currentphase(RUBBER_BEGIN),qt_cursor(),
00039 start(0,0,0),end(0,0,0),have_to_pick(false),font()
00040 {
00041 font.setFamily("Helvetica");
00042 font.setPixelSize(10);
00043 }
00044
00045 void Rubberband::Render(QGLWidget* gla)
00046 {
00047 if(have_to_pick){
00048 assert(currentphase!=RUBBER_DRAGGED);
00049 Point3f pick_point;
00050 bool picked = Pick(qt_cursor.x(), gla->height() - qt_cursor.y(), pick_point);
00051 if(picked){
00052 have_to_pick=false;
00053 switch(currentphase){
00054 case RUBBER_BEGIN:
00055 start = pick_point;
00056 gla->setMouseTracking(true);
00057 currentphase = RUBBER_DRAGGING;
00058 break;
00059 case RUBBER_DRAGGING:
00060 if(pick_point==start){
00061 have_to_pick=true;
00062 break;
00063 }
00064 end = pick_point;
00065 gla->setMouseTracking(false);
00066 currentphase = RUBBER_DRAGGED;
00067 break;
00068 default:
00069 assert(0);
00070 }
00071 }
00072 }
00073
00074 if(currentphase==RUBBER_BEGIN) return;
00075
00076
00077 glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT);
00078 glDisable(GL_LIGHTING);
00079 glDisable(GL_TEXTURE_2D);
00080 glDepthMask(false);
00081 glLineWidth(2.5);
00082 glPointSize(5.0);
00083 if(currentphase==RUBBER_DRAGGING ) {
00084 Point3f qt_start_point;
00085 qt_start_point = PixelConvert(start);
00086 glColor(color);
00087 glMatrixMode(GL_PROJECTION);
00088 glPushMatrix();
00089 glLoadIdentity();
00090 gluOrtho2D(0,gla->width(),gla->height(),0);
00091 glMatrixMode(GL_MODELVIEW);
00092 glPushMatrix();
00093 glLoadIdentity();
00094 glDisable(GL_DEPTH_TEST);
00095 glBegin(GL_LINES);
00096 glVertex2f(qt_start_point[0],qt_start_point[1]);
00097 glVertex2f(qt_cursor.x(),qt_cursor.y());
00098 glEnd();
00099 glEnable(GL_DEPTH_TEST);
00100 glMatrixMode(GL_PROJECTION);
00101 glPopMatrix();
00102 glMatrixMode(GL_MODELVIEW);
00103 glPopMatrix();
00104 } else {
00105 assert(currentphase == RUBBER_DRAGGED);
00106 glEnable(GL_BLEND);
00107 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00108 glEnable(GL_LINE_SMOOTH);
00109 glEnable(GL_POINT_SMOOTH);
00110 glColor(color);
00111 glBegin(GL_LINES);
00112 glVertex(start);
00113 glVertex(end);
00114 glEnd();
00115 glBegin(GL_POINTS);
00116 glVertex(start);
00117 glVertex(end);
00118 glEnd();
00119 glDisable(GL_DEPTH_TEST);
00120 glLineWidth(0.7);
00121 glPointSize(1.4);
00122 glBegin(GL_LINES);
00123 glVertex(start);
00124 glVertex(end);
00125 glEnd();
00126 glBegin(GL_POINTS);
00127 glVertex(start);
00128 glVertex(end);
00129 glEnd();
00130 }
00131 glPopAttrib();
00132 assert(!glGetError());
00133 }
00134
00135 void Rubberband::Drag(QPoint p)
00136 {
00137 if(currentphase==RUBBER_DRAGGING);
00138 qt_cursor=p;
00139 }
00140
00141 void Rubberband::Pin(QPoint p)
00142 {
00143 if(IsReady())
00144 return;
00145 qt_cursor=p;
00146 have_to_pick=true;
00147 }
00148
00149 void Rubberband::Reset()
00150 {
00151 currentphase = RUBBER_BEGIN;
00152 qt_cursor = QPoint();
00153 start = Point3f(0,0,0);
00154 end = Point3f(0,0,0);
00155 have_to_pick = false;
00156 }
00157
00158 bool Rubberband::IsReady()
00159 {
00160 return currentphase==RUBBER_DRAGGED;
00161 }
00162
00163 void Rubberband::GetPoints(Point3f &s,Point3f &e)
00164 {
00165 assert(IsReady());
00166 s=start;
00167 e=end;
00168 }
00169
00170 void Rubberband::RenderLabel(QString text,QGLWidget* gla)
00171 {
00172 if(currentphase==RUBBER_BEGIN) return;
00173
00174 int x,y;
00175 if(currentphase==RUBBER_DRAGGING){
00176 x=qt_cursor.x()+16;
00177 y=qt_cursor.y()+16;
00178 } else {
00179 Point3f qt_start = PixelConvert(start);
00180 Point3f qt_end = PixelConvert(end);
00181 if(qt_start[0]>qt_end[0]){
00182 x=int(qt_start[0]+5);
00183 y=int(qt_start[1]);
00184 }else{
00185 x=int(qt_end[0]+5);
00186 y=int(qt_end[1]);
00187 }
00188 }
00189
00190 QFontMetrics fm(font);
00191 QRect brec=fm.boundingRect(text);
00192 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT );
00193 glDisable(GL_LIGHTING);
00194 glDisable(GL_TEXTURE_2D);
00195 glEnable(GL_BLEND);
00196 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00197
00198 glMatrixMode(GL_PROJECTION);
00199 glPushMatrix();
00200 glLoadIdentity();
00201 gluOrtho2D(0,gla->width(),gla->height(),0);
00202 glMatrixMode(GL_MODELVIEW);
00203 glPushMatrix();
00204 glLoadIdentity();
00205 glColor4f(0,0,0,0.5);
00206 glBegin(GL_QUADS);
00207 glVertex2f(x+brec.left(),y+brec.bottom());
00208 glVertex2f(x+brec.right(),y+brec.bottom());
00209 glVertex2f(x+brec.right(),y+brec.top());
00210 glVertex2f(x+brec.left(),y+brec.top());
00211 glEnd();
00212 int offset=2;
00213 glColor4f(0,0,0,0.2);
00214 glBegin(GL_QUADS);
00215 glVertex2f(x+brec.left()-offset,y+brec.bottom()+offset);
00216 glVertex2f(x+brec.right()+offset,y+brec.bottom()+offset);
00217 glVertex2f(x+brec.right()+offset,y+brec.top()-offset);
00218 glVertex2f(x+brec.left()-offset,y+brec.top()-offset);
00219 glEnd();
00220 glColor3f(1,1,1);
00221 gla->renderText(x,y,0.99f,text,font);
00222 glMatrixMode(GL_PROJECTION);
00223 glPopMatrix();
00224 glMatrixMode(GL_MODELVIEW);
00225 glPopMatrix();
00226 glPopAttrib();
00227 }
00228
00229 Point3f Rubberband::PixelConvert(const Point3f p)
00230 {
00231 GLint vm[4];
00232 GLdouble mm[16];
00233 GLdouble pm[16];
00234 glGetIntegerv(GL_VIEWPORT, vm);
00235 glGetDoublev(GL_MODELVIEW_MATRIX, mm);
00236 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00237 GLdouble wx,wy,wz;
00238 gluProject(p[0], p[1], p[2], mm, pm, vm, &wx, &wy, &wz);
00239 return Point3f(wx,vm[3]-wy,wz);
00240 }