GLUT程序只适用于少数帧
GLUT program only works for a few frames
我有一个6个多月前编写的程序,它使用了GLUT库。6个月前,当我写这篇文章的时候,它运行得非常好。从那以后,我没有使用过它,也没有以任何方式编辑过代码。
程序让一些立方体以随机的速度漂浮在周围,它们在环境的墙壁上反弹。相机可以用方向键移动,用鼠标平移/倾斜。点击可以在环境中添加更多的墙壁,然后可以用箭头键调整它们的位置。
然而,尽管这是6个月前的工作,现在相机只在程序的前几帧用鼠标平移/倾斜,就像用箭头键移动相机一样。然而,程序没有冻结,我仍然可以看到立方体漂浮在周围,可以添加和调整位置的墙壁仍然可以移动。
是否存在导致先前工作的GLUT程序仅在前几帧正常工作的常见原因?
#include <iostream>
#include <GL/glut.h>
#include <Windows.h> //FOR CURSOR
#include <tgmath.h> //FOR MATHS
#include <fstream>
#include <string>
#include <time.h> //FOR THE TIME FOR RANDOM GENERATOR SEED
const int MAXMOLECULES = 1000000, MAXCUBOIDS = 10000, NUMBER_OF_PRESSURE_SENSORS = 3, MAX_RECORDING_TIME = 1000000;
int widthOfMonitor = glutGet( GLUT_SCREEN_WIDTH ), heightOfMonitor = glutGet( GLUT_SCREEN_HEIGHT ),
cuboidBuilding = 0;//IS A CUBE CURRENTLY BEING BUILT? 0 FOR NO, 1 FOR YES.
const float ORIGINAL_CAMERA_LOCATION[3] = { 0, 0, 0 }, //ORIGINAL CAMERA LOCATION
ORIGINAL_CAMERA_DIRECTION[3] = { 2.001, 0, 0 },
PI = 3.14159265359, //PI
MAPSIZE = 20.0, //SIZE OF THE CUBE SURROUNDING THE CENTER
SIZESCALE = 100.0; //SCALE THE SIZE OF BOXES
float cameraInformation[3][3], //(CAMERA TRANSLATION FROM ORIGINAL CAMERA LOCATION, CAMERA DIRECTION, CAMERA LOCATION) in (x,y,z)
cursorAngle[2], //POSITION OF CURSOR CONVERTED TO AN ANGLE, in (y,z)
cubeInitialOrigin[3], //ORIGIN OF CUBE WHEN STARTING BUILDING, in (x,y,z)
movementSpeed = 0.0125;
char s[30];
std::string str1 = "FILLINGUPTHESTRING"; //TAKES USERS INPUT OF FILENAME
const char *FILENAME = str1.c_str( );
void window_size( int w, int h ); //TAKE CURRENT SIZE OF WINDOW
void rotate_camera( );
void move_forward( float forwardsOrBackwards );
void move_left( float forwardsOrBackwards );
void move_up( float forwardsOrBackwards );
void keyboard( unsigned char key, int x, int y );
void cuboid ( float OCX, float OCY, float OCZ,
float xsize, float ysize, float zsize,
float TR, float TG, float TB,
float BR, float BG, float BB,
float FR, float FG, float FB,
float BWR, float BWG, float BWB,
float LR, float LG, float LB,
float RR, float RG, float RB ); //PRODUCE CUBOIDS
void display ( ); //RENDERS CUBOIDS, TEXT AND MOLECULES
int main ( int argc, char **argv )
{
ShowCursor( FALSE );
void glutInit( int *argc, char **argv );
glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
//CREATE WINDOW, SET RESOLUTION AND POSITION
glutInitWindowSize( widthOfMonitor, heightOfMonitor );
glutCreateWindow( "SQUARE" );
glutInitWindowPosition( 0, 0 );
glutFullScreen( );
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glutReshapeFunc( window_size ); //SET WINDOW CORRECT SIZE
glutKeyboardFunc( keyboard );//DETECT IF KEYBOARD IS PRESSED AND RESPOND
//CONSTANTLY UPDATE DISPLAY AT FRAME rate OF MONITOR (OR LOWER IF CPU/GPU CANNOT PROCESS FAST ENOUGH)
glutDisplayFunc( display );
glutIdleFunc( display );
glEnable( GL_DEPTH_TEST ); //RENDER OBJECTS CLOSEST TO CAMERA INFRONT OF OBJECTS FURTHER AWAY
glutMainLoop( );
}
/*window_size TAKES INPUT OF SIZE OF WINDOW THEN GENERATES THE ORIGINAL CAMERA VIEW*/
void window_size( int widthOfMonitor, int heightOfMonitor ) //TAKE CURRENT SIZE OF WINDOW
{
glMatrixMode( GL_PROJECTION ); //EDIT THE CAMERA SETTINGS
glViewport( 0, 0, widthOfMonitor, heightOfMonitor ); //SET THE RENDERING TO COVER ENTIRE WINDOW
//SET THE PERSPECTIVE
gluPerspective( 90, //FOV
widthOfMonitor / heightOfMonitor, //DISPLAY ASPECT
0.01, //NEAR CLIP
20000.0 ); //FAR CLIP
glMatrixMode( GL_MODELVIEW ); //CHANGE BACK TO EDITING THE WOLRD
gluLookAt( ORIGINAL_CAMERA_LOCATION[0], ORIGINAL_CAMERA_LOCATION[1], ORIGINAL_CAMERA_LOCATION[2], //CAMERA LOCATION
ORIGINAL_CAMERA_LOCATION[0] + ORIGINAL_CAMERA_DIRECTION[0], ORIGINAL_CAMERA_LOCATION[1] + ORIGINAL_CAMERA_LOCATION[1], ORIGINAL_CAMERA_LOCATION[2] + ORIGINAL_CAMERA_LOCATION[2], //LOOK AT
0.0, 1.0, 0.0 ); //VERTICAL DEFINITION
}
/*rotate_camera DETECTS LOCATION OF CURSOR, ADJUSTING THE DIRECTION LOOKED DEPENDING ON WHAT DIRECTION THE MOUSE IS MOVED*/
void rotate_camera( )
{
POINT m1;
GetCursorPos( &m1 );//EXTRACT MOUSE COORDINATES
//DISPLACEMENT FROM CENTRE OF SCREEN IN X&Y
int xmpos = ( m1.x - widthOfMonitor / 2 );
int ympos = ( m1.y - heightOfMonitor / 2 );
//TAKE MOUSE COORDS AND SET WHOLE WINDOW TO BE LENGTH 2PI IN X AND Y
cursorAngle[0] += - ( ( xmpos * 180 / (widthOfMonitor / 2) ) * PI / 180 );
cursorAngle[1] += ( ( ympos * 180 / (heightOfMonitor / 2) ) * PI / 180 );
//DON'T ALLOW ROTATING UP PAST CEILING OR BELOW FLOOR, CAN BE DONE BUT MAKES PERSPECTIVE CONFUSING
if ( cursorAngle[1] > 0 )
cursorAngle[1] = - 1E-5;
else if ( cursorAngle[1] < -PI )
cursorAngle[1] = -( PI - 1E-5 );
//CONVERT FROM SPHERICAL POLARS INTO CARTESIANS
cameraInformation[1][0] = cos( cursorAngle[0] ) * sin( cursorAngle[1] );
cameraInformation[1][1] = sin( cursorAngle[0] ) * sin( cursorAngle[1] );
cameraInformation[1][2] = -cos( cursorAngle[1] );
//KEEP CURSOR CENTERED TO PREVENT SCREEN GETTING STUCK WHEN ROTATING PAST 2PI.
SetCursorPos( widthOfMonitor / 2, heightOfMonitor / 2 );
}
/*MoveForwards TRIGGERS IF W OR S IS PRESSED AND MOVES FORWARD OR BACKWARDS IN THE DIRECTION FACED IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE FORWARD OR BACKWARDS IN THE DIRECTION FACED IF CUBE IS BEING BUILT*/
void move_forward( float forwardsOrBackwards )
{
float changeInX, changeInY, changeInZ, length;
if ( cuboidBuilding == 0 )
{
//GO FORWARD/BACK RELATIVE TO CAMERA VIEW
changeInX = ( forwardsOrBackwards * cameraInformation[1][0] );
changeInY = ( forwardsOrBackwards * cameraInformation[1][1] );
changeInZ = ( forwardsOrBackwards * cameraInformation[1][2] );
//NORMALIZE MOVEMENT
length = sqrt ( pow ( changeInX, 2.0 ) + pow ( changeInY, 2.0 ) + pow ( changeInZ, 2.0 ) );
changeInX = changeInX / length;
changeInY = changeInY / length;
changeInZ = changeInZ / length;
//SET SENSITIVITY AND ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
cameraInformation[0][0] += changeInX * movementSpeed;
cameraInformation[0][1] += changeInY * movementSpeed;
cameraInformation[0][2] += changeInZ * movementSpeed;
}
}
/*move_left TRIGGERS IF A OR D IS PRESSED AND MOVES LEFT OR RIGHT TO THE DIRECTION FACED IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE LEFT OR RIGHT OF THE DIRECTION FACED IF CUBE IS BEING BUILT*/
void move_left( float forwardsOrBackwards )
{
float changeInX, changeInY, length;
if ( cuboidBuilding == 0 )
{
//GO LEFT/RIGHT RELATIVE TO CAMERA VIEW
changeInX = ( -forwardsOrBackwards * cameraInformation[1][1] );
changeInY = ( forwardsOrBackwards * cameraInformation[1][0] );
//NORMALIZE MOVEMENT
length = sqrt ( pow ( changeInX, 2.0 ) + pow ( changeInY, 2.0 ) );
changeInX = changeInX / length;
changeInY = changeInY / length;
//SET SENSITIVITY AND ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
cameraInformation[0][0] += changeInX * movementSpeed;
cameraInformation[0][1] += changeInY * movementSpeed;
}
}
/*move_up TRIGGERS IF Q OR E IS PRESSED AND MOVES VERTICALLY UP OR DOWN IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE VERTICALLY UP OR DOWN IF CUBE IS BEING BUILT*/
void move_up( float forwardsOrBackwards )
{
//MOVEMENT AND MAKING CUBE AS THE DIRECTION MOVED IS ALWAYS PARRALEL TO Z COORDS, SO NO CONVERSION FROM CAMERA TO BOX IS REQUIRED
float changeInZ, length;
//GO UP/DOWN RELATIVE TO CAMERA VIEW
changeInZ = ( forwardsOrBackwards );
//NORMALIZE MOVEMENT
length = sqrt( pow ( changeInZ, 2.0 ) );
changeInZ = changeInZ / length;
//SET SENSITIVITY
if ( cuboidBuilding == 0 )
cameraInformation[0][2] += changeInZ * movementSpeed;
//ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
}
/*keyboard TRIGGERS IF A KEY ON THE KEYBOARD IS PRESSED, THEN PASSES TO A FUNCTION THAT PROCESSES THE KEY PRESSED, ALSO UPDATES THE LOCATION OF CAMERA IF MOVEMENT KEYS ARE PRESSED */
void keyboard( unsigned char key, int x, int y )
{
int forwardsOrBackwards; //FORWARD OR BACKWORDS.
//PREVENT A POTENTIAL DIVIDE BY 0 ERROR BY SETTING 0 DIRECTIONS TO VERY SMALL DIRECTIONS.
for ( int i = 0; i <= 2; i++ )
{
if ( cameraInformation[1][i] > -1E-5 && cameraInformation[1][i] < 1E-5 )
cameraInformation[1][i] = 1E-4;
}
switch ( key )
{
case 122: case 90: //z
if ( movementSpeed < 0.5 )
movementSpeed = 1.0;
else
movementSpeed = 0.025;
break;
case 119: case 52: forwardsOrBackwards = 1; move_forward ( forwardsOrBackwards ); break; //w
case 115: case 83: forwardsOrBackwards = -1;move_forward ( forwardsOrBackwards ); break; //s
case 97 : case 65: forwardsOrBackwards = 1; move_left ( forwardsOrBackwards ); break; //a
case 100: case 68: forwardsOrBackwards = -1;move_left ( forwardsOrBackwards ); break; //d
case 113: case 81: forwardsOrBackwards = -1;move_up ( forwardsOrBackwards ); break; //q
case 101: case 69: forwardsOrBackwards = 1; move_up ( forwardsOrBackwards ); break; //e
case 27 : exit ( 0 ); //esc CLOSE PROGRAM
}
if ( cuboidBuilding == 0 ) //IF NOT BUILDING A CUBE, MOVE CAMERA COORDS BY THE AMOUNT THEY HAVE CHANGED
{
for ( int i = 0; i <=2; i++)
{
cameraInformation[2][i] = ORIGINAL_CAMERA_LOCATION[i] + cameraInformation[0][i];
}
}
}
/*cuboid TAKES INPUTS OF CENTER OF CUBE, SIZE OF CUBE AND COLOURS OF EACH FACE THEN PRODUCES A CUBE BY SPLITING EACH FACE UP INTO TWO TRIANGLES*/
void cuboid ( float OCX, float OCY, float OCZ,
float xsize, float ysize, float zsize,
float TR, float TG, float TB,
float BR, float BG, float BB,
float FR, float FG, float FB,
float BWR, float BWG, float BWB,
float LR, float LG, float LB,
float RR, float RG, float RB )
{
glBegin( GL_TRIANGLES );
//MAKE TRIANGLES IN SHAPE OF A CUBE BY SPECIFYING VERTICES OF TRIANGLES
glColor3f ( TR, TG, TB ); //TOP
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glColor3f ( BR, BG, BB ); //BOTTOM
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glColor3f ( FR, FG, FB ); //FORWARDS
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glColor3f ( BWR, BWG, BWB ); //BACKWARDS
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize);
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glColor3f ( LR, LG, LB ); //LEFT
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glColor3f ( RR, RG, RB ); //RIGHT
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glEnd( );
}
/*place_cuboid TRIGGERS IF LEFT MOUSE BUTTON IS PLACED, CAUSES A TEMPORARY CUBE TO APPEAR AT THE CURSOR LOCATION, THEN WHEN LEFT MOUSE BUTTON IS RELEASED IT SAVES THE CENTER,SIZE AND COLOUR OF THIS TEMPORARY CUBE INTO THE PERMAMENT ARRAYS OF CUBS*/
/*display TAKES THE ARRAYS OF CUBE AND MOLECULE LOCATIONS, SIZE AND COLOURS THEN RENDERS AND CHECKS IF MOLECULES ARE COLLIDING WITH A CUBE*/
void display ( )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//SET EDGES OF THE MAP
cuboid ( 0.0, 0.0, 0.0,
MAPSIZE, MAPSIZE, MAPSIZE,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0 );
glColor3d( 1.0, 0.0, 0.0 );
glPushMatrix( );
glLoadIdentity( );
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
rotate_camera( ); //ROTATE CAMERA WITH MOUSE
//MOVE CAMERA
gluLookAt( cameraInformation[2][0], cameraInformation[2][1], cameraInformation[2][2], //Camera location
cameraInformation[2][0] + cameraInformation[1][0], cameraInformation[2][1] + cameraInformation[1][1], cameraInformation[2][2] + cameraInformation[1][2], //LOOK AT
0.0, 0.0, 1.0 ); //VERTICAL
glutSwapBuffers();
}
- 在调用
glutInit()
之前不要使用glutGet()
- 初始化变量
- 使用c++风格的
#include
- 设置你的矩阵在你的显示回调,有助于防止使用错误
- 无需使用Windows来跟踪/隐藏光标,(免费)GLUT有相应的功能
- 对于电池/CPU风扇来说,timerfunc或vsync比空闲回调更友好
一起:
#include <GL/freeglut.h>
#include <cmath>
int cuboidBuilding = 0;//IS A CUBE CURRENTLY BEING BUILT? 0 FOR NO, 1 FOR YES.
const float ORIGINAL_CAMERA_LOCATION[3] = { 0, 0, 0 }, //ORIGINAL CAMERA LOCATION
ORIGINAL_CAMERA_DIRECTION[3] = { 2.001, 0, 0 },
PI = 3.14159265359, //PI
MAPSIZE = 20.0, //SIZE OF THE CUBE SURROUNDING THE CENTER
SIZESCALE = 100.0; //SCALE THE SIZE OF BOXES
float cameraInformation[3][3], //(CAMERA TRANSLATION FROM ORIGINAL CAMERA LOCATION, CAMERA DIRECTION, CAMERA LOCATION) in (x,y,z)
cursorAngle[2], //POSITION OF CURSOR CONVERTED TO AN ANGLE, in (y,z)
cubeInitialOrigin[3], //ORIGIN OF CUBE WHEN STARTING BUILDING, in (x,y,z)
movementSpeed = 0.0125;
// DETECTS LOCATION OF CURSOR, ADJUSTING THE
// DIRECTION LOOKED DEPENDING ON WHAT DIRECTION THE MOUSE IS MOVED
bool warped = false;
void passiveMotion( int x, int y )
{
if( warped )
{
// break warp loop
warped = false;
return;
}
int widthOfMonitor = glutGet( GLUT_WINDOW_WIDTH );
int heightOfMonitor = glutGet( GLUT_WINDOW_HEIGHT );
//DISPLACEMENT FROM CENTRE OF SCREEN IN X&Y
int xmpos = ( x - widthOfMonitor / 2 );
int ympos = ( y - heightOfMonitor / 2 );
//TAKE MOUSE COORDS AND SET WHOLE WINDOW TO BE LENGTH 2PI IN X AND Y
cursorAngle[0] += - ( ( xmpos * 180 / (widthOfMonitor / 2) ) * PI / 180 );
cursorAngle[1] += ( ( ympos * 180 / (heightOfMonitor / 2) ) * PI / 180 );
//DON'T ALLOW ROTATING UP PAST CEILING OR BELOW FLOOR, CAN BE DONE BUT MAKES PERSPECTIVE CONFUSING
if ( cursorAngle[1] > 0 )
cursorAngle[1] = - 1E-5;
else if ( cursorAngle[1] < -PI )
cursorAngle[1] = -( PI - 1E-5 );
//CONVERT FROM SPHERICAL POLARS INTO CARTESIANS
cameraInformation[1][0] = cos( cursorAngle[0] ) * sin( cursorAngle[1] );
cameraInformation[1][1] = sin( cursorAngle[0] ) * sin( cursorAngle[1] );
cameraInformation[1][2] = -cos( cursorAngle[1] );
//KEEP CURSOR CENTERED TO PREVENT SCREEN GETTING STUCK WHEN ROTATING PAST 2PI.
warped = true;
glutWarpPointer( widthOfMonitor / 2, heightOfMonitor / 2 );
}
// MoveForwards TRIGGERS IF W OR S IS PRESSED AND MOVES FORWARD OR BACKWARDS
// IN THE DIRECTION FACED IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE FORWARD
// OR BACKWARDS IN THE DIRECTION FACED IF CUBE IS BEING BUILT
void move_forward( float forwardsOrBackwards )
{
float changeInX, changeInY, changeInZ, length;
if ( cuboidBuilding == 0 )
{
//GO FORWARD/BACK RELATIVE TO CAMERA VIEW
changeInX = ( forwardsOrBackwards * cameraInformation[1][0] );
changeInY = ( forwardsOrBackwards * cameraInformation[1][1] );
changeInZ = ( forwardsOrBackwards * cameraInformation[1][2] );
//NORMALIZE MOVEMENT
length = sqrt ( pow ( changeInX, 2.0 ) + pow ( changeInY, 2.0 ) + pow ( changeInZ, 2.0 ) );
changeInX = changeInX / length;
changeInY = changeInY / length;
changeInZ = changeInZ / length;
//SET SENSITIVITY AND ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
cameraInformation[0][0] += changeInX * movementSpeed;
cameraInformation[0][1] += changeInY * movementSpeed;
cameraInformation[0][2] += changeInZ * movementSpeed;
}
}
// move_left TRIGGERS IF A OR D IS PRESSED AND MOVES LEFT OR RIGHT TO THE
// DIRECTION FACED IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE
// LEFT OR RIGHT OF THE DIRECTION FACED IF CUBE IS BEING BUILT
void move_left( float forwardsOrBackwards )
{
float changeInX, changeInY, length;
if ( cuboidBuilding == 0 )
{
//GO LEFT/RIGHT RELATIVE TO CAMERA VIEW
changeInX = ( -forwardsOrBackwards * cameraInformation[1][1] );
changeInY = ( forwardsOrBackwards * cameraInformation[1][0] );
//NORMALIZE MOVEMENT
length = sqrt ( pow ( changeInX, 2.0 ) + pow ( changeInY, 2.0 ) );
changeInX = changeInX / length;
changeInY = changeInY / length;
//SET SENSITIVITY AND ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
cameraInformation[0][0] += changeInX * movementSpeed;
cameraInformation[0][1] += changeInY * movementSpeed;
}
}
// move_up TRIGGERS IF Q OR E IS PRESSED AND MOVES VERTICALLY UP OR DOWN
// IF A CUBE IS NOT BEING BUILT, OR MOVES CUBE VERTICALLY UP OR DOWN IF CUBE IS BEING BUILT
void move_up( float forwardsOrBackwards )
{
//MOVEMENT AND MAKING CUBE AS THE DIRECTION MOVED IS ALWAYS PARRALEL TO Z COORDS, SO NO CONVERSION FROM CAMERA TO BOX IS REQUIRED
float changeInZ, length;
//GO UP/DOWN RELATIVE TO CAMERA VIEW
changeInZ = ( forwardsOrBackwards );
//NORMALIZE MOVEMENT
length = sqrt( pow ( changeInZ, 2.0 ) );
changeInZ = changeInZ / length;
//SET SENSITIVITY
if ( cuboidBuilding == 0 )
cameraInformation[0][2] += changeInZ * movementSpeed;
//ADD CHANGE FROM STARTING POSITION TO STARTING POSITION TO GET CURRENT POSITION
}
// keyboard TRIGGERS IF A KEY ON THE KEYBOARD IS PRESSED,
// THEN PASSES TO A FUNCTION THAT PROCESSES THE KEY PRESSED,
// ALSO UPDATES THE LOCATION OF CAMERA IF MOVEMENT KEYS ARE PRESSED
void keyboard( unsigned char key, int x, int y )
{
int forwardsOrBackwards; //FORWARD OR BACKWORDS.
//PREVENT A POTENTIAL DIVIDE BY 0 ERROR BY SETTING 0 DIRECTIONS TO VERY SMALL DIRECTIONS.
for ( int i = 0; i <= 2; i++ )
{
if ( cameraInformation[1][i] > -1E-5 && cameraInformation[1][i] < 1E-5 )
cameraInformation[1][i] = 1E-4;
}
switch ( key )
{
case 122: case 90: //z
if ( movementSpeed < 0.5 )
movementSpeed = 1.0;
else
movementSpeed = 0.025;
break;
case 119: case 52: forwardsOrBackwards = 1; move_forward ( forwardsOrBackwards ); break; //w
case 115: case 83: forwardsOrBackwards = -1;move_forward ( forwardsOrBackwards ); break; //s
case 97 : case 65: forwardsOrBackwards = 1; move_left ( forwardsOrBackwards ); break; //a
case 100: case 68: forwardsOrBackwards = -1;move_left ( forwardsOrBackwards ); break; //d
case 113: case 81: forwardsOrBackwards = -1;move_up ( forwardsOrBackwards ); break; //q
case 101: case 69: forwardsOrBackwards = 1; move_up ( forwardsOrBackwards ); break; //e
case 27 : exit ( 0 ); //esc CLOSE PROGRAM
}
if ( cuboidBuilding == 0 ) //IF NOT BUILDING A CUBE, MOVE CAMERA COORDS BY THE AMOUNT THEY HAVE CHANGED
{
for ( int i = 0; i <=2; i++)
{
cameraInformation[2][i] = ORIGINAL_CAMERA_LOCATION[i] + cameraInformation[0][i];
}
}
}
// cuboid TAKES INPUTS OF CENTER OF CUBE, SIZE OF CUBE AND COLOURS OF EACH FACE
// THEN PRODUCES A CUBE BY SPLITING EACH FACE UP INTO TWO TRIANGLES
void cuboid
(
float OCX, float OCY, float OCZ,
float xsize, float ysize, float zsize,
float TR, float TG, float TB,
float BR, float BG, float BB,
float FR, float FG, float FB,
float BWR, float BWG, float BWB,
float LR, float LG, float LB,
float RR, float RG, float RB
)
{
glBegin( GL_TRIANGLES );
//MAKE TRIANGLES IN SHAPE OF A CUBE BY SPECIFYING VERTICES OF TRIANGLES
glColor3f ( TR, TG, TB ); //TOP
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glColor3f ( BR, BG, BB ); //BOTTOM
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glColor3f ( FR, FG, FB ); //FORWARDS
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glColor3f ( BWR, BWG, BWB ); //BACKWARDS
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize);
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glColor3f ( LR, LG, LB ); //LEFT
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX - xsize, OCY + ysize, OCZ + zsize );
glColor3f ( RR, RG, RB ); //RIGHT
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY - ysize, OCZ + zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ - zsize );
glVertex3f( OCX + xsize, OCY + ysize, OCZ + zsize );
glEnd( );
}
// display TAKES THE ARRAYS OF CUBE AND MOLECULE LOCATIONS, SIZE AND
// COLOURS THEN RENDERS AND CHECKS IF MOLECULES ARE COLLIDING WITH A CUBE
void display ( )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//SET THE PERSPECTIVE
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
int widthOfMonitor = glutGet( GLUT_WINDOW_WIDTH );
int heightOfMonitor = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective( 90, //FOV
widthOfMonitor / heightOfMonitor, //DISPLAY ASPECT
0.01, //NEAR CLIP
20000.0 ); //FAR CLIP
//MOVE CAMERA
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt
(
cameraInformation[2][0], cameraInformation[2][1], cameraInformation[2][2], //Camera location
cameraInformation[2][0] + cameraInformation[1][0],
cameraInformation[2][1] + cameraInformation[1][1],
cameraInformation[2][2] + cameraInformation[1][2], //LOOK AT
0.0, 0.0, 1.0
); //VERTICAL
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glEnable( GL_DEPTH_TEST ); //RENDER OBJECTS CLOSEST TO CAMERA INFRONT OF OBJECTS FURTHER AWAY
//SET EDGES OF THE MAP
glColor3d( 1.0, 0.0, 0.0 );
cuboid
(
0.0, 0.0, 0.0,
MAPSIZE, MAPSIZE, MAPSIZE,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0
);
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main ( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
glutInitWindowSize( 600, 600 );
glutInitWindowPosition( 0, 0 );
glutCreateWindow( "SQUARE" );
glutKeyboardFunc( keyboard );
glutDisplayFunc( display );
glutPassiveMotionFunc( passiveMotion );
glutTimerFunc( 0, timer, 0 );
glutSetCursor( GLUT_CURSOR_NONE );
glutMainLoop( );
}
glutPostRedisplay是这里的主要内容。您甚至可以从显示函数内部发布它。
相关文章:
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 选择排序C++(已修改)并非适用于所有情况
- 无法让"std::enable_if"适用于无作用域枚举
- QT 样式表主题,适用于使用属性选择器的整个应用程序
- 程序只适用于包含(无副作用)cout声明
- Visual C++ wxWidgets应用程序仅适用于我的PC
- 使用程序集嵌入数据时"Undefined reference"错误,使用适用于窗口的 mingw-w64 编译(COFF 而不是 ELF)
- 为什么我的程序仅适用于调试版本
- 为什么这个C++程序适用于第一行输入,而不适用于第二行或第三行
- 适用于桌面和移动应用程序的Qt
- Clang编译器错误,适用于非常简单的程序
- 多线程程序只适用于打印语句
- 使用PostMessage模拟按键仅适用于某些应用程序
- 源代码构建中的 SCons 仅适用于可执行程序,不适用于目标文件
- 适用于多个窗口的win32程序
- 适用于应用程序级集合的适当体系结构
- GLUT程序只适用于少数帧
- 内存分析工具,适用于使用c#、c++ /CLI和非托管c++的应用程序