moving mouse
c
last edit: Oct, 17th 2012 | jump to bottom
#include "Angel.h" #include <gl/glew.h> #include <glut.h> #define bool int /* if system does not support bool type */ #define false 0 #define true 1 #define M_PI 3.14159 /* if not in math.h */ int winWidth, winHeight; float angle = 0.0, axis[3], trans[3]; bool trackingMouse = false; bool redrawContinue = false; bool trackballMove = false; float lastPos[3] = {0.0, 0.0, 0.0}; int curx, cury; int startX, startY; //the program object GLuint program = 0; typedef Angel::vec4 color4; typedef Angel::vec4 point4; const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle) point4 points[NumVertices]; color4 colors[NumVertices]; // Vertices of a unit cube centered at origin, sides aligned with axes point4 vertices[8] = { point4( -0.5, -0.5, 0.5, 1.0 ), point4( -0.5, 0.5, 0.5, 1.0 ), point4( 0.5, 0.5, 0.5, 1.0 ), point4( 0.5, -0.5, 0.5, 1.0 ), point4( -0.5, -0.5, -0.5, 1.0 ), point4( -0.5, 0.5, -0.5, 1.0 ), point4( 0.5, 0.5, -0.5, 1.0 ), point4( 0.5, -0.5, -0.5, 1.0 ) }; // RGBA colors color4 vertex_colors[8] = { color4( 0.0, 0.0, 0.0, 1.0 ), // black color4( 1.0, 0.0, 0.0, 1.0 ), // red color4( 1.0, 1.0, 0.0, 1.0 ), // yellow color4( 0.0, 1.0, 0.0, 1.0 ), // green color4( 0.0, 0.0, 1.0, 1.0 ), // blue color4( 1.0, 0.0, 1.0, 1.0 ), // magenta color4( 1.0, 1.0, 1.0, 1.0 ), // white color4( 0.0, 1.0, 1.0, 1.0 ) // cyan }; // Array of rotation angles (in degrees) for each coordinate axis enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 }; int Axis = Xaxis; GLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 }; GLuint theta; // The location of the "theta" shader uniform variable GLuint shaderaxis; //---------------------------------------------------------------------- // quad generates two triangles for each face and assigns colors // to the vertices int Index = 0; void quad( int a, int b, int c, int d ) { colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++; colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++; colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++; colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++; colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++; colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++; } //---------------------------------------------------------------------- // generate 12 triangles: 36 vertices and 36 colors void colorcube( void ) { quad( 1, 0, 3, 2 ); quad( 2, 3, 7, 6 ); quad( 3, 0, 4, 7 ); quad( 6, 5, 1, 2 ); quad( 4, 5, 6, 7 ); quad( 5, 4, 0, 1 ); } //--------------------------------------------- void trackball_ptov(int x, int y, int width, int height, float v[3]) { float d, a; /* project x,y onto a hemisphere centered within width, height , note z is up here*/ v[0] = (2.0*x - width) / width; v[1] = (height - 2.0F*y) / height; d = sqrt(v[0]*v[0] + v[1]*v[1]); v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0)); a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] *= a; v[1] *= a; v[2] *= a; } //--------------------------------------------------------------- void mouseMotion(int x, int y) { float curPos[3], dx, dy, dz; /* compute position on hemisphere */ trackball_ptov(x, y, 512, 512, curPos); if(trackingMouse) { /* compute the change in position on the hemisphere */ dx = curPos[0] - lastPos[0]; dy = curPos[1] - lastPos[1]; dz = curPos[2] - lastPos[2]; if (dx || dy || dz) { /* compute theta and cross product */ angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz); axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1]; axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2]; axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0]; /* update position */ lastPos[0] = curPos[0]; lastPos[1] = curPos[1]; lastPos[2] = curPos[2]; } } glutPostRedisplay(); } //---------------------------------------------------------------------- // OpenGL initialization void init( void ) { colorcube(); // Load shaders and use the resulting shader program GLuint program = InitShader( "vshader36.glsl", "fshader36.glsl" ); glUseProgram( program ); // Create a vertex array object GLuint vao; glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); // Create and initialize a buffer object GLuint buffer; glGenBuffers( 1, &buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW ); glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points ); glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors ); // set up vertex arrays GLuint vPosition = glGetAttribLocation( program, "vPosition" ); glEnableVertexAttribArray( vPosition ); glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); GLuint vColor = glGetAttribLocation( program, "vColor" ); glEnableVertexAttribArray( vColor ); glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)) ); theta = glGetUniformLocation( program, "theta" ); glEnable( GL_DEPTH_TEST ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); } //---------------------------------------------------------------------- void spinCube() { if (redrawContinue) glutPostRedisplay(); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glUniform3fv( theta, 1, Theta ); if (trackballMove) { float a = angle; float b = axis[0]; float c = axis[1]; float d = axis[2]; float xform[16] = {(a*a+b*b-c*c-d*d),(2*b*c-2*a*d),(2*b*d+2*a*c),0.0, (2*b*c+2*a*d),(a*a-b*b+c*c-d*d),(2*c*d-2*a*b),0.0, (2*b*d-2*a*c),(2*c*d+2*a*b),(a*a-b*b-c*c+d*d),0.0, 0.0,0.0,0.0,1.0}; GLuint Transform = glGetUniformLocation( program, "vTransform"); glUniformMatrix4fv(Transform, 1, false, xform); } else{ float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; GLuint Transform = glGetUniformLocation( program, "vTransform"); glUniformMatrix4fv(Transform, 1, false, identity); } colorcube(); glDrawArrays( GL_TRIANGLES, 0, NumVertices ); glutSwapBuffers(); } //--------------------------------------------------- void keyboard( unsigned char key, int x, int y ) { switch( key ) { case 033: // Escape Key case 'q': case 'Q': exit( EXIT_SUCCESS ); break; } } //---------------------------------------------------------------------- void startMotion(int x, int y) { trackingMouse = true; redrawContinue = false; startX = x; startY = y; curx = x; cury = y; trackball_ptov(x, y, 512, 512, lastPos); trackballMove=true; } //--------- void stopMotion(int x, int y) { trackingMouse = false; /* check if position has changed */ if (startX != x || startY != y) redrawContinue = true; else { angle = 0.0; redrawContinue = false; trackballMove = false; } } //------------- void mouseButton(int button, int state, int x, int y) { if(button==GLUT_RIGHT_BUTTON) exit(0); /* holding down left button allows user to rotate cube */ if(button==GLUT_LEFT_BUTTON) switch(state) { case GLUT_DOWN: startMotion( x,y); break; case GLUT_UP: stopMotion( x,y); break; } } //---------------------------------------------------------------------- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize( 512, 512 ); glutCreateWindow( "Color Cube" ); glewInit(); init(); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutMouseFunc( mouseButton ); glutMotionFunc(mouseMotion); glutIdleFunc( spinCube ); glutMainLoop(); return 0; } ////////vshader///////////// #version 150 in vec4 vPosition; in vec4 vColor; out vec4 color; uniform vec3 theta; uniform mat4 vTransform; void main() { // Compute the sines and cosines of theta for each of // the three axes in one computation. vec3 angles = radians( theta ); vec3 c = cos( angles ); vec3 s = sin( angles ); // Remember: these matrices are column-major mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, c.x, -s.x, 0.0, 0.0, s.x, c.x, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 ry = mat4( c.y, 0.0, s.y, 0.0, 0.0, 1.0, 0.0, 0.0, -s.y, 0.0, c.y, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 rz = mat4( c.z, -s.z, 0.0, 0.0, s.z, c.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); color = vColor; gl_Position = rx * ry * rz * vPosition; }
206 views




