我有一个程序,其中使用OpenGL显示彩色立方体。我正在使用freeglut来显示OpenGL实例。该程序应该允许用户在按住鼠标左键的同时用鼠标旋转立方体。每次鼠标移动后,光标应该在窗口中居,然后是glutPostRedisplay();只是被调用几次然后停止被调用,直到你释放鼠标左键。
my_cube.c
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/glew.h>
#include <GL/freeglut.h>
// ----------------------------------------------------------
// Function Prototypes
// ----------------------------------------------------------
void display();
void specialKeys();
// ----------------------------------------------------------
// Global Variables
// ----------------------------------------------------------
double rotate_y=0;
double rotate_x=0;
float deltaAngleX = 0.0f;
float deltaAngleY = 0.0f;
int xOrigin = -1;
int yOrigin = -1;
int MSAA;
int MouseState = 0;
void enableMultisample(int msaa){
if(msaa)
{
glEnable(GL_MULTISAMPLE);
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
//detect current settings
GLint iMultiSample = 0;
GLint iNumSamples = 0;
glGetIntegerv(GL_SAMPLE_BUFFERS, &iMultiSample);
glGetIntegerv(GL_SAMPLES, &iNumSamples);
//printf("MSAA on, GL_SAMPLE_BUFFERS = %d, GL_SAMPLES = %d\n", iMultiSample, iNumSamples);
}
else
{
glDisable(GL_MULTISAMPLE);
//printf("MSAA off\n");
}
}
void mouseButton(int button, int state, int x, int y) {
// only start motion if the left button is pressed
if (button == GLUT_LEFT_BUTTON) {
// when the button is released
if (state == GLUT_UP) {
//rotate_x += deltaAngleX;
//rotate_y += deltaAngleY;
xOrigin = -1;
yOrigin = -1;
MouseState = 0;
}
else {// state = GLUT_DOWN
xOrigin = x;
yOrigin = y;
MouseState = 1;
}
}
}
void mouseMove(int x, int y) {
// this will only be true when the left button is down
if (xOrigin >= 0) {
int midWindowX = 1280 / 2;
int midWindowY = 720 / 2;
rotate_y -= (x - midWindowX) / 10.0f;
rotate_x += (y - midWindowY) / 10.0f;
glutWarpPointer(midWindowX, midWindowY);
//glutPostRedisplay();
printf("Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y);
glutPostRedisplay();
}
}
// ----------------------------------------------------------
// display() Callback function
// ----------------------------------------------------------
void display(){
// Clear screen and Z-buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Reset transformations
//
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (1280.0f/720.0f), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
enableMultisample(MSAA);
glTranslatef(0, 0, -4);
glRotatef(180, 1.0, 0.0, 0.0);
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// Reset rotations
if(rotate_x == 360.0f || rotate_x > 360.0f || rotate_x == -360 || rotate_x < -360) rotate_x = 0.0f;
if(rotate_y == 360.0f || rotate_y > 360.0f || rotate_y == -360 || rotate_y < -360) rotate_y = 0.0f;
//Multi-colored side - FRONT
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 ); glVertex3f( -0.5, -0.5, -0.5 ); // P4 is green
glColor3f( 0.0, 0.0, 1.0 ); glVertex3f( -0.5, 0.5, -0.5 ); // P3 is blue
glColor3f( 1.0, 0.0, 1.0 ); glVertex3f( 0.5, 0.5, -0.5 ); // P2 is purple
glColor3f( 1.0, 0.0, 0.0 ); glVertex3f( 0.5, -0.5, -0.5 ); // P1 is red
glEnd();
// White side - BACK
glBegin(GL_POLYGON);
glColor3f( 1.0, 1.0, 1.0 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glEnd();
// Purple side - RIGHT
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glEnd();
// Green side - LEFT
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
// Blue side - TOP
glBegin(GL_POLYGON);
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glEnd();
// Red side - BOTTOM
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
glFlush();
glutSwapBuffers();
}
// ----------------------------------------------------------
// specialKeys() Callback Function
// ----------------------------------------------------------
void specialKeys( int key, int x, int y ) {
if(!MouseState){
// Right arrow - increase rotation by 5 degree
if (key == GLUT_KEY_RIGHT)
rotate_y -= 5;
// Left arrow - decrease rotation by 5 degree
else if (key == GLUT_KEY_LEFT)
rotate_y += 5;
else if (key == GLUT_KEY_UP)
rotate_x -= 5;
else if (key == GLUT_KEY_DOWN)
rotate_x += 5;
// Request display update
glutPostRedisplay();
}
}
// ----------------------------------------------------------
// main() function
// ----------------------------------------------------------
int main(int argc, char* argv[]){
for(int i; i<argc; i++){
char *arg;
arg = argv[i];
const char msaaArg[4] = "MSAA";
char *ret;
ret = strstr(arg, msaaArg);
if(ret != NULL){
MSAA = (intptr_t)argv[i+1];
}
}
// Initialize GLUT and process user parameters
glutInit(&argc,argv);
// Set Initial Size of window
glutInitWindowSize(1280, 720);
// Enable Multisampling
glutSetOption(GLUT_MULTISAMPLE, 8);
// Request double buffered true color window with Z-buffer
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
// Create window
glewInit();
glutCreateWindow("");
// Get OpenGL Version
printf("Using OpenGL Version: %s\n", glGetString(GL_VERSION));
char title[150];
const char* temp;
strcpy(title, "Awesome Cube [OpenGL Version ");
strcat(title, glGetString(GL_VERSION));
temp = glGetString(GL_VERSION);
strcat(title, "]");
glutSetWindowTitle(title);
// Enable Z-buffer depth test
glEnable(GL_DEPTH_TEST);
// Enable Backface Culling
glEnable(GL_CULL_FACE);
// Move mouse to the middle of the screen
glutWarpPointer(1280/2, 720/2);
// Callback functions
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMove);
// Pass control to GLUT for events
glutMainLoop();
return 0;
}
答案 0 :(得分:1)
glutWarpPointer()
生成一个新的鼠标动作回调;设置一个标志并忽略warp生成的运动回调:
bool warped = false;
void mouseMove( int x, int y )
{
if( warped )
{
warped = false;
return;
}
// this will only be true when the left button is down
if( xOrigin >= 0 )
{
int midWindowX = 1280 / 2;
int midWindowY = 720 / 2;
rotate_y -= ( x - midWindowX ) / 10.0f;
rotate_x += ( y - midWindowY ) / 10.0f;
warped = true;
glutWarpPointer( midWindowX, midWindowY );
printf( "Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y );
glutPostRedisplay();
}
}
所有在一起:
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
// ----------------------------------------------------------
// Function Prototypes
// ----------------------------------------------------------
void display();
void specialKeys();
// ----------------------------------------------------------
// Global Variables
// ----------------------------------------------------------
double rotate_y = 0;
double rotate_x = 0;
float deltaAngleX = 0.0f;
float deltaAngleY = 0.0f;
int xOrigin = -1;
int yOrigin = -1;
int MouseState = 0;
void mouseButton( int button, int state, int x, int y )
{
// only start motion if the left button is pressed
if( button == GLUT_LEFT_BUTTON )
{
// when the button is released
if( state == GLUT_UP )
{
//rotate_x += deltaAngleX;
//rotate_y += deltaAngleY;
xOrigin = -1;
yOrigin = -1;
MouseState = 0;
}
else
{
// state = GLUT_DOWN
xOrigin = x;
yOrigin = y;
MouseState = 1;
}
}
}
bool warped = false;
void mouseMove( int x, int y )
{
if( warped )
{
warped = false;
return;
}
// this will only be true when the left button is down
if( xOrigin >= 0 )
{
int midWindowX = 1280 / 2;
int midWindowY = 720 / 2;
rotate_y -= ( x - midWindowX ) / 10.0f;
rotate_x += ( y - midWindowY ) / 10.0f;
warped = true;
glutWarpPointer( midWindowX, midWindowY );
printf( "Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y );
glutPostRedisplay();
}
}
// ----------------------------------------------------------
// display() Callback function
// ----------------------------------------------------------
void display()
{
// Clear screen and Z-buffer
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Reset transformations
//
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, ( 1280.0f / 720.0f ), 0.1f, 100.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0, 0, -4 );
glRotatef( 180, 1.0, 0.0, 0.0 );
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// Reset rotations
if( rotate_x == 360.0f || rotate_x > 360.0f || rotate_x == -360 || rotate_x < -360 ) rotate_x = 0.0f;
if( rotate_y == 360.0f || rotate_y > 360.0f || rotate_y == -360 || rotate_y < -360 ) rotate_y = 0.0f;
//Multi-colored side - FRONT
glBegin( GL_POLYGON );
glColor3f( 0.0, 1.0, 0.0 ); glVertex3f( -0.5, -0.5, -0.5 ); // P4 is green
glColor3f( 0.0, 0.0, 1.0 ); glVertex3f( -0.5, 0.5, -0.5 ); // P3 is blue
glColor3f( 1.0, 0.0, 1.0 ); glVertex3f( 0.5, 0.5, -0.5 ); // P2 is purple
glColor3f( 1.0, 0.0, 0.0 ); glVertex3f( 0.5, -0.5, -0.5 ); // P1 is red
glEnd();
// White side - BACK
glBegin( GL_POLYGON );
glColor3f( 1.0, 1.0, 1.0 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glEnd();
// Purple side - RIGHT
glBegin( GL_POLYGON );
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glEnd();
// Green side - LEFT
glBegin( GL_POLYGON );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
// Blue side - TOP
glBegin( GL_POLYGON );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glEnd();
// Red side - BOTTOM
glBegin( GL_POLYGON );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
glFlush();
glutSwapBuffers();
}
// ----------------------------------------------------------
// specialKeys() Callback Function
// ----------------------------------------------------------
void specialKeys( int key, int x, int y )
{
if( !MouseState )
{
// Right arrow - increase rotation by 5 degree
if( key == GLUT_KEY_RIGHT )
rotate_y -= 5;
// Left arrow - decrease rotation by 5 degree
else if( key == GLUT_KEY_LEFT )
rotate_y += 5;
else if( key == GLUT_KEY_UP )
rotate_x -= 5;
else if( key == GLUT_KEY_DOWN )
rotate_x += 5;
// Request display update
glutPostRedisplay();
}
}
// ----------------------------------------------------------
// main() function
// ----------------------------------------------------------
int main( int argc, char* argv[] )
{
// Initialize GLUT and process user parameters
glutInit( &argc, argv );
// Set Initial Size of window
glutInitWindowSize( 1280, 720 );
// Request double buffered true color window with Z-buffer
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
// Create window
glewInit();
glutCreateWindow( "" );
// Enable Z-buffer depth test
glEnable( GL_DEPTH_TEST );
// Enable Backface Culling
glEnable( GL_CULL_FACE );
// Move mouse to the middle of the screen
glutWarpPointer( 1280 / 2, 720 / 2 );
// Callback functions
glutDisplayFunc( display );
glutSpecialFunc( specialKeys );
glutMouseFunc( mouseButton );
glutMotionFunc( mouseMove );
// Pass control to GLUT for events
glutMainLoop();
return 0;
}