我有一个简单的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,通过了深度测试,仅在屏幕的那些区域(没有其他几何图形覆盖)渲染天空盒。