การแปลแบบสุ่มใน 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 ของมันอย่างรวดเร็ว ผมแค่อยากให้มันอยู่ในตำแหน่ง x 1 แล้วผมจะเรียกลูกบาศก์มากขึ้นในตำแหน่ง 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);
}

ในฟังก์ชัน หลัก ให้โทร InitCubes() ระหว่างการเริ่มต้น

ในฟังก์ชัน จอแสดงผล ให้ทำดังนี้:

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 looping อยู่ในส่วนใด ฉันคัดลอกและวางโค้ดของคุณใต้ฟังก์ชัน void display (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 เพื่อย้ายตำแหน่ง cube z ได้อย่างราบรื่น (ดูฟังก์ชันของฉัน MOVE_CUBE ด้านบน) มันสามารถใช้ในหลาย ๆ คิวบ์ในรหัสของคุณได้ไหม? หรือฉันต้องหาวิธีอื่นในการทำเช่นนั้น? - person Hendra Anggrian; 06.06.2013
comment
นั่นคือที่มาของฟังก์ชันการอัปเดตของคุณ เพียงเพิ่มตำแหน่ง z ให้กับโครงสร้าง Cube แล้วอัปเดตตามนั้น แทนที่จะเรียก UpdateCube จากฟังก์ชัน display ของคุณ บางทีคุณอาจต้องการโทรจาก MOVE_CUBE - person paddy; 06.06.2013