3D-куб прыгает по оси X, когда я использую glutIdleFunc, чтобы попытаться разместить куб на другой оси X

0

Я использую функции rand() для размещения кубов в разных местах на экране. Причина в том, что я должен иметь случайное количество кубов на экране, и я не хочу, чтобы все они начинались в одном и том же месте. Что происходит, когда я запускаю программу, куб прыгает по всему экрану из-за glutPostRedisplay(), в котором мне нужно для вращения кубов. Мой вопрос: как я могу сказать, например, 7 кубов, начиная с 7 разных мест на экране, пока все вращаются? В конечном итоге им нужно, чтобы они переместились со своих стартовых пятен вдоль оси z с экрана, а затем начали весь процесс?

Вот код, который у меня есть:

/* -- 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;
}
Теги:
opengl

2 ответа

1
Лучший ответ

В дополнение к тому, что сказал qternion, вы можете попробовать следующий код. Я добавил пользовательский тип - vec3. Я жестко закодировал количество кубов, я добавил один вызов для размещения всех кубов при запуске программы.

#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;
}
  • 0
    Благодарю вас! Я понимаю и ценю это!
  • 0
    Не за что. :) Но, если честно, qternion сделал тяжелую работу. Я просто увеличил выделенные области - мне даже не приходилось задумываться, почему это работает не так, как хотелось бы. Я действительно предоставил компилируемый пример, но (я думаю) qternion сделал всю работу.
2

Кажется, что ваши кубы используют одни и те же координаты, поскольку вы устанавливаете cubeX и cubeY перед своим циклом. Вы можете установить координаты внутри цикла for, который выполняет итерацию во всех кубах, чтобы убедиться, что все они имеют другой. Кроме того, вы, вероятно, не должны делать glClear() внутри цикла (делать это снаружи), если только вы не хотите нарисовать один куб на 7 разных позициях. glClear() очистит весь экран.

  • 0
    Хорошо подмечено. : thumbs-up: Получил мой голос и пример, основанный на ваших наблюдениях.
  • 0
    Благодарю вас! Я ценю наблюдения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню