Clint
Clint

Reputation: 175

3d cube jumps on x-axis when I use glutIdleFunc to try and place cube on different x-axis

I am using the rand() functions to place my cubes in different spots on the screen. The reason being is I have to have a random amount of cubes on the screen and I do not want them all to start in the same spot. What is happening is when I run the program the cube jumps on all over the screen because of the glutPostRedisplay() in which I need for the rotation of the cubes. My question is how can I have, say for example, 7 cubes starting at 7 different spots on the screen while all are rotating? I eventually need them to move from their starting spots along the z-axis off the screen and then start over the process all over?

Here is the code I have:

/* -- GLOBAL VARIABLES --------------------------------------------------------------------------    --------------- */

GLint screenWidth = 500;
GLint screenHeight = 500;
GLfloat cubeX = 0.0;
GLfloat cubeY = 5.0;
GLfloat cubeZ = -20.0;
GLfloat rotateY = 0.0;
//GLfloat rotCube = 0.0;
GLint cubeCount = 0;
//const GLint CUBE_LOW = 7;
//const GLint CUBE_HIGH = 15;
const GLint CUBE_HIGH = 15;
const GLint CUBE_LOW = 7;
const GLfloat X_HIGH = 10.0;
const GLfloat X_LOW = -10.0;
const GLfloat Y_HIGH = 10.0;
const GLfloat Y_LOW = -10.0;

/* -- NAMESPACE ---------------------------------------------------------------------------------    --------------- */

using namespace std;

/* ----------------------------------------------------------------------------------------------    -------------- */
/*
Function:   unsigned time_seed()
*/

unsigned time_seed()
{
    time_t now = time (0);
    unsigned char *p = (unsigned char *)&now;
    unsigned seed = 0;
    size_t i;

    for(i = 0; i < sizeof now; i++)
        seed  = seed * (UCHAR_MAX + 2U) + p[i];

    return seed;
}

/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   void rotateCube()
*/

 void rotateCube()
{
    rotateY += 0.050f;
    if(rotateY > 360.0f)
        rotateY -= 360.0f;
    glutPostRedisplay();
}

/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   void myDisplay()
*/

void myDisplay()
{
cubeCount = CUBE_LOW + rand() / RAND_MAX * (CUBE_HIGH - CUBE_LOW);
float cubeX = X_LOW + (float)rand() / (float)RAND_MAX * (X_HIGH - X_LOW);
float cubeY = Y_LOW + (float)rand() / (float)RAND_MAX * (Y_HIGH - Y_LOW);

for(int i = 0; i < cubeCount; i++)
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(cubeX, cubeY, cubeZ);
    glRotatef(rotateY, 0.0f, 1.0f, 0.0f);

    glutWireCube(2.0f);
    glutSwapBuffers();
    glFlush();


}
}

/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   int main( int argc, char **argv )
*/

void myReshape(int width, int height)
{
    glViewport(0, 0, (GLsizei)width, (GLsizei)height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100);
    glMatrixMode(GL_MODELVIEW);
}
/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   int main( int argc, char **argv )
*/

int main( int argc, char **argv )
{
    srand(time_seed());
    glutInit( &argc, argv );
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(100, 40);
    glutCreateWindow("Boxes!");
    glutDisplayFunc(myDisplay);
    glutIdleFunc(rotateCube);
    glutReshapeFunc(myReshape);
    glutMainLoop();

   return 0;
}

Upvotes: 0

Views: 155

Answers (2)

enhzflep
enhzflep

Reputation: 13109

Further to what qternion said, you may wish to try the following code. I added a user-defined type - vec3. I hard-coded the number of cubes, I added a single call to position all of the cubes at program start.

#include <GL/glut.h>
#include <stdlib.h>
#include <time.h>


/* -- GLOBAL VARIABLES --------------------------------------------------------------------------    --------------- */

GLint screenWidth = 500;
GLint screenHeight = 500;
GLfloat cubeX = 0.0;
GLfloat cubeY = 5.0;
GLfloat cubeZ = -20.0;
GLfloat rotateY = 0.0;
//GLfloat rotCube = 0.0;
GLint cubeCount = 0;
//const GLint CUBE_LOW = 7;
//const GLint CUBE_HIGH = 15;
const GLint CUBE_HIGH = 15;
const GLint CUBE_LOW = 7;
const GLfloat X_HIGH = 10.0;
const GLfloat X_LOW = -10.0;
const GLfloat Y_HIGH = 10.0;
const GLfloat Y_LOW = -10.0;

const int maxCubes = 50;

typedef struct vec3
{
    double x, y, z;
};

vec3 cubeOrigins[maxCubes];

/* -- NAMESPACE ---------------------------------------------------------------------------------    --------------- */

using namespace std;


void initOrigins()
{
    int i;
    for (i=0; i<maxCubes; i++)
    {
        cubeOrigins[i].x = X_LOW + (float)rand() / (float)RAND_MAX * (X_HIGH - X_LOW);
        cubeOrigins[i].y = Y_LOW + (float)rand() / (float)RAND_MAX * (Y_HIGH - Y_LOW);
    }
}

/* ----------------------------------------------------------------------------------------------    -------------- */
/*
Function:   unsigned time_seed()
*/


unsigned time_seed()
{
    time_t now = time (0);
    unsigned char *p = (unsigned char *)&now;
    unsigned seed = 0;
    size_t i;

    for(i = 0; i < sizeof now; i++)
        seed  = seed * (255 + 2U) + p[i];

    return seed;
}


/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   void rotateCube()
*/

 void rotateCube()
{
    rotateY += 0.050f;
    if(rotateY > 360.0f)
        rotateY -= 360.0f;
    glutPostRedisplay();
}

/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   void myDisplay()
*/

void myDisplay()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    for(int i = 0; i < maxCubes; i++)
    {
        glLoadIdentity();

        glTranslatef(cubeOrigins[i].x, cubeOrigins[i].y, cubeZ);
        glRotatef(rotateY, 0.0f, 1.0f, 0.0f);

        glutWireCube(2.0f);
    }
    glutSwapBuffers();
    glFlush();
}

/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   int main( int argc, char **argv )
*/

void myReshape(int width, int height)
{
    glViewport(0, 0, (GLsizei)width, (GLsizei)height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100);
    glMatrixMode(GL_MODELVIEW);
}
/* ----------------------------------------------------------------------------------------------    --------------- */
/*
Function:   int main( int argc, char **argv )
*/

int main( int argc, char **argv )
{
    srand(time_seed());
    initOrigins();

    glutInit( &argc, argv );
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(100, 40);
    glutCreateWindow("Boxes!");
    glutDisplayFunc(myDisplay);
    glutIdleFunc(rotateCube);
    glutReshapeFunc(myReshape);
    glutMainLoop();

   return 0;
}

Upvotes: 1

qternion
qternion

Reputation: 526

Your cubes are using the same coordinates, it seems, since you set cubeX and cubeY before your loop. You can set the coordinates inside that for loop that iterates on all the cubes to ensure all have a different one. In addition, you probably shouldn't do glClear() within the loop (do it outside) unless you only want to draw the one cube at 7 different positions. glClear() will clear your whole screen.

Upvotes: 2

Related Questions