我有一个简单的skybox

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>
#include <iostream>

#include "texture.h"
#include "deviLoader.h"

using namespace std;

static std::vector<GLuint> textures;

class Skybox
{
private:
float x, y, z;
float width, height, length;
bool isBottomRequired;
void rearrange();
void loadTextures();
public:
Skybox() {};
Skybox(float x,
        float y,
        float z,
        float width,
        float height,
        float length);
void renderSkybox();
void setBottom(bool required);
~Skybox() {};
};


我在方法loadTextures中使用devIL lib加载纹理。

void Skybox::loadTextures()
{
cout<<"SKYBOX: texture loading...";

Texture t;
LoadTexture(IL_BMP, "Back.bmp", &t);
textures.push_back(t.texID);

LoadTexture(IL_BMP, "Front.bmp", &t);
textures.push_back(t.texID);

LoadTexture(IL_BMP, "Bottom.bmp", &t);
textures.push_back(t.texID);

LoadTexture(IL_BMP, "Top.bmp", &t);
textures.push_back(t.texID);

LoadTexture(IL_BMP, "Left.bmp", &t);
textures.push_back(t.texID);

LoadTexture(IL_BMP, "Right.bmp", &t);
textures.push_back(t.texID);

/*
LoadTexture(IL_BMP, "Back.bmp", &t);
textures[0] = t.texID;
*/

cout<<"SUCCESS"<<endl;
}


函数loadTexture

void LoadTexture(ILenum FileType, char *filename, Texture *texture)
{
ilInit();
iluInit();

ilLoad(FileType, filename);

int err = ilGetError();
if (err != IL_NO_ERROR)
{
    const char* strError = iluErrorString(err);
    cout<<strError<<" - error during loading!"<<endl;
    return;
}

texture->width = ilGetInteger(IL_IMAGE_WIDTH);
texture->height = ilGetInteger(IL_IMAGE_HEIGHT);
texture->bpp = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);

texture->imageData = ilGetData();

ilEnable(IL_CONV_PAL);

unsigned int type = ilGetInteger(IL_IMAGE_FORMAT);

glGenTextures(1, &texture->texID);
glBindTexture(GL_TEXTURE_2D, texture->texID);

gluBuild2DMipmaps(GL_TEXTURE_2D, texture->bpp, texture->width, texture->height,
    type, GL_UNSIGNED_BYTE, texture->imageData);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}


在我的main.cpp中,我将skybox对象声明为全局变量,并在方法draw中进行渲染

Skybox skyBox;
.....
//part of method draw
if (selected[7] == 1) {
    glDisable(GL_FOG);
    glEnable(GL_TEXTURE_2D);
    glPushMatrix();
        glTranslatef(-0.2, 4, 2.3);
        glScalef(0.15, 0.2, 0.19);
        skyBox.renderSkybox();
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
    if (selected[6] == 1)
        glEnable(GL_FOG);
}


renderSkybox方法

void Skybox::renderSkybox()
{
glBindTexture(GL_TEXTURE_2D, textures[0]);
glBegin(GL_QUADS);
    glTexCoord2f(1.0, 0.0); glVertex3f(x + width, y, z);
    glTexCoord2f(1.0, 1.0); glVertex3f(x + width, y + height, z);
    glTexCoord2f(0.0, 1.0); glVertex3f(x, y + height, z);
    glTexCoord2f(0.0, 0.0); glVertex3f(x, y, z);
glEnd();

glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z + length);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z + length);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,z + length);
glEnd();

if (isBottomRequired)
{
    glBindTexture(GL_TEXTURE_2D, textures[2]);
    glBegin(GL_QUADS);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,z);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y,z + length);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y,z + length);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,z);
    glEnd();
}

glBindTexture(GL_TEXTURE_2D, textures[3]);
glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z + length);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y + height,z + length);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height,z);
glEnd();

glBindTexture(GL_TEXTURE_2D, textures[4]);
glBegin(GL_QUADS);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height,z);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height,z + length);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y,z + length);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,z);
glEnd();

glBindTexture(GL_TEXTURE_2D, textures[5]);
glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,z);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,z + length);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height,z + length);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height,z);
glEnd();
};


当我绘制其他对象时-可以看到天空盒看起来是黑色的

问题是什么?为什么是黑色?

编辑我添加了项目,以防万一有人决定调查更多细节的问题。有项目和glm,aspimp,恶魔,freeglut库。项目尚未完成,但应该可以正常工作。

http://www.filedropper.com/task

最佳答案

绘制天空盒有两种策略:


使用天空盒进行“清除”:将天空盒绘制为场景中的第一件事。在绘制天空盒调用glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE);之前,然后绘制天空盒并根据需要重新启用深度测试(glEnable(GL_DEPTH_TEST))和深度写入(glDepthMask(GL_FALSE)
在最后一个不透明物体之后,但在混合几何体之前绘制天空盒(需要支持深度夹紧)。将深度缓冲区清除为(pow(2, b)-1.)/pow(2, b)清除场景,其中b是深度缓冲区的位深度。照常绘制不透明场景。启用深度夹紧和深度测试,将深度测试功能设置为大于或等于(glDepthFunc(GL_GEQUAL))并设置投影或按比例缩放天空盒,以便天空盒四边形始终位于远剪切平面之后。由于进行了深度夹紧,因此生成的片段深度全部为1.0,通过了深度测试,仅在屏幕的那些区域(没有其他几何图形覆盖)渲染天空盒。

10-08 08:42