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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifndef ViewPort3D_C_DEFINED
00048 #define ViewPort3D_C_DEFINED
00049
00050 #include "GUI/ViewPort3D.H"
00051 #include "Image/DrawOps.H"
00052 #include "GUI/DebugWin.H"
00053 #include <stdio.h>
00054
00055 ViewPort3D::ViewPort3D(const int width,const int height,
00056 bool wireframe, bool useLights, bool useFeedback) :
00057 itsScreenWidth(width),
00058 itsScreenHeight(height),
00059 itsCameraPosition(Point3D<float>(0,0,0)),
00060 itsCameraRotation(Point3D<float>(0,0,0)),
00061 itsShowRenderWindow(false),
00062 itsWireframe(wireframe),
00063 itsUseLights(useLights),
00064 itsUseFeedback(useFeedback),
00065 itsSphereQuality(5),
00066 itsCylinderQuality(5),
00067 itsSphereListNum(0),
00068 itsInitGlew(false)
00069
00070 {
00071
00072
00073
00074 itsDisplay = XOpenDisplay(0);
00075 if (!itsDisplay)
00076 LFATAL("Failed to open X display");
00077
00078
00079 static int visual_attribs[] =
00080 {
00081 GLX_X_RENDERABLE , True,
00082 GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
00083 GLX_RENDER_TYPE , GLX_RGBA_BIT,
00084 GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
00085 GLX_RED_SIZE , 8,
00086 GLX_GREEN_SIZE , 8,
00087 GLX_BLUE_SIZE , 8,
00088 GLX_ALPHA_SIZE , 8,
00089 GLX_DEPTH_SIZE , 24,
00090 GLX_STENCIL_SIZE , 8,
00091 GLX_DOUBLEBUFFER , True,
00092
00093
00094 None
00095 };
00096
00097 XVisualInfo *vi;
00098 LINFO( "Getting matching framebuffer configs" );
00099 int fbcount;
00100 GLXFBConfig *fbc = glXChooseFBConfig( itsDisplay, DefaultScreen( itsDisplay ),
00101 visual_attribs, &fbcount );
00102 if ( fbc )
00103 {
00104 LINFO( "Found %d matching FB configs.", fbcount );
00105
00106
00107 LINFO( "Getting XVisualInfos" );
00108 int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
00109
00110 for (int i = 0; i < fbcount; i++ )
00111 {
00112 XVisualInfo *tmpVi = glXGetVisualFromFBConfig( itsDisplay, fbc[i] );
00113 if ( tmpVi )
00114 {
00115 int samp_buf, samples;
00116 glXGetFBConfigAttrib( itsDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
00117 glXGetFBConfigAttrib( itsDisplay, fbc[i], GLX_SAMPLES , &samples );
00118
00119 LINFO( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
00120 " SAMPLES = %d",
00121 i, (uint)tmpVi -> visualid, samp_buf, samples );
00122
00123 if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) )
00124 best_fbc = i, best_num_samp = samples;
00125 if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
00126 worst_fbc = i, worst_num_samp = samples;
00127 }
00128 XFree( tmpVi );
00129 }
00130
00131
00132 int fbc_id = worst_fbc;
00133
00134 vi = glXGetVisualFromFBConfig( itsDisplay, fbc[ fbc_id ] );
00135 LINFO( "Chosen visual ID = 0x%x", (uint)vi->visualid );
00136 } else {
00137
00138 int screen = DefaultScreen(itsDisplay);
00139
00140 static int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16,
00141 GLX_RED_SIZE,4, GLX_GREEN_SIZE,4,
00142 GLX_BLUE_SIZE,4, None};
00143 vi = glXChooseVisual (itsDisplay,screen,attribList);
00144 }
00145 if (!vi) LFATAL("no good X11 visual found for OpenGL");
00146
00147 LINFO( "Creating colormap" );
00148 XSetWindowAttributes swa;
00149 swa.colormap = XCreateColormap( itsDisplay, RootWindow( itsDisplay, vi->screen ),
00150 vi->visual, AllocNone );
00151 swa.background_pixmap = None ;
00152 swa.border_pixel = 0;
00153 swa.event_mask = StructureNotifyMask;
00154
00155 LINFO( "Creating window");
00156 itsWin = XCreateWindow( itsDisplay, RootWindow( itsDisplay, vi->screen ),
00157 0, 0, itsScreenWidth, itsScreenHeight, 0,
00158 vi->depth, InputOutput,
00159 vi->visual,
00160 CWBorderPixel|CWColormap|CWEventMask, &swa );
00161 if ( !itsWin )
00162 LFATAL( "Failed to create window." );
00163
00164 if (itsShowRenderWindow)
00165 {
00166 XStoreName( itsDisplay, itsWin, "Render Window");
00167 XMapWindow( itsDisplay, itsWin );
00168 }
00169
00170
00171
00172
00173
00174 GLXContext ctx_old = glXCreateContext( itsDisplay, vi, 0, True );
00175
00176 (glXCreateContextAttribsARBProc)
00177 glXGetProcAddress( (const GLubyte *) "glXCreateContextAttribsARB" );
00178
00179 itsCtx = ctx_old;
00180 XFree( fbc );
00181
00182
00183
00184
00185
00186
00187
00188
00189 double cameraParam[3][4] = {
00190 {350.475735, 0, 158.250000, 0},
00191 {0.000000, -363.047091, 118.250000, 0.000000},
00192 {0.000000, 0.000000, 1.000000, 0.00000}};
00193 setProjectionMatrix(cameraParam);
00194
00195 itsUseExParam = false;
00196
00197
00198 if (itsUseFeedback)
00199 {
00200 itsFeedbackBufferSize = 1024*1024;
00201 itsFeedbackBuffer = new float[itsFeedbackBufferSize];
00202 } else {
00203 itsFeedbackBufferSize = 0;
00204 itsFeedbackBuffer = NULL;
00205 }
00206
00207
00208
00209 }
00210
00211 ViewPort3D::~ViewPort3D()
00212 {
00213 delete[] itsFeedbackBuffer;
00214 glXMakeCurrent( itsDisplay, 0, 0 );
00215 glXDestroyContext( itsDisplay, itsCtx );
00216 }
00217
00218 void ViewPort3D::initCtx()
00219 {
00220 glXMakeCurrent (itsDisplay,itsWin,itsCtx);
00221 }
00222
00223
00224 void ViewPort3D::initFrame()
00225 {
00226 glXMakeCurrent (itsDisplay,itsWin,itsCtx);
00227
00228
00229 glDrawBuffer(GL_BACK);
00230 glReadBuffer(GL_BACK);
00231
00232 glEnable(GL_TEXTURE_2D);
00233 glShadeModel(GL_SMOOTH);
00234 glClearColor(0, 0, 0, 0.5);
00235 glClearDepth(1.0);
00236
00237
00238
00239
00240
00241 glEnable (GL_CULL_FACE);
00242 glCullFace (GL_BACK);
00243 glFrontFace (GL_CCW);
00244
00245 glEnable(GL_DEPTH_TEST);
00246 glDepthFunc (GL_LESS);
00247
00248 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00249
00250 if (itsWireframe)
00251 {
00252 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00253 glLineWidth(1);
00254 }
00255 else
00256 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00257
00258 if (itsUseLights)
00259 setLights();
00260 else
00261 glDisable(GL_LIGHTING);
00262
00263
00264
00265 glViewport(0,0,itsScreenWidth,itsScreenHeight);
00266
00267
00268 glMatrixMode(GL_PROJECTION);
00269 glLoadMatrixd(itsProjMatrix);
00270
00271
00272 glMatrixMode (GL_MODELVIEW);
00273 glLoadIdentity();
00274
00275 if (itsUseExParam)
00276 {
00277 glLoadMatrixd( itsCameraExParam );
00278 } else {
00279 glLoadIdentity();
00280
00281 glRotatef (180, 1,0,0);
00282 glRotatef (itsCameraRotation.x, 1,0,0);
00283 glRotatef (itsCameraRotation.y, 0,1,0);
00284 glRotatef (-itsCameraRotation.z, 0,0,1);
00285 glTranslatef (-itsCameraPosition.x,-itsCameraPosition.y,-itsCameraPosition.z);
00286 }
00287
00288 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00289
00290 if (itsUseFeedback)
00291 {
00292 glFeedbackBuffer(itsFeedbackBufferSize, GL_2D, itsFeedbackBuffer);
00293 (void) glRenderMode(GL_FEEDBACK);
00294 }
00295
00296
00297 }
00298
00299 void ViewPort3D::initProjection()
00300 {
00301 glXMakeCurrent (itsDisplay,itsWin,itsCtx);
00302
00303
00304 glDrawBuffer(GL_BACK);
00305 glReadBuffer(GL_BACK);
00306
00307 glEnable(GL_TEXTURE_2D);
00308
00309
00310
00311 glViewport(0,0,itsScreenWidth,itsScreenHeight);
00312
00313
00314 glMatrixMode(GL_PROJECTION);
00315 glLoadIdentity();
00316 glOrtho(0.0,320,0.0,240, -1.0, 1.0);
00317
00318
00319
00320 glMatrixMode (GL_MODELVIEW);
00321 glLoadIdentity();
00322
00323 glClearColor(0, 0, 0, 0);
00324 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00325
00326 }
00327
00328
00329 void ViewPort3D::setLights()
00330 {
00331
00332 glEnable(GL_LIGHTING);
00333
00334
00335 GLfloat lModelAmbient[] = { 0.5, 0.5, 0.5, 1.0 };
00336 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lModelAmbient);
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 GLfloat LightAmbient[]= { 0.0f, 0.0f, 0.0f, 1.0f };
00350 GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
00351 GLfloat LightPosition[]= { 100.0f, 100.0f, 2.0f, 0.0f };
00352
00353 glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
00354 glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
00355 glLightfv(GL_LIGHT0, GL_POSITION,LightPosition);
00356 glEnable(GL_LIGHT0);
00357
00358 }
00359
00360 void ViewPort3D::setCamera ( const Point3D<float> pos,
00361 const Point3D<float> rot )
00362 {
00363
00364 itsCameraPosition = pos;
00365 itsCameraRotation = rot;
00366 }
00367
00368 void ViewPort3D::setCamera ( const double trans[3][4])
00369 {
00370 for(int j = 0; j < 3; j++ ) {
00371 for(int i = 0; i < 4; i++ ) {
00372 itsCameraExParam[i*4+j] = trans[j][i];
00373 }
00374 }
00375 itsCameraExParam[0*4+3] = itsCameraExParam[1*4+3] = itsCameraExParam[2*4+3] = 0.0;
00376 itsCameraExParam[3*4+3] = 1.0;
00377
00378 itsUseExParam = true;
00379
00380 }
00381
00382 Image<PixRGB<byte> > ViewPort3D::getFrame(){
00383
00384
00385
00386 glFlush();
00387 Image<PixRGB<byte> > retImg(itsScreenWidth, itsScreenHeight, NO_INIT);
00388 glPixelStorei(GL_PACK_ALIGNMENT,1);
00389 glReadBuffer(GL_BACK_LEFT);
00390 glReadPixels (0, 0, itsScreenWidth, itsScreenHeight,
00391 GL_RGB, GL_UNSIGNED_BYTE,
00392 (unsigned char*)retImg.getArrayPtr());
00393
00394 return retImg;
00395 }
00396
00397 Image<PixRGB<float> > ViewPort3D::getFrameFloat(){
00398
00399
00400
00401 glFlush();
00402 Image<PixRGB<float> > retImg(itsScreenWidth, itsScreenHeight, NO_INIT);
00403 glPixelStorei(GL_PACK_ALIGNMENT,1);
00404 glReadBuffer(GL_BACK_LEFT);
00405 glReadPixels (0, 0, itsScreenWidth, itsScreenHeight,
00406 GL_RGB, GL_FLOAT, retImg.getArrayPtr());
00407
00408 return retImg;
00409 }
00410
00411 Image<float> ViewPort3D::getDepthFrame(){
00412
00413
00414
00415 glFlush();
00416 Image<float> retImg(itsScreenWidth, itsScreenHeight, NO_INIT);
00417 glPixelStorei(GL_PACK_ALIGNMENT,1);
00418
00419 glReadPixels (0, 0, itsScreenWidth, itsScreenHeight,
00420 GL_DEPTH_COMPONENT, GL_FLOAT,
00421 (unsigned char*)retImg.getArrayPtr());
00422 return retImg;
00423 }
00424
00425 std::vector<ViewPort3D::Line> ViewPort3D::getFrameLines()
00426 {
00427 std::vector<Line> lines;
00428
00429 if (itsUseFeedback)
00430 {
00431 int size = glRenderMode(GL_RENDER);
00432
00433 if (size < 0)
00434 LFATAL("FeedbackBuffer too small, increase itsFeedbackSize");
00435
00436 int count = size;
00437 while (count) {
00438 float token = itsFeedbackBuffer[size-count]; count--;
00439
00440 if (token == GL_PASS_THROUGH_TOKEN) {
00441 LINFO("GL_PASS_THROUGH_TOKEN\n");
00442 LINFO(" %4.2f\n", itsFeedbackBuffer[size-count]);
00443 count--;
00444 if (count < 0) break;
00445 }
00446 else if (token == GL_POINT_TOKEN) {
00447 LINFO("GL_POINT_TOKEN\n");
00448 count -= 2;
00449 if (count < 0) break;
00450
00451 }
00452 else if (token == GL_LINE_TOKEN) {
00453 Line l;
00454 l.p1.i = itsFeedbackBuffer[size-count+0];
00455 l.p1.j = itsScreenHeight-itsFeedbackBuffer[size-count+1];
00456
00457 l.p2.i = itsFeedbackBuffer[size-count+2];
00458 l.p2.j = itsScreenHeight-itsFeedbackBuffer[size-count+3];
00459 count -= 4;
00460 if (count < 0) break;
00461
00462 lines.push_back(l);
00463
00464 }
00465 else if (token == GL_LINE_RESET_TOKEN) {
00466 Line l;
00467 l.p1.i = itsFeedbackBuffer[size-count+0];
00468 l.p1.j = itsScreenHeight-itsFeedbackBuffer[size-count+1];
00469
00470 l.p2.i = itsFeedbackBuffer[size-count+2];
00471 l.p2.j = itsScreenHeight-itsFeedbackBuffer[size-count+3];
00472 count -= 4;
00473 if (count < 0) break;
00474
00475 lines.push_back(l);
00476 }
00477 }
00478
00479
00480 } else {
00481 LFATAL("Need to enable feedback to use this function");
00482 }
00483
00484
00485 return lines;
00486 }
00487
00488
00489 Point3D<float> ViewPort3D::getPosition(Point3D<float> loc)
00490 {
00491 GLint viewport[4];
00492 GLdouble modelview[16];
00493 GLdouble projection[16];
00494 GLfloat winX, winY, winZ;
00495 GLdouble posX=0, posY=0, posZ=0;
00496
00497 glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
00498 glGetDoublev( GL_PROJECTION_MATRIX, projection );
00499 glGetIntegerv( GL_VIEWPORT, viewport );
00500
00501 winX = loc.x;
00502 winY = (float)viewport[3] - loc.y;
00503 winZ = loc.z;
00504
00505
00506
00507 #ifdef INVT_HAVE_LIBGLUT
00508 gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
00509 #else
00510 LFATAL("Need lib Glut fro this function");
00511 #endif
00512
00513 return Point3D<float>(posX, posY, posZ);
00514
00515 }
00516
00517 void ViewPort3D::setProjectionMatrix(float fovy, float aspect, float zmin, float zmax)
00518 {
00519
00520 glXMakeCurrent (itsDisplay,itsWin,itsCtx);
00521 glViewport(0,0,itsScreenWidth,itsScreenHeight);
00522 glMatrixMode(GL_PROJECTION);
00523 glLoadIdentity();
00524
00525 float xmin, xmax, ymin, ymax;
00526 ymax = zmin * tan(fovy * M_PI / 360.0);
00527 ymin = -ymax;
00528 xmin = ymin * aspect;
00529 xmax = ymax * aspect;
00530 glFrustum(xmin, xmax, ymin, ymax, zmin, zmax);
00531
00532
00533 glGetDoublev(GL_PROJECTION_MATRIX, itsProjMatrix);
00534
00535 }
00536
00537
00538 void ViewPort3D::setProjectionMatrix(const double cameraParam[3][4])
00539 {
00540
00541
00542 double icpara[3][4];
00543 double trans[3][4];
00544 double p[3][3], q[4][4];
00545 int i, j;
00546 double gnear = 0.1;
00547 double gfar = 5000;
00548
00549 if( paramDecompMat(cameraParam, icpara, trans) < 0 )
00550 LFATAL("Camera Parameter error!!\n");
00551
00552 for( i = 0; i < 3; i++ ) {
00553 for( j = 0; j < 3; j++ ) {
00554 p[i][j] = icpara[i][j] / icpara[2][2];
00555 }
00556 }
00557 q[0][0] = (2.0 * p[0][0] / itsScreenWidth);
00558 q[0][1] = (2.0 * p[0][1] / itsScreenWidth);
00559 q[0][2] = ((2.0 * p[0][2] / itsScreenWidth) - 1.0);
00560 q[0][3] = 0.0;
00561
00562 q[1][0] = 0.0;
00563 q[1][1] = (2.0 * p[1][1] / itsScreenHeight);
00564 q[1][2] = ((2.0 * p[1][2] / itsScreenHeight) - 1.0);
00565 q[1][3] = 0.0;
00566
00567 q[2][0] = 0.0;
00568 q[2][1] = 0.0;
00569 q[2][2] = (gfar + gnear)/(gfar - gnear);
00570 q[2][3] = -2.0 * gfar * gnear / (gfar - gnear);
00571
00572 q[3][0] = 0.0;
00573 q[3][1] = 0.0;
00574 q[3][2] = 1.0;
00575 q[3][3] = 0.0;
00576
00577 for( i = 0; i < 4; i++ ) {
00578 for( j = 0; j < 3; j++ ) {
00579 itsProjMatrix[i+j*4] = q[i][0] * trans[0][j]
00580 + q[i][1] * trans[1][j]
00581 + q[i][2] * trans[2][j];
00582 }
00583 itsProjMatrix[i+3*4] = q[i][0] * trans[0][3]
00584 + q[i][1] * trans[1][3]
00585 + q[i][2] * trans[2][3]
00586 + q[i][3];
00587 }
00588
00589 }
00590
00591 #define NORM(a,b,c) sqrt(a*a + b*b + c*c)
00592 #define DOT(a1,a2,a3,b1,b2,b3) (a1*b1 + a2*b2 + a3*b3)
00593
00594 int ViewPort3D::paramDecompMat(const double source[3][4],
00595 double cpara[3][4],
00596 double trans[3][4] )
00597 {
00598 int r, c;
00599 double Cpara[3][4];
00600 double rem1, rem2, rem3;
00601
00602 if( source[2][3] >= 0 ) {
00603 for( r = 0; r < 3; r++ ){
00604 for( c = 0; c < 4; c++ ){
00605 Cpara[r][c] = source[r][c];
00606 }
00607 }
00608 }
00609 else {
00610 for( r = 0; r < 3; r++ ){
00611 for( c = 0; c < 4; c++ ){
00612 Cpara[r][c] = -(source[r][c]);
00613 }
00614 }
00615 }
00616
00617 for( r = 0; r < 3; r++ ){
00618 for( c = 0; c < 4; c++ ){
00619 cpara[r][c] = 0.0;
00620 }
00621 }
00622 cpara[2][2] = NORM( Cpara[2][0], Cpara[2][1], Cpara[2][2] );
00623 trans[2][0] = Cpara[2][0] / cpara[2][2];
00624 trans[2][1] = Cpara[2][1] / cpara[2][2];
00625 trans[2][2] = Cpara[2][2] / cpara[2][2];
00626 trans[2][3] = Cpara[2][3] / cpara[2][2];
00627
00628 cpara[1][2] = DOT( trans[2][0], trans[2][1], trans[2][2],
00629 Cpara[1][0], Cpara[1][1], Cpara[1][2] );
00630 rem1 = Cpara[1][0] - cpara[1][2] * trans[2][0];
00631 rem2 = Cpara[1][1] - cpara[1][2] * trans[2][1];
00632 rem3 = Cpara[1][2] - cpara[1][2] * trans[2][2];
00633 cpara[1][1] = NORM( rem1, rem2, rem3 );
00634 trans[1][0] = rem1 / cpara[1][1];
00635 trans[1][1] = rem2 / cpara[1][1];
00636 trans[1][2] = rem3 / cpara[1][1];
00637
00638 cpara[0][2] = DOT( trans[2][0], trans[2][1], trans[2][2],
00639 Cpara[0][0], Cpara[0][1], Cpara[0][2] );
00640 cpara[0][1] = DOT( trans[1][0], trans[1][1], trans[1][2],
00641 Cpara[0][0], Cpara[0][1], Cpara[0][2] );
00642 rem1 = Cpara[0][0] - cpara[0][1]*trans[1][0] - cpara[0][2]*trans[2][0];
00643 rem2 = Cpara[0][1] - cpara[0][1]*trans[1][1] - cpara[0][2]*trans[2][1];
00644 rem3 = Cpara[0][2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];
00645 cpara[0][0] = NORM( rem1, rem2, rem3 );
00646 trans[0][0] = rem1 / cpara[0][0];
00647 trans[0][1] = rem2 / cpara[0][0];
00648 trans[0][2] = rem3 / cpara[0][0];
00649
00650 trans[1][3] = (Cpara[1][3] - cpara[1][2]*trans[2][3]) / cpara[1][1];
00651 trans[0][3] = (Cpara[0][3] - cpara[0][1]*trans[1][3]
00652 - cpara[0][2]*trans[2][3]) / cpara[0][0];
00653
00654 for( r = 0; r < 3; r++ ){
00655 for( c = 0; c < 3; c++ ){
00656 cpara[r][c] /= cpara[2][2];
00657 }
00658 }
00659
00660 return 0;
00661 }
00662
00663
00664
00665
00666 void ViewPort3D::setColor(const PixRGB<byte> color)
00667 {
00668
00669 float r = color[0]/256.0;
00670 float g = color[1]/256.0;
00671 float b = color[2]/256.0;
00672
00673 if (itsUseLights)
00674 {
00675 GLfloat light_ambient[4],light_diffuse[4],light_specular[4];
00676 light_ambient[0] = r*0.3f;
00677 light_ambient[1] = g*0.3f;
00678 light_ambient[2] = b*0.3f;
00679 light_ambient[3] = 1;
00680 light_diffuse[0] = r*0.7f;
00681 light_diffuse[1] = g*0.7f;
00682 light_diffuse[2] = b*0.7f;
00683 light_diffuse[3] = 1;
00684 light_specular[0] = r*0.2f;
00685 light_specular[1] = g*0.2f;
00686 light_specular[2] = b*0.2f;
00687 light_specular[3] = 1;
00688
00689 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient);
00690 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse);
00691 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular);
00692 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 50.0f);
00693 } else {
00694
00695 glColor3f(r,g,b);
00696 }
00697
00698 }
00699
00700 void ViewPort3D::drawGrid(Dims size, Dims step, float height)
00701 {
00702
00703 glPushMatrix();
00704
00705 glTranslatef(0, 0, 0);
00706 glRotatef(0, 1,0,0);
00707 glRotatef(0, 0,1,0);
00708 glRotatef(0, 0,0,1);
00709
00710 glBegin(GL_LINES);
00711
00712 for(float i=-size.w()/2; i<=size.w()/2; i+=step.w())
00713 {
00714 glVertex3f( -size.h()/2,i,height);
00715 glVertex3f( size.h()/2,i,height);
00716 }
00717
00718
00719 for(float i=-size.h()/2; i<=size.h()/2; i+=step.h())
00720 {
00721 glVertex3f(i, -size.w()/2,height);
00722 glVertex3f(i, size.w()/2,height);
00723 }
00724
00725 glEnd();
00726
00727 glPopMatrix();
00728
00729 }
00730
00731 void ViewPort3D::drawLine(const Point3D<float>& p1, const Point3D<float>& p2)
00732 {
00733 glPushMatrix();
00734
00735 glTranslatef(0, 0, 0);
00736 glRotatef(0, 1,0,0);
00737 glRotatef(0, 0,1,0);
00738 glRotatef(0, 0,0,1);
00739
00740 glBegin(GL_LINES);
00741 glVertex3f(p1.x, p1.y, p1.z);
00742 glVertex3f(p2.x, p2.y, p2.z);
00743 glEnd();
00744
00745 glPopMatrix();
00746
00747 }
00748
00749
00750 void ViewPort3D::drawRectangle(const Point3D<float> pos,
00751 const Point3D<float> rot,
00752 const float width, const float height,
00753 const PixRGB<byte> color)
00754 {
00755
00756 glPushMatrix();
00757 setColor(color);
00758
00759 glShadeModel (GL_FLAT);
00760
00761 glTranslatef(pos.x, pos.y, pos.z);
00762 glRotatef(rot.x, 1,0,0);
00763 glRotatef(rot.y, 0,1,0);
00764 glRotatef(rot.z, 0,0,1);
00765
00766 double lx = width*0.5f;
00767 double ly = height*0.5f;
00768
00769 glBegin(GL_QUADS);
00770 glNormal3f(0,0,1);
00771 glTexCoord2i(0, 0); glVertex3f( lx, ly, 0);
00772 glTexCoord2i(0, 1); glVertex3f(-lx, ly, 0);
00773 glTexCoord2i(1, 1); glVertex3f(-lx,-ly, 0);
00774 glTexCoord2i(1, 0); glVertex3f( lx,-ly, 0);
00775 glEnd();
00776
00777 glPopMatrix();
00778
00779 }
00780
00781
00782 void ViewPort3D::drawDisk(const Point3D<float> pos,
00783 const Point3D<float> rot,
00784 const float radius,
00785 const PixRGB<byte> color)
00786 {
00787 glPushMatrix();
00788 setColor(color);
00789 glShadeModel (GL_SMOOTH);
00790
00791 glTranslatef(pos.x, pos.y, pos.z);
00792 glRotatef(rot.x, 1,0,0);
00793 glRotatef(rot.y, 0,1,0);
00794 glRotatef(rot.z, 0,0,1);
00795
00796
00797 const int n = itsCylinderQuality*4;
00798
00799 double a = double(M_PI*2.0)/double(n);
00800 double sa = (double) sin(a);
00801 double ca = (double) cos(a);
00802
00803
00804 glShadeModel (GL_FLAT);
00805 double ny=1;
00806 double nz=0;
00807 glBegin (GL_TRIANGLE_FAN);
00808 glNormal3d (0,0,1);
00809 glVertex3d (0,0,0);
00810 for (int i=0; i<=n; i++) {
00811 glVertex3d (ny*radius,nz*radius,0);
00812
00813
00814 double tmp = ca*ny - sa*nz;
00815 nz = sa*ny + ca*nz;
00816 ny = tmp;
00817 }
00818 glEnd();
00819
00820 glPopMatrix();
00821 }
00822
00823 void ViewPort3D::drawCircle(const Point3D<float> pos,
00824 const Point3D<float> rot,
00825 const float radius,
00826 const PixRGB<byte> color)
00827 {
00828 glPushMatrix();
00829 setColor(color);
00830 glShadeModel (GL_SMOOTH);
00831
00832 glTranslatef(pos.x, pos.y, pos.z);
00833 glRotatef(rot.x, 1,0,0);
00834 glRotatef(rot.y, 0,1,0);
00835 glRotatef(rot.z, 0,0,1);
00836
00837
00838 const int n = itsCylinderQuality*4;
00839
00840 double a = double(M_PI*2.0)/double(n);
00841 double sa = (double) sin(a);
00842 double ca = (double) cos(a);
00843
00844
00845 double ny=1;
00846 double nz=0;
00847 glBegin(GL_LINE_LOOP);
00848 for(int i=0; i<=n; i++)
00849 {
00850 glVertex3d( ny*radius, nz*radius,0);
00851
00852 double tmp = ca*ny - sa*nz;
00853 nz = sa*ny + ca*nz;
00854 ny = tmp;
00855 }
00856
00857 glEnd();
00858
00859 glPopMatrix();
00860 }
00861
00862 void ViewPort3D::drawEllipse(const Point3D<float> pos,
00863 const Point3D<float> rot,
00864 const float radiusX, const float radiusY,
00865 const PixRGB<byte> color)
00866 {
00867 glPushMatrix();
00868 setColor(color);
00869 glShadeModel (GL_SMOOTH);
00870
00871 glTranslatef(pos.x, pos.y, pos.z);
00872 glRotatef(rot.x, 1,0,0);
00873 glRotatef(rot.y, 0,1,0);
00874 glRotatef(rot.z, 0,0,1);
00875
00876
00877 const int n = itsCylinderQuality*4;
00878
00879 double a = double(M_PI*2.0)/double(n);
00880 double sa = (double) sin(a);
00881 double ca = (double) cos(a);
00882
00883
00884 double ny=1;
00885 double nz=0;
00886 glBegin(GL_LINE_LOOP);
00887 for(int i=0; i<=n; i++)
00888 {
00889 glVertex3d( ny*radiusX, nz*radiusY,0);
00890
00891 double tmp = ca*ny - sa*nz;
00892 nz = sa*ny + ca*nz;
00893 ny = tmp;
00894 }
00895
00896 glEnd();
00897
00898 glPopMatrix();
00899 }
00900
00901
00902 void ViewPort3D::drawBox(const Point3D<float> pos,
00903 const Point3D<float> rot,
00904 const Point3D<float> size,
00905 const PixRGB<byte> color)
00906 {
00907
00908 glPushMatrix();
00909 setColor(color);
00910
00911 glShadeModel (GL_FLAT);
00912
00913 glTranslatef(pos.x, pos.y, pos.z);
00914 glRotatef(rot.x, 1,0,0);
00915 glRotatef(rot.y, 0,1,0);
00916 glRotatef(rot.z, 0,0,1);
00917
00918 double lx = size.x*0.5f;
00919 double ly = size.y*0.5f;
00920 double lz = size.z*0.5f;
00921
00922 glBegin(GL_QUADS);
00923 glNormal3f(0,1,0);
00924 glTexCoord2i(0, 0); glVertex3f( lx, ly,-lz);
00925 glTexCoord2i(0, 1); glVertex3f(-lx, ly,-lz);
00926 glTexCoord2i(1, 1); glVertex3f(-lx, ly, lz);
00927 glTexCoord2i(1, 0); glVertex3f( lx, ly, lz);
00928
00929 glNormal3f(0,-1,0);
00930 glTexCoord2i(0, 0); glVertex3f( lx,-ly, lz);
00931 glTexCoord2i(0, 1); glVertex3f(-lx,-ly, lz);
00932 glTexCoord2i(1, 1); glVertex3f(-lx,-ly,-lz);
00933 glTexCoord2i(1, 0); glVertex3f( lx,-ly,-lz);
00934
00935 glNormal3f(0,0,1);
00936 glTexCoord2i(0, 0); glVertex3f( lx, ly, lz);
00937 glTexCoord2i(0, 1); glVertex3f(-lx, ly, lz);
00938 glTexCoord2i(1, 1); glVertex3f(-lx,-ly, lz);
00939 glTexCoord2i(1, 0); glVertex3f( lx,-ly, lz);
00940
00941 glNormal3f(0,0,-1);
00942 glTexCoord2i(0, 0); glVertex3f( lx,-ly,-lz);
00943 glTexCoord2i(0, 1); glVertex3f(-lx,-ly,-lz);
00944 glTexCoord2i(1, 1); glVertex3f(-lx, ly,-lz);
00945 glTexCoord2i(1, 0); glVertex3f( lx, ly,-lz);
00946
00947 glNormal3f(-1,0,0);
00948 glTexCoord2i(0, 0); glVertex3f(-lx, ly, lz);
00949 glTexCoord2i(0, 1); glVertex3f(-lx, ly,-lz);
00950 glTexCoord2i(1, 1); glVertex3f(-lx,-ly,-lz);
00951 glTexCoord2i(1, 0); glVertex3f(-lx,-ly, lz);
00952
00953 glNormal3f(1,0,0);
00954 glTexCoord2i(0, 0); glVertex3f( lx, ly,-lz);
00955 glTexCoord2i(0, 1); glVertex3f( lx, ly, lz);
00956 glTexCoord2i(1, 1); glVertex3f( lx,-ly, lz);
00957 glTexCoord2i(1, 0); glVertex3f( lx,-ly,-lz);
00958 glEnd();
00959
00960 glPopMatrix();
00961
00962 }
00963
00964 void ViewPort3D::drawSphere(const Point3D<float> pos,
00965 const Point3D<float> rot,
00966 const Point3D<float> size,
00967 const PixRGB<byte> color)
00968 {
00969
00970 glPushMatrix();
00971
00972 setColor(color);
00973
00974
00975
00976
00977 glEnable (GL_NORMALIZE);
00978
00979 glShadeModel (GL_SMOOTH);
00980
00981 glTranslatef(pos.x, pos.y, pos.z);
00982 glRotatef(rot.x, 1,0,0);
00983 glRotatef(rot.y, 0,1,0);
00984 glRotatef(rot.z, 0,0,1);
00985 glScaled (size.x,size.y,size.z);
00986
00987
00988 if (itsSphereListNum == 0)
00989 itsSphereListNum = generateSphere(itsSphereQuality);
00990
00991 if (itsSphereListNum != 0)
00992 glCallList (itsSphereListNum);
00993
00994 glDisable (GL_NORMALIZE);
00995
00996 glPopMatrix();
00997 }
00998
00999 uint ViewPort3D::generateSphere(int quality)
01000 {
01001
01002
01003 # define ICX 0.525731112119133606f
01004 # define ICZ 0.850650808352039932f
01005 static GLdouble idata[12][3] = {
01006 {-ICX, 0, ICZ},
01007 {ICX, 0, ICZ},
01008 {-ICX, 0, -ICZ},
01009 {ICX, 0, -ICZ},
01010 {0, ICZ, ICX},
01011 {0, ICZ, -ICX},
01012 {0, -ICZ, ICX},
01013 {0, -ICZ, -ICX},
01014 {ICZ, ICX, 0},
01015 {-ICZ, ICX, 0},
01016 {ICZ, -ICX, 0},
01017 {-ICZ, -ICX, 0}
01018 };
01019
01020 static int index[20][3] = {
01021 {0, 4, 1}, {0, 9, 4},
01022 {9, 5, 4}, {4, 5, 8},
01023 {4, 8, 1}, {8, 10, 1},
01024 {8, 3, 10}, {5, 3, 8},
01025 {5, 2, 3}, {2, 7, 3},
01026 {7, 10, 3}, {7, 6, 10},
01027 {7, 11, 6}, {11, 0, 6},
01028 {0, 1, 6}, {6, 1, 10},
01029 {9, 0, 11}, {9, 11, 2},
01030 {9, 2, 5}, {7, 2, 11},
01031 };
01032
01033 uint listnum = glGenLists (1);
01034 glNewList (listnum,GL_COMPILE);
01035 glBegin (GL_TRIANGLES);
01036 for (int i=0; i<20; i++) {
01037 drawPatch (&idata[index[i][2]][0],&idata[index[i][1]][0],
01038 &idata[index[i][0]][0],quality);
01039 }
01040 glEnd();
01041 glEndList();
01042
01043 return listnum;
01044
01045 }
01046
01047 void ViewPort3D::drawPatch (double p1[3], double p2[3], double p3[3], int level)
01048 {
01049 int i;
01050 if (level > 0) {
01051 double q1[3],q2[3],q3[3];
01052 for (i=0; i<3; i++) {
01053 q1[i] = 0.5f*(p1[i]+p2[i]);
01054 q2[i] = 0.5f*(p2[i]+p3[i]);
01055 q3[i] = 0.5f*(p3[i]+p1[i]);
01056 }
01057 double length1 = (double)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2]));
01058 double length2 = (double)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2]));
01059 double length3 = (double)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2]));
01060 for (i=0; i<3; i++) {
01061 q1[i] *= length1;
01062 q2[i] *= length2;
01063 q3[i] *= length3;
01064 }
01065 drawPatch (p1,q1,q3,level-1);
01066 drawPatch (q1,p2,q2,level-1);
01067 drawPatch (q1,q2,q3,level-1);
01068 drawPatch (q3,q2,p3,level-1);
01069 }
01070 else {
01071 glNormal3f (p1[0],p1[1],p1[2]);
01072 glVertex3f (p1[0],p1[1],p1[2]);
01073 glNormal3f (p2[0],p2[1],p2[2]);
01074 glVertex3f (p2[0],p2[1],p2[2]);
01075 glNormal3f (p3[0],p3[1],p3[2]);
01076 glVertex3f (p3[0],p3[1],p3[2]);
01077 }
01078 }
01079
01080 void ViewPort3D::drawCappedCylinder(const Point3D<float> pos,
01081 const Point3D<float> rot,
01082 const float radius,
01083 const float length,
01084 const PixRGB<byte> color)
01085 {
01086
01087 glPushMatrix();
01088
01089 setColor(color);
01090
01091 glShadeModel (GL_SMOOTH);
01092
01093 glTranslatef(pos.x, pos.y, pos.z);
01094 glRotatef(rot.x, 1,0,0);
01095 glRotatef(rot.y, 0,1,0);
01096 glRotatef(rot.z, 0,0,1);
01097
01098
01099 const int n = itsCylinderQuality*4;
01100
01101 float halfLength = length * 0.5;
01102
01103 double a = double(M_PI*2.0)/double(n);
01104 double sa = (double) sin(a);
01105 double ca = (double) cos(a);
01106
01107
01108 double ny=1, nz=0;
01109 glBegin (GL_TRIANGLE_STRIP);
01110 for (int i=0; i<=n; i++) {
01111 glNormal3d (ny,nz,0);
01112 glVertex3d (ny*radius,nz*radius,halfLength);
01113 glNormal3d (ny,nz,0);
01114 glVertex3d (ny*radius,nz*radius,-halfLength);
01115
01116 double tmp = ca*ny - sa*nz;
01117 nz = sa*ny + ca*nz;
01118 ny = tmp;
01119 }
01120 glEnd();
01121
01122
01123 double start_nx = 0;
01124 double start_ny = 1;
01125 for (int j=0; j<(n/4); j++) {
01126
01127 double start_nx2 = ca*start_nx + sa*start_ny;
01128 double start_ny2 = -sa*start_nx + ca*start_ny;
01129
01130 double nx = start_nx, ny = start_ny, nz = 0;
01131 double nx2 = start_nx2, ny2 = start_ny2, nz2 = 0;
01132 glBegin (GL_TRIANGLE_STRIP);
01133 for (int i=0; i<=n; i++) {
01134 glNormal3d (ny2,nz2,nx2);
01135 glVertex3d (ny2*radius,nz2*radius,halfLength+nx2*radius);
01136 glNormal3d (ny,nz,nx);
01137 glVertex3d (ny*radius,nz*radius,halfLength+nx*radius);
01138
01139 double tmp = ca*ny - sa*nz;
01140 nz = sa*ny + ca*nz;
01141 ny = tmp;
01142 tmp = ca*ny2- sa*nz2;
01143 nz2 = sa*ny2 + ca*nz2;
01144 ny2 = tmp;
01145 }
01146 glEnd();
01147 start_nx = start_nx2;
01148 start_ny = start_ny2;
01149 }
01150
01151
01152 start_nx = 0;
01153 start_ny = 1;
01154 for (int j=0; j<(n/4); j++) {
01155
01156 double start_nx2 = ca*start_nx - sa*start_ny;
01157 double start_ny2 = sa*start_nx + ca*start_ny;
01158
01159 double nx = start_nx, ny = start_ny, nz = 0;
01160 double nx2 = start_nx2, ny2 = start_ny2, nz2 = 0;
01161 glBegin (GL_TRIANGLE_STRIP);
01162 for (int i=0; i<=n; i++) {
01163 glNormal3d (ny,nz,nx);
01164 glVertex3d (ny*radius,nz*radius,-halfLength+nx*radius);
01165 glNormal3d (ny2,nz2,nx2);
01166 glVertex3d (ny2*radius,nz2*radius,-halfLength+nx2*radius);
01167
01168 double tmp = ca*ny - sa*nz;
01169 nz = sa*ny + ca*nz;
01170 ny = tmp;
01171 tmp = ca*ny2- sa*nz2;
01172 nz2 = sa*ny2 + ca*nz2;
01173 ny2 = tmp;
01174 }
01175 glEnd();
01176 start_nx = start_nx2;
01177 start_ny = start_ny2;
01178 }
01179
01180 glPopMatrix();
01181 }
01182
01183 void ViewPort3D::drawCylinder(const Point3D<float> pos,
01184 const Point3D<float> rot,
01185 const float radius,
01186 const float length,
01187 const PixRGB<byte> color)
01188 {
01189
01190 glPushMatrix();
01191
01192 setColor(color);
01193
01194 glShadeModel (GL_SMOOTH);
01195
01196 glTranslatef(pos.x, pos.y, pos.z);
01197 glRotatef(rot.x, 1,0,0);
01198 glRotatef(rot.y, 0,1,0);
01199 glRotatef(rot.z, 0,0,1);
01200
01201
01202 const int n = itsCylinderQuality*4;
01203
01204 float halfLength = length * 0.5;
01205
01206 double a = double(M_PI*2.0)/double(n);
01207 double sa = (double) sin(a);
01208 double ca = (double) cos(a);
01209
01210
01211 double ny=1, nz=0;
01212 glBegin (GL_TRIANGLE_STRIP);
01213 for (int i=0; i<=n; i++) {
01214 glNormal3d (ny,nz,0);
01215 glVertex3d (ny*radius,nz*radius,halfLength);
01216 glNormal3d (ny,nz,0);
01217 glVertex3d (ny*radius,nz*radius,-halfLength);
01218
01219 double tmp = ca*ny - sa*nz;
01220 nz = sa*ny + ca*nz;
01221 ny = tmp;
01222 }
01223 glEnd();
01224
01225
01226 glShadeModel (GL_FLAT);
01227 ny=1, nz=0;
01228 glBegin (GL_TRIANGLE_FAN);
01229 glNormal3d (0,0,1);
01230 glVertex3d (0,0,halfLength);
01231 for (int i=0; i<=n; i++) {
01232
01233
01234 glNormal3d (0,0,1);
01235 glVertex3d (ny*radius,nz*radius,halfLength);
01236
01237
01238
01239
01240 double tmp = ca*ny - sa*nz;
01241 nz = sa*ny + ca*nz;
01242 ny = tmp;
01243 }
01244 glEnd();
01245
01246
01247 ny=1; nz=0;
01248 glBegin (GL_TRIANGLE_FAN);
01249 glNormal3d (0,0,-1);
01250 glVertex3d (0,0,-halfLength);
01251 for (int i=0; i<=n; i++) {
01252
01253
01254 glNormal3d (0,0,-1);
01255 glVertex3d (ny*radius,nz*radius,-halfLength);
01256
01257
01258
01259
01260 double tmp = ca*ny + sa*nz;
01261 nz = -sa*ny + ca*nz;
01262 ny = tmp;
01263 }
01264 glEnd();
01265
01266
01267 glPopMatrix();
01268 }
01269
01270 void ViewPort3D::drawCone(const Point3D<float> pos,
01271 const Point3D<float> rot,
01272 const float radius,
01273 const float length,
01274 const PixRGB<byte> color)
01275 {
01276
01277 glPushMatrix();
01278
01279 setColor(color);
01280
01281 glShadeModel (GL_SMOOTH);
01282
01283 glTranslatef(pos.x, pos.y, pos.z);
01284 glRotatef(rot.x, 1,0,0);
01285 glRotatef(rot.y, 0,1,0);
01286 glRotatef(rot.z, 0,0,1);
01287
01288
01289 const int n = itsCylinderQuality*4;
01290
01291 float halfLength = length * 0.5;
01292
01293 double a = double(M_PI*2.0)/double(n);
01294 double sa = (double) sin(a);
01295 double ca = (double) cos(a);
01296
01297 glShadeModel (GL_FLAT);
01298
01299 glFrontFace(GL_CW);
01300
01301 double ny=1; double nz=0;
01302 glBegin (GL_TRIANGLE_FAN);
01303 glNormal3d (0,0,1);
01304 glVertex3d (0,0,-halfLength);
01305 for (int i=0; i<=n; i++) {
01306 glNormal3d (0,0,1);
01307 glVertex3d (ny*radius,nz*radius,-halfLength);
01308
01309 double tmp = ca*ny + sa*nz;
01310 nz = -sa*ny + ca*nz;
01311 ny = tmp;
01312 }
01313 glEnd();
01314
01315 glFrontFace(GL_CCW);
01316
01317 ny=1; nz=0;
01318 glBegin (GL_TRIANGLE_FAN);
01319 glNormal3d (0,0,-1);
01320 glVertex3d (0,0,halfLength);
01321 for (int i=0; i<=n; i++) {
01322 glNormal3d (ny,nz,0);
01323 glVertex3d (ny*radius,nz*radius,-halfLength);
01324
01325 double tmp = ca*ny + sa*nz;
01326 nz = -sa*ny + ca*nz;
01327 ny = tmp;
01328 }
01329 glEnd();
01330
01331 glPopMatrix();
01332 }
01333
01334
01335 void ViewPort3D::drawGround(const Point2D<float> size, const PixRGB<byte> color)
01336 {
01337
01338 glPushMatrix();
01339 setColor(color);
01340 glShadeModel (GL_FLAT);
01341 glTranslatef(0, 0, 0);
01342
01343 glBegin(GL_QUADS);
01344
01345 glNormal3f(0,0,1);
01346 glVertex3f( size.i, size.j, 0);
01347 glVertex3f(-size.i, size.j, 0);
01348 glVertex3f(-size.i,-size.j, 0);
01349 glVertex3f( size.i,-size.j, 0);
01350
01351 glEnd();
01352
01353 glPopMatrix();
01354
01355 }
01356
01357
01358
01359
01360 void ViewPort3D::drawExtrudedContour(const std::vector<Point2D<float> >& contour,
01361 const Point3D<float> pos,
01362 const Point3D<float> rot,
01363 const float thickness,
01364 const PixRGB<byte> color)
01365 {
01366 std::vector<Point2D<float> > triangles = triangulate(contour);
01367
01368 glPushMatrix();
01369 setColor(color);
01370
01371 glShadeModel (GL_SMOOTH);
01372
01373 glTranslatef(pos.x, pos.y, pos.z);
01374 glRotatef(rot.x, 1,0,0);
01375 glRotatef(rot.y, 0,1,0);
01376 glRotatef(rot.z, 0,0,1);
01377
01378
01379 glFrontFace(GL_CW);
01380 glBegin(GL_TRIANGLES);
01381 glNormal3f(0,0,-1);
01382 for(uint i=0; i<triangles.size(); i++)
01383 {
01384 glVertex3f(triangles[i].i, triangles[i].j,-thickness/2);
01385 }
01386 glEnd();
01387
01388 glBegin(GL_QUAD_STRIP);
01389 uint numPoints = contour.size();
01390 for(uint i=0; i<numPoints; i++)
01391 {
01392 glVertex3f(contour[i].i, contour[i].j,-thickness/2);
01393 glVertex3f(contour[i].i, contour[i].j,thickness/2);
01394 glVertex3f(contour[(i+1)%numPoints].i, contour[(i+1)%numPoints].j,-thickness/2);
01395 glVertex3f(contour[(i+1)%numPoints].i, contour[(i+1)%numPoints].j,thickness/2);
01396
01397 double dx = contour[(i+1)%numPoints].j - contour[i].j;
01398 double dy = contour[i].i - contour[(i+1)%numPoints].i;
01399 double len = sqrt(dx * dx + dy * dy);
01400 glNormal3f(dx / len, dy / len, 0.0);
01401 }
01402 glEnd();
01403
01404 glFrontFace(GL_CCW);
01405
01406 glBegin(GL_TRIANGLES);
01407 glNormal3f(0,0,1);
01408 for(uint i=0; i<triangles.size(); i++)
01409 {
01410
01411 glVertex3f(triangles[i].i, triangles[i].j, thickness/2);
01412 }
01413 glEnd();
01414
01415 glPopMatrix();
01416 }
01417
01418
01419 bool ViewPort3D::snip(const std::vector<Point2D<float> > &contour,
01420 int u,int v,int w,int n,int *V)
01421 {
01422
01423 Point2D<float> A = contour[V[u]];
01424 Point2D<float> B = contour[V[v]];
01425 Point2D<float> C = contour[V[w]];
01426
01427 const float EPSILON=0.0000000001f;
01428
01429 if ( EPSILON > (((B.i-A.i)*(C.j-A.j)) - ((B.j-A.j)*(C.i-A.i))) ) return false;
01430
01431 for (int p=0;p<n;p++)
01432 {
01433 if( (p == u) || (p == v) || (p == w) ) continue;
01434 Point2D<float> P = contour[V[p]];
01435 if (pnTriangle(A,B,C,P)) return false;
01436 }
01437
01438 return true;
01439 }
01440
01441
01442
01443 std::vector<Point2D<float> > ViewPort3D::triangulate(const std::vector<Point2D<float> >& contour)
01444 {
01445 std::vector<Point2D<float> > result;
01446
01447 int n = contour.size();
01448 if ( n < 3 ) return result;
01449
01450 int *V = new int[n];
01451
01452
01453
01454 if ( 0.0f < area(contour) )
01455 for (int v=0; v<n; v++) V[v] = v;
01456 else
01457 for(int v=0; v<n; v++) V[v] = (n-1)-v;
01458
01459 int nv = n;
01460
01461
01462 int count = 2*nv;
01463
01464 for(int m=0, v=nv-1; nv>2; )
01465 {
01466
01467 if (0 >= (count--))
01468 {
01469
01470 return result;
01471 }
01472
01473
01474 int u = v ; if (nv <= u) u = 0;
01475 v = u+1; if (nv <= v) v = 0;
01476 int w = v+1; if (nv <= w) w = 0;
01477
01478 if ( snip(contour,u,v,w,nv,V) )
01479 {
01480 int a,b,c,s,t;
01481
01482
01483 a = V[u]; b = V[v]; c = V[w];
01484
01485
01486 result.push_back( contour[a] );
01487 result.push_back( contour[b] );
01488 result.push_back( contour[c] );
01489
01490 m++;
01491
01492
01493 for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;
01494
01495
01496 count = 2*nv;
01497 }
01498 }
01499
01500 delete V;
01501
01502 return result;
01503
01504 }
01505
01506 uint ViewPort3D::addTexture(const Image<PixRGB<byte> >& textureImg)
01507 {
01508 uint texId;
01509 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01510
01511 glGenTextures(1, &texId);
01512 glBindTexture(GL_TEXTURE_2D, texId);
01513
01514 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01515 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01516 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01517 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01518
01519
01520
01521
01522
01523
01524
01525 unsigned char* arrayPtr = const_cast<unsigned char*>
01526 (reinterpret_cast<const unsigned char*> (textureImg.getArrayPtr()));
01527 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
01528 textureImg.getWidth(), textureImg.getHeight(),
01529 0, GL_RGB, GL_UNSIGNED_BYTE,
01530 arrayPtr);
01531
01532 return texId;
01533
01534 }
01535
01536 uint ViewPort3D::addTexture(const Image<float>& textureImg)
01537 {
01538 uint texId;
01539 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01540
01541 glGenTextures(1, &texId);
01542 glBindTexture(GL_TEXTURE_2D, texId);
01543
01544 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01545 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01548
01549
01550
01551
01552
01553
01554
01555 unsigned char* arrayPtr = const_cast<unsigned char*>
01556 (reinterpret_cast<const unsigned char*> (textureImg.getArrayPtr()));
01557 glTexImage2D(GL_TEXTURE_2D, 0, GL_FLOAT,
01558 textureImg.getWidth(), textureImg.getHeight(),
01559 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
01560 arrayPtr);
01561
01562 return texId;
01563
01564 }
01565
01566 void ViewPort3D::loadTexture(const Image<PixRGB<byte> >& textureImg, uint texId)
01567 {
01568 glBindTexture(GL_TEXTURE_2D, texId);
01569
01570 unsigned char* arrayPtr = const_cast<unsigned char*>
01571 (reinterpret_cast<const unsigned char*> (textureImg.getArrayPtr()));
01572 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
01573 textureImg.getWidth(), textureImg.getHeight(),
01574 0, GL_RGB, GL_UNSIGNED_BYTE,
01575 arrayPtr);
01576
01577 }
01578
01579
01580 void ViewPort3D::bindTexture(const uint texId)
01581 {
01582 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
01583 glBindTexture(GL_TEXTURE_2D, texId);
01584
01585 }
01586
01587 #ifdef HAVE_GL_GLEW_H
01588
01589 void ViewPort3D::printInfoLog(GLhandleARB obj)
01590 {
01591 int infologLength = 0;
01592 int charsWritten = 0;
01593 char *infoLog;
01594
01595 glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
01596 &infologLength);
01597
01598 if (infologLength > 0)
01599 {
01600 infoLog = (char *)malloc(infologLength);
01601 glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
01602 LINFO("%s",infoLog);
01603 free(infoLog);
01604 }
01605
01606
01607 }
01608
01609 GLhandleARB ViewPort3D::createShader(const char *prog, int type)
01610 {
01611
01612 if (!itsInitGlew)
01613 {
01614 glewInit();
01615 if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
01616 LINFO("Ready for GLSL\n");
01617 else
01618 LFATAL("No GLSL support\n");
01619 itsInitGlew=true;
01620 }
01621
01622
01623
01624
01625 FILE *fp = fopen(prog, "rt");
01626 if (fp == NULL)
01627 LFATAL("Can not find shader program %s", prog);
01628
01629
01630 fseek(fp, 0, SEEK_END);
01631 int count = ftell(fp);
01632 rewind(fp);
01633
01634 char* progContent = NULL;
01635 if (count > 0)
01636 {
01637 progContent = (char *)malloc(sizeof(char) * (count+1));
01638 count = fread(progContent, sizeof(char), count, fp);
01639 progContent[count] = '\0';
01640 }
01641 fclose(fp);
01642
01643 if (progContent == NULL)
01644 LFATAL("Can not load program");
01645
01646 GLhandleARB h;
01647
01648 h = glCreateShaderObjectARB(type);
01649
01650 LINFO("Add program\n");
01651 glShaderSourceARB(h, 1, (const char**)&progContent,NULL);
01652 LINFO("Done");
01653
01654 glCompileShaderARB(h);
01655
01656 LINFO("Compiling Shader");
01657 printInfoLog(h);
01658
01659 GLhandleARB p = glCreateProgramObjectARB();
01660 glAttachObjectARB(p,h);
01661 glLinkProgramARB(p);
01662 printInfoLog(p);
01663 glUseProgramObjectARB(p);
01664
01665 return p;
01666 }
01667
01668 void ViewPort3D::progToTexture(const GLhandleARB prog, const int texId)
01669
01670 {
01671 glUseProgramObjectARB(prog);
01672 initProjection();
01673 glBegin(GL_QUADS);
01674 glTexCoord2f(0.0, 0.0); glVertex3f(0, 0, 0);
01675 glTexCoord2f(1.0, 0.0); glVertex3f(320, 0, 0);
01676 glTexCoord2f(1.0, 1.0); glVertex3f(320, 240 , 0);
01677 glTexCoord2f(0.0, 1.0); glVertex3f(0, 240, 0);
01678 glEnd();
01679
01680 glFlush();
01681 if (texId != -1)
01682 glBindTexture(GL_TEXTURE_2D, texId);
01683 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, 320-10,240-10);
01684
01685
01686 }
01687
01688 #endif
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700 #endif
01701