2017-10-08 122 views
1

我在用openGL有序地移動這些對象時遇到了問題。opengl中渲染對象的移動

我想要做的是讓每一行中的每個對象緩慢旋轉並移動屏幕的右側,當它從視圖中消失時,它應該再次出現在另一側,就像在一個循環中一樣。

空閒函數對單個對象工作正常,但它不適用於對象組。

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

GLuint objectList; 

GLfloat xRotated, yRotated, zRotated; 
GLdouble size = 0.5; 

float xpos = 0.0; 
float ypos = 0.0; 
float zpos = 0.0; 

int x = 1; 
float r, g, b; 

/* 
* Initialize depth buffer, projection matrix, light source, and lighting 
* model. Do not specify a material property here. 
*/ 
void init(void) 
{ 
    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; 
    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; 
    GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; 
    GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; 

    GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; 
    GLfloat local_view[] = { 0.0 }; 

    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 
    glLightfv(GL_LIGHT0, GL_POSITION, position); 
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 
    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); 

    glFrontFace(GL_CW); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glEnable(GL_AUTO_NORMAL); 
    glEnable(GL_NORMALIZE); 
    glEnable(GL_DEPTH_TEST); 


    objectList = glGenLists(1); 
    glNewList(objectList, GL_COMPILE); 
    glutSolidTeapot(0.5); 
    glEndList(); 
} 

/* 
* Move object into position. Use 3rd through 12th 
* parameters to specify the material property. Draw a teapot. 
*/ 
void renderObject(GLfloat x, GLfloat y, 
    GLfloat ambr, GLfloat ambg, GLfloat ambb, 
    GLfloat difr, GLfloat difg, GLfloat difb, 
    GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine) 
{ 
    GLfloat mat[4]; 

    glPushMatrix(); 
    glTranslatef(x, y, 0.0); 
    mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0; 
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat); 
    mat[0] = difr; mat[1] = difg; mat[2] = difb; 
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat); 
    mat[0] = specr; mat[1] = specg; mat[2] = specb; 
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat); 
    glMaterialf(GL_FRONT, GL_SHININESS, shine * 128.0); 
    glCallList(objectList); 
    glPopMatrix(); 
} 

void idle(void) { 

    //xRotated += 0.01; 
    yRotated += 0.01; 
    //zRotated += 0.01; 

    if (xpos > -1 && x == 1) { 

     xpos = -15; 
     ypos = 0; 

    } 
    else { 
     x = 0; 

     if (xpos <= 15) { 
      xpos += 0.001; 
      //ypos += 0.001; 
     } 
     else { 
      xpos = 1; 
      ypos = 1; 
      x = 1; 
     } 
    } 

    glutPostRedisplay(); 
} 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // glRotatef(xRotated, 1.0, 0.0, 0.0); 
    // rotation about Y axis 
    glRotatef(xRotated, 1.0, 0.0, 0.0); 
    // rotation about the Z axis 
    glRotatef(yRotated, 0.0, 1.0, 0.0); 
    // scale transformation 
    glScalef(1.0, 1.0, 1.0); 
    // glut spheres 

    renderObject(2.0, 11.0, 0.05375, 0.05, 0.06625, 
     0.18275, 0.17, 0.22525, 0.332741, 0.328634, 0.346435, 0.3); 
    renderObject(2.0, 8.0, 0.25, 0.20725, 0.20725, 
     1, 0.829, 0.829, 0.296648, 0.296648, 0.296648, 0.088); 
    renderObject(2.0, 5.0, 0.1745, 0.01175, 0.01175, 
     0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6); 

    renderObject(6.0, 11.0, 0.25, 0.25, 0.25, 
     0.4, 0.4, 0.4, 0.774597, 0.774597, 0.774597, 0.6); 
    renderObject(6.0, 8.0, 0.19125, 0.0735, 0.0225, 
     0.7038, 0.27048, 0.0828, 0.256777, 0.137622, 0.086014, 0.1); 
    renderObject(6.0, 5.0, 0.24725, 0.1995, 0.0745, 
     0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4); 


    renderObject(10.0, 11.0, 0.0, 0.0, 0.0, 
     0.1, 0.35, 0.1, 0.45, 0.55, 0.45, .25); 
    renderObject(10.0, 8.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 
     0.7, 0.6, 0.6, .25); 
    renderObject(10.0, 5.0, 0.0, 0.0, 0.0, 0.55, 0.55, 0.55, 
     0.70, 0.70, 0.70, .25); 

    renderObject(14.0, 11.0, 0.0, 0.05, 0.0, 0.4, 0.5, 0.4, 
     0.04, 0.7, 0.04, .078125); 
    renderObject(14.0, 8.0, 0.05, 0.0, 0.0, 0.5, 0.4, 0.4, 
     0.7, 0.04, 0.04, .078125); 
    renderObject(14.0, 5.0, 0.05, 0.05, 0.05, 0.5, 0.5, 0.5, 
     0.7, 0.7, 0.7, .078125); 

    renderObject(18.0, 11.0, 0.0, 0.05, 0.0, 0.4, 0.5, 0.4, 
     0.04, 0.7, 0.04, .078125); 
    renderObject(18.0, 8.0, 0.05, 0.0, 0.0, 0.5, 0.4, 0.4, 
     0.7, 0.04, 0.04, .078125); 
    renderObject(18.0, 5.0, 0.05, 0.05, 0.05, 0.5, 0.5, 0.5, 
     0.7, 0.7, 0.7, .078125); 


    glutSwapBuffers(); 
} 


