OpenGL:使用正交投影进行轨道运算

时间:2015-05-08 15:46:34

标签: c++ opengl

我正在使用正交投影对太阳系进行建模并测试太阳周围地球的轨道。

地球的起点是太阳的右侧,移动的方向是左侧。但是当地球在太阳前面并且在太阳背后更远时,地球并没有被完全渲染,正如你从下面的3张图片中看到的那样:

起点:

enter image description here

下一帧:

enter image description here

最后一帧:

enter image description here

有人可以解释这里究竟发生了什么吗?我认为这是剔除脸的问题,我试过了:

glEnable(GL_CULL_FACES);
glCullFace(GL_FRONT);

它实际上不起作用。

这是我的代码:

// global vars
int width = 1820, height = 960;
#define CENTRE_X static_cast<float>(width/2)
#define CENTRE_Z static_cast<float>(-height/2)
#define EARTH_SIZE glm::vec3(30.0f, 40.0f, 30.0f)
#define SUN_SIZE EARTH_SIZE*3.0f

void renderSun(int i){
    glPushMatrix();
    glLoadIdentity();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_ID[0]);
    glUniform1i(texture_Location, 0);
    glm::mat4 Projection = glm::ortho(0.0f, static_cast<float>(width), 0.0f, static_cast<float>(height), 0.0f, 100.0f);
    glm::mat4 View = glm::lookAt(
        glm::vec3(0, 120, 1),
        glm::vec3(0, 0, 0),
        glm::vec3(0, 1, 0)
    );

    /* Animations */
    GLfloat angle = (GLfloat) (i);
    View = glm::translate(View, glm::vec3(static_cast<float>(width/2), 0.0f, static_cast<float>(-height/2)));
    View = glm::scale(View, SUN_SIZE);
    View = glm::rotate(View, angle * 0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
    /* ******* */
    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 MVP = Projection * View * Model;

    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
    glDrawElements(GL_TRIANGLES, numsToDraw, GL_UNSIGNED_INT, NULL);
    glPopMatrix();
}

void renderEarth(int i){
    glPushMatrix();
    glLoadIdentity();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_ID[3]);
    glUniform1i(texture_Location, 0);
    glm::mat4 Projection = glm::ortho(0.0f, static_cast<float>(width), 0.0f, static_cast<float>(height), 0.0f, 100.0f);
    glm::mat4 View = glm::lookAt(
        glm::vec3(0, 150, 1),
        glm::vec3(0, 0, 0),
        glm::vec3(0, 1, 0)
    );

    /* Animations */
    GLfloat angle = (GLfloat) (i);
    View = glm::translate(View, glm::vec3(cos(orbitPos)*150, sin(orbitPos)*150, 0.0f));
    View = glm::translate(View, glm::vec3(CENTRE_X, 0.0f, CENTRE_Z));
    View = glm::scale(View, EARTH_SIZE);
    View = glm::rotate(View, angle * 0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
    /* ******* */
    glm::mat4 Model = glm::mat4(1.0f);
    orbitPos += 0.005;
    glm::mat4 MVP = Projection * View * Model;

    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
    glDrawElements(GL_TRIANGLES, numsToDraw, GL_UNSIGNED_INT, NULL);
    glPopMatrix();
}

1 个答案:

答案 0 :(得分:1)

您正在使用不一致的View矩阵,您的代码基本上是旋转地球的视图,这会导致它相对于太阳移动。这是非常不寻常的做事方式,可能是您遇到问题的原因。它(推测)导致模型在剪辑空间中碰撞,并且彼此相交。您应该为两者使用相同的View矩阵,并修改地球模型的Model矩阵。保持renderSun方法相同,您可以通过修改renderEarth

来执行此操作
void renderEarth(int i){
//...
/* Animations */
GLfloat angle = (GLfloat) (i);
glm::mat4 M0 = glm::translate(View, glm::vec3(cos(orbitPos)*150, sin(orbitPos)*150, 0.0f));
glm::mat4 M1 = glm::translate(View, glm::vec3(CENTRE_X, 0.0f, CENTRE_Z));
glm::mat4 M2 = glm::scale(View, EARTH_SIZE);
glm::mat4 M3 = glm::rotate(View, angle * 0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
/* ******* */
orbitPos += 0.005;
glm::mat4 MVP = Projection * View * M3 * M2 * M1 * M0;
// ...
相关问题