c++ - 如何使用 openGL 正确定位天空盒相机

标签 c++ opengl skybox

我为我的项目创建了一个天空盒,它看起来是我想要的样子;但是,有一些问题我不知道如何解决,我已经阅读了一些关于这个主题的教程,但是我找不到对我有帮助的东西。 第一个问题是我不知道如何让盒子始终随着我的相机移动。在下图中,您可以看到我能够缩小并看到整个盒子,而不是只放大/缩小太阳系并始终将星星放在背景上。

enter image description here

我遇到的另一个问题是,当我放大得太近时,我的背景消失了。下图说明了我的意思 enter image description here

我知道如果我能让相机正常工作,我就能解决这个问题,但这又回到了我的第一个问题。我不知道如何访问相机信息。

我相信我必须将代码中的 glTranslatef()glScalef() 从固定数字修改为随相机位置变化的数字。 这是我的代码:

void Skybox::displaySkybox() 
{

Images::RGBImage test[6]; //6 pictures for 6 sides
test[0]=Images::readImageFile(fileName); //Top
//test[1]=Images::readImageFile(fileName);//Back
//test[2]=Images::readImageFile(fileName);//Bottom
//test[3]=Images::readImageFile(fileName);//Right
//test[4]=Images::readImageFile(fileName); //Left
//test[5]=Images::readImageFile(fileName);  //Front

glEnable(GL_TEXTURE_2D);    

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
test[0].glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);

// Save Current Matrix
glPushMatrix();

// Second Move the render space to the correct position (Translate)
glTranslatef(0,0,0);

// First apply scale matrix
glScalef(10000,10000,10000);

 static const GLint faces[6][4] =
                {
                {5, 1, 2, 6}, // back
                {5, 4, 0, 1}, // bottom
                {0, 4, 7, 3}, // front
                {4, 5, 6, 7}, // right ( 'left' in crinity's labeling )
                {1, 0, 3, 2}, // left  ( 'right' in crinity's labeling )
                {2, 3, 7, 6}  // top*/
                };
GLfloat v[8][3];
GLint i;

v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;  // min x
v[4][0] = v[5][0] = v[6][0] = v[7][0] =  1;  // max x
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;  // min y
v[2][1] = v[3][1] = v[6][1] = v[7][1] =  1;  // max y
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -1;  // min z
v[1][2] = v[2][2] = v[5][2] = v[6][2] =  1;  // max z

for (i = 0; i < 7; i++) 
{
    //
    glBegin(GL_QUADS);

    glTexCoord2f(0,1);  glVertex3fv(&v[faces[i][0]][0]);
glTexCoord2f(1,1);  glVertex3fv(&v[faces[i][1]][0]);
glTexCoord2f(1,0);  glVertex3fv(&v[faces[i][2]][0]);
glTexCoord2f(0,0);  glVertex3fv(&v[faces[i][3]][0]);

    glEnd();
}
// Load Saved Matrix
glPopMatrix();

}

我怎样才能访问这些变量? openGL是否已经有一个函数可以处理这个问题?

最佳答案

I believe I would have to modify glTranslatef() and glScalef() in my code from a fixed number to a number that changes with the camera position.

你很接近,但还有一个更简单的解决方案:

  1. 先绘制天空盒,然后再平移相机,这样您就不必平移该框。不要忘记为每个新帧清除深度缓冲区(稍后您就会明白为什么)。

  2. 禁止写入深度缓冲区(调用 glDepthMask(GL_FALSE))。这将导致您渲染的所有其他对象都绘制在它上面,使其始终出现在其他所有对象的“后面”。

  3. 假设您的变换矩阵在帧开始时被重置,则仅应用相机的旋转。这样相机将始终在盒子内“居中”。

  4. 绘制天空盒。由于对深度缓冲区的写入已关闭,因此只要它大于相机的近裁剪平面,它有多小都没有关系。

  5. 重新启用对深度缓冲区的写入(调用 glDepthMask(GL_TRUE))

  6. 正常渲染场景。

关于c++ - 如何使用 openGL 正确定位天空盒相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16841732/

相关文章:

unity-game-engine - 为什么我添加 urp 包后我的天空盒就消失了?

unity3d - 如何使用 Unity 5 程序天空盒添加夜空?

c++ - 编写代码,不会导致很多页面错误

opengl - 为什么我必须计算模型矩阵的逆矩阵的转置才能计算反射纹理的法线?

C++ 创建一个 vector 大小的数组,然后将 vector 复制到 C 样式数组中

c++ - 我想删除字符串中的撇号,但不起作用

c++ - C++ static 与 C 中的 static 相同吗?

c++ - 如何像普通 C 函数一样使用正确的 'this' 指针调用 C++ 类成员函数? (指向类成员函数的指针)

opengl - 更详细地了解缓冲区交换

c++ - Opengl 在移动 3D 场景中绘制 2D 矩形