void reshape(int w, int h) 
{ 
    glViewport(0, 0, (GLsizei)w, (GLsizei)h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    glOrtho(0.0, 16.0, 0.0, 16.0*(GLfloat)h/(GLfloat)w, 
      -10.0, 10.0); 

    glMatrixMode(GL_MODELVIEW); 
} 



/* 
* Main Loop 
*/ 
int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize(750, 750); 
    glutInitWindowPosition(50, 50); 
    glutCreateWindow(argv[0]); 
    init(); 
    glutReshapeFunc(reshape); 
    glutDisplayFunc(display); 
    glutIdleFunc(idle); 

    glutMainLoop(); 
    return 0; 
} 
+2

這看起來像C,甚至可能編譯爲這樣。 C++中的'stdlib.h'已被棄用C兼容性頭文件 - 使用'cstdlib'等代替,它也將東西放在'std'命名空間中。 – tambre

回答

0

您必須更改說明的順序。通過將平移矩陣乘以旋轉矩陣來執行圍繞對象軸線的旋轉。

object-matrix = translation-matrix * rotation-matrix 

enter image description here

glRotate文檔這清楚地表示:

glRotate產生角度的旋轉而繞矢量xyz。當前矩陣(見glMatrixMode)乘以旋轉矩陣,乘積代替當前矩陣。


適應你的代碼是這樣的:

void renderObject(GLfloat x, GLfloat y, 
    GLfloat ambr, GLfloat ambg, GLfloat ambb, 
    GLfloat difr, GLfloat difg, GLfloat difb, 
    GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine) 
{ 
    glPushMatrix(); 

    glTranslatef(x, y, 0.0);   // translation-matrix 
    glRotatef(yRotated, 0.0, 1.0, 0.0); // multiply by rotation-matrix 
    glRotatef(xRotated, 1.0, 0.0, 0.0); 

    ..... 
} 

注意,你的旋轉是非常輕微。出於調試原因(角度以度數指定),將yRotated += 0.01;更改爲yRotated += 1.0;

enter image description here

+0

我已經做了這些修改,現在他們正在各自的軸上旋轉。 如何讓他們從屏幕的一側向另一側移動?我對空閒功能所做的任何更改似乎都沒有效果。 – shatter

+1

啊!我只是想通了! – shatter