#include #include #ifdef __APPLE_CC__ #include #else #include #endif #include "Vxx_Fnc.hpp" #include "i_Define.hxx" #include "i_Debug.hxx" #include "i_RadDeg.hxx" #include "Vector.hxx" #include "i_v_type.hxx" GLdouble vertex[][3] = { { 0.0, 0.0, 0.0 }, { 4.0, 0.0, 0.0 }, { 4.0, 8.0, 0.0 }, { 0.0, 8.0, 0.0 }, { 0.0, 0.0, 6.0 }, { 4.0, 0.0, 6.0 }, { 4.0, 8.0, 6.0 }, { 0.0, 8.0, 6.0 } }; int edge[][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }; int face[][4] = { { 0, 1, 2, 3 }, { 1, 5, 6, 2 }, { 5, 4, 7, 6 }, { 4, 0, 3, 7 }, { 4, 5, 1, 0 }, { 3, 2, 6, 7 } }; GLdouble normal[][3] = { { 0.0, 0.0,-1.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, {-1.0, 0.0, 0.0 }, { 0.0,-1.0, 0.0 }, { 0.0, 1.0, 0.0 } }; Vd3 EP(7.,-10.,6) ; // Eye Vd3 TP(2,5,3) ; // Target Vd3 Up(0,0,1) ; // Up Vd2 Anchor(-1) ; // Eye Drag Start Vd3 LastEP ; int SelIndex(-1) ; GLuint SelDepth(0) ; v_long NearIndex ; Vd3 SelPoint(0) ; void cuboid (GLfloat* color) { { ::glEnable(GL_LIGHTING); ::glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color) ; ::glBegin(GL_QUADS); for (int j = 0; j < 6; ++j) { ::glNormal3dv(normal[j]); for (int i = 0; i < 4; ++i) { ::glVertex3dv(vertex[face[j][i]]); } } ::glEnd(); } { ::glDisable(GL_LIGHTING); ::glColor4fv(color) ; ::glBegin(GL_LINES); for (int i = 0; i < 12; ++i) { ::glVertex3dv(vertex[edge[i][0]]); ::glVertex3dv(vertex[edge[i][1]]); } ::glEnd(); } } void draw (void) { GLint mode = 0 ; ::glGetIntegerv(GL_RENDER_MODE,&mode) ; { if (mode == GL_SELECT) { ::glInitNames(); ::glPushName(-1); } } int nameIndex = 0 ; int cntMax = 5 ; for (int z=0 ; z= 0) if (SelPoint != Vd3(0)) { GLfloat color[4] ; color[0] = color[1] = 0.1 ; color[2] = color[3] = 1 ; ::glPointSize(10) ; ::glColor4fv(color) ; ::glBegin(GL_POINTS) ; ::glVertex3f(SelPoint.x,SelPoint.y,SelPoint.z) ; ::glEnd() ; ::glBegin(GL_LINES) ; ::glVertex3f(SelPoint.x,SelPoint.y,SelPoint.z) ; ::glVertex3f(TP.x,TP.y,TP.z) ; ::glEnd() ; } { GLfloat color[4] ; color[0] = color[2] = 0.1 ; color[1] = color[3] = 1 ; ::glPointSize(10) ; ::glColor4fv(color) ; ::glBegin(GL_LINES) ; ::glVertex3d(-30,0.0,0.0) ; ::glVertex3d( 30,0.0,0.0); ::glVertex3d(0.0,-30,0.0) ; ::glVertex3d(0.0, 30,0.0); ::glVertex3d(0.0,0.0,-30) ; ::glVertex3d(0.0,0.0, 30); ::glEnd() ; } } } void idle (void) { ::glutPostRedisplay(); } void Perspective (void) { // ::glMatrixMode(GL_PROJECTION); // ::glLoadIdentity(); double w = ::glutGet(GLUT_WINDOW_WIDTH) ; double h = ::glutGet(GLUT_WINDOW_HEIGHT) ; ::gluPerspective(30.0, (double)w / (double)h, 1.0, 1000.0); } void LookAt (void) { { Vd3 ep = EP ; ep.Normalize() ; ep *= 100 ; EP = ep ; } ::glMatrixMode(GL_MODELVIEW); ::glLoadIdentity(); // #ifndef _DEBUG ::gluLookAt(EP.x,EP.y,EP.z,TP.x,TP.y,TP.z,Up.x,Up.y,Up.z); // #endif } void display (void) { ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); LookAt() ; ::draw() ; ::glutSwapBuffers() ; } void resize (int w, int h) { ::glViewport(0, 0, w, h); ::glMatrixMode(GL_PROJECTION); ::glLoadIdentity(); Perspective() ; } void processHits (GLint hits, GLuint buffer[]) { unsigned int i, j; GLuint ii, jj, names, *ptr; ptr = (GLuint *) buffer; // GLuint depth = 0xffffffff ; SelIndex = -1 ; SelDepth = 0xffffffff ; NearIndex.clear() ; if (hits > 0) { printf ("\nhits = %d\n", hits); for (i = 0; i < hits; i++) { /* for each hit */ names = *ptr; // printf (" number of names for this hit = %d\n", names); ptr++; GLuint dMin = *ptr ; printf(" z1 is %g;", (float) *ptr/0x7fffffff); ptr++; GLuint dMax = *ptr ; printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++; printf (" names are "); NearIndex.push_back(*ptr) ; if (SelDepth > dMin) { SelIndex = *ptr ; SelDepth = dMin ; } for (j = 0; j < names; j++) { /* for each name */ printf ("%d ", *ptr); if (j == 0) /* set row and column */ ii = *ptr; else if (j == 1) jj = *ptr; ptr++; } printf ("\n"); // board[ii][jj] = (board[ii][jj] + 1) % 3; } std::tout<< _T("Select=") << SelIndex << std::endl << std::endl ; } } #define BUFSIZE 512 void Pick (int x,int y) { GLint viewPort[4] ; ::glGetIntegerv (GL_VIEWPORT,viewPort) ; GLuint selBuf[BUFSIZE] ; ::glSelectBuffer(BUFSIZE,selBuf) ; ::glRenderMode(GL_SELECT) ; ::glMatrixMode(GL_PROJECTION); ::glPushMatrix() ; ::glLoadIdentity(); ::gluPickMatrix (x, viewPort[3]-y, 1.0, 1.0, viewPort); Perspective() ; LookAt() ; ::draw() ; ::glMatrixMode (GL_PROJECTION); ::glPopMatrix (); ::glFlush (); GLint hits = ::glRenderMode (GL_RENDER); processHits (hits, selBuf); ::glutPostRedisplay(); /* if (hits > 0) { GLdouble model[16] ; ::glGetDoublev (GL_MODELVIEW_MATRIX, model) ; GLdouble projm[16] ; ::glGetDoublev (GL_PROJECTION_MATRIX, projm) ; GLfloat z = float(SelDepth) / 0xffffffff ; double w = ::glutGet(GLUT_WINDOW_WIDTH) ; double h = ::glutGet(GLUT_WINDOW_HEIGHT) ; Vd3 op ; ::gluUnProject(x,h-y,z,model,projm,viewPort,&op.x,&op.y,&op.z) ; std::tout << _T("SelPoint=\t") << op.x << _T("\t,\t") << op.y << _T("\t,\t") << op.z << _T("\t,\t") << std::endl ; SelPoint = op ; } */ { GLdouble model[16] ; ::glGetDoublev (GL_MODELVIEW_MATRIX, model) ; GLdouble projm[16] ; ::glGetDoublev (GL_PROJECTION_MATRIX, projm) ; GLfloat z = float(SelDepth) / 0xffffffff ; double w = ::glutGet(GLUT_WINDOW_WIDTH) ; double h = ::glutGet(GLUT_WINDOW_HEIGHT) ; Vd3 op ; ::gluUnProject(x,h-y,z,model,projm,viewPort,&op.x,&op.y,&op.z) ; std::tout << _T("SelPoint=\t") << op.x << _T("\t,\t") << op.y << _T("\t,\t") << op.z << _T("\t,\t") << std::endl ; SelPoint = op ; } } void mouse (int button,int state,int x,int y) { std::tout << _T("Button=") << button << _T("\t") << x << _T(" , ") << y << _T("\t") << state << std::endl ; LastEP = Vd3(0) ; if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { Anchor = Vd2(x,y) ; LastEP = EP ; } if (state == GLUT_DOWN) { ::glutIdleFunc(idle) ; } else { ::glutIdleFunc(NULL) ; } // return ; } if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { Pick(x,y) ; return ; } if (Anchor == Vd2(x,y) && button == GLUT_LEFT_BUTTON && state == GLUT_UP) { Pick(x,y) ; } } void motion (int x,int y) { // std::tout << _T("MouseMove") << _T("\t") << x << _T(" , ") << y << std::endl ; if (LastEP == Vd3(0)) { return ; } double width_ = ::glutGet(GLUT_WINDOW_WIDTH) ; double height = ::glutGet(GLUT_WINDOW_HEIGHT) ; double angleXY = rad(180*(Anchor.x-x) / width_) ; double angle_Z = -rad(180*(Anchor.y-y) / height) ; Vd3 eye = LastEP ; eye = ::Eye_GetSpinXY(eye,angleXY) ; eye = ::Eye_GetSpin_Z(eye,angle_Z) ; EP = eye ; // std::tout << deg(angleXY) << _T("\t") << deg(angle_Z) << std::endl ; } void passive (int x,int y) { // std::tout << _T("PassiveMove") << _T("\t") << x << _T(" , ") << y << std::endl ; Pick(x,y) ; } void keyboard (unsigned char key,int x,int y) { std::tout << _T("Key=") << key << _T("\t") << x << _T(" , ") << y << std::endl ; switch (key) { case 'q': case 'Q': case '\x1b' : exit(0); break; default: break; } } void init (void) { ::glClearColor(0.9,0.9,0.9,1.0) ; ::glEnable(GL_DEPTH_TEST); ::glEnable(GL_LIGHTING); ::glEnable(GL_LIGHT0); } // int _tmain (int argc, _TCHAR* argv[]) int main (int argc, char* argv[]) { { tstring thisFile = _T(__FILE__) ; std::tout << thisFile.c_str() << std::endl ; std::tout << ::Debug_GetMacroCC() << std::endl ; } ::glutInitWindowPosition(200, 000); ::glutInitWindowSize (600, 400); ::glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); ::glutInit (&argc,argv) ; ::glutCreateWindow (argv[0]) ; ::glutReshapeFunc (resize); ::glutDisplayFunc (display) ; ::glutKeyboardFunc (keyboard) ; ::glutMouseFunc (mouse) ; ::glutMotionFunc (motion) ; ::glutPassiveMotionFunc (passive) ; ::init () ; ::glutMainLoop () ; return 0 ; }