简体   繁体   English

天空盒纹理未显示在opengl中

[英]skybox textures not showing in opengl

I have a simple skybox . 我有一个简单的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() {};
};

I load textures using devIL lib in method loadTextures . 我在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;
}

where function loadTexture 其中的功能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);
}

In my main.cpp I declare skybox object as a global variable and render it in method draw main.cpp我将skybox对象声明为全局变量,并在draw方法中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 method 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();
};

When I draw other objects - It is seen that skybox appears to be black 当我绘制其他对象时-可以看到天空盒看起来是黑色的 在此处输入图片说明 What is the problem? 问题是什么? Why it is black? 为什么是黑色?

edit I've added project in case if somebody decides to look into problem with more details. 编辑我添加了项目,以防万一有人决定调查更多细节的问题。 There project and glm, assimp, devil, freeglut libs. 有项目和glm,aspimp,恶魔,freeglut库。 Project is not finished but it should work. 项目尚未完成,但应该可以正常工作。

http://www.filedropper.com/task http://www.filedropper.com/task

There are two strategies on drawing a skybox: 绘制天空盒有两种策略:

  • use the skybox for "clearing": You draw the skybox as the first thing in your scene. 使用天空盒进行“清除”:将天空盒绘制为场景中的第一件事。 Before drawing the skybox call glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); 在绘制天空盒之前, glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE);调用glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); , then draw the skybox and reenable depth testing ( glEnable(GL_DEPTH_TEST) ) and depth writes ( glDepthMask(GL_FALSE) ) as needed ,然后根据需要绘制天空盒并重新启用深度测试( glEnable(GL_DEPTH_TEST) )和深度写入( glDepthMask(GL_FALSE)

  • draw the skybox after the last opaque, but before blended geometry (requires support for depth clamping). 在最后一个不透明物体之后,但在混合几何体之前绘制天空盒(需要支持深度夹紧)。 Clear the scene with the depth buffer cleared to (pow(2, b)-1.)/pow(2, b) where b is the bit depth of the depth buffer. 在深度缓冲区被清除为(pow(2, b)-1.)/pow(2, b)下清除场景,其中b是深度缓冲区的位深度。 Draw the opaque scene as usual. 照常绘制不透明场景。 Enable depth clamping and depth test set the depth test function to greater or equal ( glDepthFunc(GL_GEQUAL) ) and setup a projection, or scale up the skybox, so that the skybox quads will always stay behind the far clipping plane. 启用深度夹紧和深度测试,将深度测试功能设置为大于或等于( glDepthFunc(GL_GEQUAL) )并设置投影或缩放天空盒,以便天空盒四边形始终位于远剪切平面之后。 Due to depth clamping the generated fragment depths with all be 1.0 passing the depth test rendering the skybox only at those areas of the screen, not covered by other geometry. 由于进行了深度夹紧,因此生成的片段深度全部为1.0,通过了深度测试,仅在屏幕的那些区域渲染了天空盒,而其他几何图形均未覆盖这些区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM