我正在使用正交投影对太阳系进行建模并测试太阳周围地球的轨道。
地球的起点是太阳的右侧,移动的方向是左侧。但是当地球在太阳前面并且在太阳背后更远时,地球并没有被完全渲染,正如你从下面的3张图片中看到的那样:
起点:
下一帧:
最后一帧:
有人可以解释这里究竟发生了什么吗?我认为这是剔除脸的问题,我试过了:
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();
}
答案 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;
// ...