рандомный перевод в GLUT становится плохим

это мой куб. После создания он имеет случайную позицию x на -2, -1, 0, 1 или 2.

void cube(void)
{
    srand (time(0));

    int cube_posX;
    int lowv = -2;
    int highv = 2;

    cube_posX = rand() % (highv - lowv + 1) + lowv;

    glTranslatef(cube_posX, 0.0, cube_angle);
    glRotatef(cube_angle, 90.0, 0.0, 1.0);
    glutSolidCube(0.25);
}

и вот как я медленно двигаю куб вперед

void MOVE_CUBE(int value)
{
    cube_posZ = cube_posZ - 0.01;
    glutPostRedisplay();
    glutTimerFunc(25, MOVE_CUBE, 0);
}

и, наконец, отображая их:

void init(void)
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}

float cam_eyeX = 0.0, cam_eyeY = 1.5, cam_eyeZ = 5.0;
float cam_centerX = 0.0, cam_centerY = 0.0, cam_centerZ = 0.0;
void display(void)
{
    glClearColor(1.0,1.0,1.0,1.0);      //to add background color (white)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);  //camera! (cam position X, cam position Y, cam position Z, cam target X, cam target Y, cam target Z,  up position X, up position Y, up position Z)

    cube();

    glutSwapBuffers();
    angle += 0.05; //to affect the glRotate function
    glFlush();
}

void reshape(int w, int h)
{
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}


int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);      // Set up display buffer 
    glutInitWindowSize(750, 500);       //window's size
    glutInitWindowPosition(100, 100);   //window's position
    glutCreateWindow("Hendra Ganteng!");  //window's title
    init();
    glutDisplayFunc(display);
    glutIdleFunc (display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard_Handler);

    MOVE_CUBE(0);

    glutMainLoop();
    return 0;
}

Но когда я вижу его в действии, куб движется безупречно, но продолжает менять положение x на эти 5 возможностей (-2,-1,0,1,2) каждые 0,5–1 секунду. Если я отключу srand(time(0)), куб быстро изменит свою позицию x. Я просто хочу, чтобы он оставался в позиции 1 x, чтобы я мог вызывать больше кубов в другой позиции x. Может кто-нибудь, пожалуйста, что не так в моем коде?


person Hendra Anggrian    schedule 04.06.2013    source источник


Ответы (1)


Как такое поведение не ожидается? Вы генерируете случайную позицию X каждый раз, когда отображаете свой куб. Если вы повторно запустите генератор случайных чисел, используя время, то он будет запускать другую последовательность при каждом изменении времени (один раз в секунду).

Вместо этого вы должны предварительно сгенерировать куб(ы). Как насчет этого:

// Global cube data
struct Cube {
    int x;
    double angle;
};

vector<Cube> cubes;
const int num_cubes = 1;

// Example initialisation...
void InitCubes()
{
    cubes.reserve(num_cubes);

    for( int i = 0; i < num_cubes; i++ )
    {
        Cube cube;
        cube.x = rand() % (highv - lowv + 1) + lowv;
        cube.angle = 0.0;
        cubes.push_back(cube);
    }
}

Теперь циклам обновления/отображения просто нужно изменить угол, но не положение x.

void UpdateCube( Cube & cube )
{
    cube.angle += 0.05;
}

void DisplayCube( Cube & cube )
{
    glTranslatef((double)cube.x, 0.0, cube.angle);
    glRotatef(cube.angle, 90.0, 0.0, 1.0);
    glutSolidCube(0.25);
}

В функции main вызовите InitCubes() во время запуска.

В своей функции display сделайте следующее:

void display(void)
{
    glClearColor(1.0,1.0,1.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);    

    // Display cubes        
    for( int i = 0; i < cubes.size(); i++ ) DisplayCube( cubes[i] );

    glutSwapBuffers();
    glFlush();

    // Update cubes for next render cycle.
    for( int i = 0; i < cubes.size(); i++ ) UpdateCube( cubes[i] );
}
person paddy    schedule 04.06.2013
comment
У меня, кажется, проблема с предварительной генерацией куба, я не понимаю, к какому разделу относится зацикливание for. Я скопировал и вставил ваш код под функцией отображения пустоты (void) в моем исходном коде выше, в результате кубы по-прежнему быстро переключают позицию x. Я не такой эксперт по программированию, как многие здесь, я был бы признателен за более простое объяснение . Спасибо! - person Hendra Anggrian; 04.06.2013
comment
Когда мы говорим о генерации, и особенно о предварительной генерации, мы имеем в виду сделать это один раз перед любым оставшимся кодом. Это означает, что не генерируйте внутри вашей функции display. Суть в том, что вы создаете куб в случайном месте один раз, а затем обновляете и отображаете его много раз. - person paddy; 05.06.2013
comment
Вам нужно передать Cube экземпляр в функцию! Я отредактировал свой ответ, чтобы попытаться сделать очевидным, как вы должны использовать код. - person paddy; 05.06.2013
comment
это очень мило с твоей стороны, я очень ценю это. Но каким-то образом кубы остаются в той же позиции x = 1. Независимо от того, сколько num_cubes я добавляю или сколько раз я пытался запустить его, позиция x теперь остается равной 1.. - person Hendra Anggrian; 06.06.2013
comment
Убедитесь, что вы не используете эти старые переменные положения и угла во время отображения. Легко случайно забыть использовать новые (в структуре Cube). Если вы сомневаетесь, не стесняйтесь редактировать свой вопрос и опубликовать свой текущий код. Еще одна вещь, которую следует учитывать, это то, что если у вас есть только один куб, вам нужно заполнить генератор случайных чисел — общий способ сделать это — srand(time(0));. Сделайте это один раз в начале вашей программы, прежде чем будут сделаны какие-либо вызовы rand(). - person paddy; 06.06.2013
comment
полностью работает после нескольких минут, пытаясь понять логику, спасибо за помощь! - person Hendra Anggrian; 06.06.2013
comment
о, у меня есть еще 1 проблема: я использовал glutTimerFunc, чтобы плавно перемещать положение куба по оси z (см. мою функцию MOVE_CUBE выше). можно ли его как-то использовать в нескольких кубах в вашем коде? или мне нужно найти другой способ сделать это? - person Hendra Anggrian; 06.06.2013
comment
Вот тут-то и пригодится ваша функция обновления. Просто добавьте позицию z в структуру Cube и соответствующим образом обновите ее. Вместо того, чтобы вызывать UpdateCube из функции display, возможно, вы захотите вызвать ее из MOVE_CUBE. - person paddy; 06.06.2013