【问题标题】:GLUT program only works for a few framesGLUT 程序仅适用于几帧
【发布时间】:2015-08-04 15:45:26
【问题描述】:

我在 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();
}

【问题讨论】:

  • 请附上MCVE
  • 我已经这样做了,感谢您提供的任何帮助。在 MCVE 中,我主要只包含了用于移动相机的内容,因此一旦停止让您移动(因为它不再包括移动的立方体),您就看不到程序实际上仍在运行,但是它是.或者它仍然允许建造更多的墙壁。您也看不到(除非您的计算机速度非常慢)它允许您在前几帧移动相机,因为前几帧现在过得很快,但确实如此。
  • 你为什么在main()声明 glutInit()而不是调用它?
  • 你为什么不在keyboard()的第一个for循环中初始化i
  • 感谢 genpfault 的任何帮助。对不起,我对编码不太熟练,我只是在自己的时间里做这件事,只是为了好玩。我不太确定如何调用 glutInit() 并让程序仍然工作,对于键盘()中的第一个 for 循环也是如此。我没有初始化我的错误,我现在已经改变了(但我的问题仍然存在)

标签: c++ opengl glut freeglut


【解决方案1】:
  • 在调用glutInit() 之前不要使用glutGet()
  • 初始化变量
  • 使用 C++ 风格的#includes
  • 在显示回调中设置矩阵,有助于防止使用错误
  • 无需使用 Windows 来跟踪/隐藏光标,(免费)GLUT 有相应的功能
  • 把你的台词换成合理的东西
  • timerfunc 或 vsync 在电池/CPU 风扇上比空闲回调更友好

大家一起:

#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( );
}

【讨论】:

  • 非常感谢您的帮助。很抱歉要求更多,但您知道我已经拥有的代码中阻止它工作的特别是什么,以帮助我进一步从错误中吸取教训吗?我很好奇具体问题是什么。
  • @Jack:未能调用glutInit() 是一个主要问题,以及在glutInit() 之前调用glutGet()。也许您更改了 GLUT 实现?还是您的 GL 实施?使用合成窗口管理器开始/停止?调整大小和显示回调之间的矩阵处理代码的拆分也有点时髦。遗憾的是,我没有要检查您的系统,所以我不能确定:(
  • 我现在尝试更改它,以便 1) 我调用 glutInit() 和 2) 在 glutInit 之后调用 glutGet(),但它仍然无法仅使用该更改。我将尝试根据您建议的更改一次更改一些位,看看我是否能找到使它起作用的原因。我肯定在使用相同的 GLUT 和 GL 实现(我知道一个事实,因为我现在把这个程序拿回来了,因为我用 zip 文件将它通过电子邮件发送给了某人,包括我刚刚用来获得 GLUT 和 OPENGL 的 GLUT 和 GL 实现在新计算机上)再次感谢您的所有帮助,您帮了大忙。
  • 我已将此标记为正确答案(因为它是:))
【解决方案2】:

glutPostRedisplay 是这里的主要内容。您甚至可以从显示功能内部发布它。没有它是行不通的。

【讨论】:

    猜你喜欢
    • 2013-07-27
    • 1970-01-01
    • 2011-10-27
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多