C++ Can';在OpenGL中渲染Skybox

C++ Can';在OpenGL中渲染Skybox,c++,opengl,rendering,skybox,C++,Opengl,Rendering,Skybox,没有可见的skybox,但代码似乎工作正常 这就是我最终看到的: 我是OpenGL新手,所以这可能是GL代码绑定或位置的问题。有关完整代码,您可以访问: 这是我的班级Skybox: class Skybox { public: Skybox(); ~Skybox(); void Draw(const glm::mat4& view, const glm::mat4& projection); private: unsigned int cub

没有可见的skybox,但代码似乎工作正常

这就是我最终看到的:

我是OpenGL新手,所以这可能是GL代码绑定或位置的问题。有关完整代码,您可以访问:

这是我的班级Skybox:

class Skybox
{
public:
    Skybox();
    ~Skybox();

    void Draw(const glm::mat4& view, const glm::mat4& projection);

private:
    unsigned int cubemapTexture;

    GLuint VAO;
    GLuint VBO;

    Shader* shader;

    GLuint loadCubemap(std::vector<std::string> faces);
};
和类实现:

Skybox::Skybox()
{
    GLfloat skyboxVertices[108] = 
    {
        // positions          
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f,  1.0f
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    std::vector<std::string> faces
    {
        "Resources/skybox/right.jpg",
        "Resources/skybox/left.jpg",
        "Resources/skybox/top.jpg",
        "Resources/skybox/bottom.jpg",
        "Resources/skybox/front.jpg",
        "Resources/skybox/back.jpg"
    };

    cubemapTexture = loadCubemap(faces);

    shader = new Shader("Resources/Shaders/skybox.vp", "Resources/Shaders/skybox.frag");

    shader->Use();
    shader->setInt("skybox", 0);
}

Skybox::~Skybox()
{
}

void Skybox::Draw(const glm::mat4& view, const glm::mat4& projection)
{
    glDepthFunc(GL_LEQUAL);
    shader->Use();
    shader->setMat4("view", glm::mat4(glm::mat3(view)));
    shader->setMat4("projection", projection);
    // skybox cube
    glBindVertexArray(VAO);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glDepthFunc(GL_LESS); 
}

GLuint Skybox::loadCubemap(std::vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height, nrChannels;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
        if (data)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            stbi_image_free(data);
        }
        else
        {
            printf("Stb can't load this sh*t: %s\n", faces[i].c_str());
            stbi_image_free(data);
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
Skybox::Skybox()
{
GLfloat SkyboxVertexts[108]=
{
//职位
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f,1.0f,-1.0f,
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,1.0f,-1.0f,
-1.0f,1.0f,-1.0f,
-1.0f,1.0f,1.0f,
-1.0f,-1.0f,1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f,1.0f,
1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,
1.0f,1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
-1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,
1.0f,-1.0f,1.0f,
-1.0f,-1.0f,1.0f,
-1.0f,1.0f,-1.0f,
1.0f,1.0f,-1.0f,
1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,
-1.0f,1.0f,1.0f,
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
1.0f,-1.0f,1.0f
};
glGenVertexArrays(1和VAO);
glGenBuffers(1,&VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_数组_BUFFER,VBO);
glBufferData(GL_数组_缓冲区、sizeof(SkyboxVertexts)和SkyboxVertexts、GL_静态_绘制);
GlenableVertexAttributeArray(0);
glvertexattributepointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(FLOAT),(void*)0);
向量面
{
“Resources/skybox/right.jpg”,
“Resources/skybox/left.jpg”,
“Resources/skybox/top.jpg”,
“Resources/skybox/bottom.jpg”,
“Resources/skybox/front.jpg”,
“参考资料/skybox/back.jpg”
};
立方体纹理=加载立方体贴图(面);
着色器=新着色器(“Resources/Shaders/skybox.vp”、“Resources/Shaders/skybox.frag”);
着色器->使用();
着色器->setInt(“天空盒”,0);
}
Skybox::~Skybox()
{
}
void Skybox::Draw(常量glm::mat4和视图,常量glm::mat4和投影)
{
glDepthFunc(GL_LEQUAL);
着色器->使用();
着色器->setMat4(“视图”,glm::mat4(glm::mat3(视图));
着色器->setMat4(“投影”,投影);
//天空盒立方体
glBindVertexArray(VAO);
玻璃纹理(GL_纹理0);
glBindTexture(GL_纹理_立方体_贴图,立方体纹理);
gldrawArray(GL_三角形,0,36);
glBindVertexArray(0);
glDepthFunc(GL_LESS);
}
GLuint Skybox::loadCubemap(标准::向量面)
{
无符号整数;
glGenTextures(1,&textureID);
glBindTexture(GL_纹理_立方体_贴图,textureID);
int宽度、高度、通道数;
for(无符号整数i=0;i
谢谢大家的帮助,但我犯了一个愚蠢的错误。在我在一个普通立方体上渲染了skybox之后,我明白了问题所在。这是我将矩阵设置为着色器的函数(他在那里,这个恶棍):

解决方法是用字符替换投影


谢谢大家的帮助,但我犯了一个愚蠢的错误。在我在一个普通立方体上渲染了skybox之后,我明白了问题所在。这是我将矩阵设置为着色器的函数(他在那里,这个恶棍):

解决方法是用字符替换投影


确保a)您可以渲染一个简单的多边形,使其可见b)skybox面向您,即它没有显示在外部b)您实际上在skybox内部上面包括解决任何问题的基本全局方法:我删除了C标记,如果您重新插入它,请确保计算关于此问题的C是什么。而且,如果这对大多数读者来说是显而易见的,对不起。请看它使用旧式gl,但这并不重要。Yunnosch是对的,你要么有错误的矩阵,要么有错误的缠绕规则。尝试在不使用纹理的情况下渲染skybox几何体,它可能超出了平锥(太远或太近),或者在相机后面。还可以尝试
glDisable(GL\u CULL\u FACE)。也可能是您的近剪裁平面(请参见投影矩阵)太近。它最多应该是1,因为天空盒的半径为1。请确保a)您可以渲染一个简单的多边形,使其可见b)天空盒面向您,即它没有显示在外部b)您实际上在天空盒内部上面包括解决任何问题的基本全局方法:我删除了C标记,如果您重新插入,请确保计算此问题的C是什么。而且,如果这对大多数读者来说是显而易见的,对不起。请看它使用旧式gl,但这并不重要。Yunnosch是对的,你要么有错误的矩阵,要么有错误的缠绕规则。尝试在不使用纹理的情况下渲染skybox几何体,它可能超出了平锥(太远或太近),或者在相机后面。还可以尝试
glDisable(GL\u CULL\u FACE)。这可能是一个错误
Skybox::Skybox()
{
    GLfloat skyboxVertices[108] = 
    {
        // positions          
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f,  1.0f
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    std::vector<std::string> faces
    {
        "Resources/skybox/right.jpg",
        "Resources/skybox/left.jpg",
        "Resources/skybox/top.jpg",
        "Resources/skybox/bottom.jpg",
        "Resources/skybox/front.jpg",
        "Resources/skybox/back.jpg"
    };

    cubemapTexture = loadCubemap(faces);

    shader = new Shader("Resources/Shaders/skybox.vp", "Resources/Shaders/skybox.frag");

    shader->Use();
    shader->setInt("skybox", 0);
}

Skybox::~Skybox()
{
}

void Skybox::Draw(const glm::mat4& view, const glm::mat4& projection)
{
    glDepthFunc(GL_LEQUAL);
    shader->Use();
    shader->setMat4("view", glm::mat4(glm::mat3(view)));
    shader->setMat4("projection", projection);
    // skybox cube
    glBindVertexArray(VAO);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glDepthFunc(GL_LESS); 
}

GLuint Skybox::loadCubemap(std::vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height, nrChannels;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
        if (data)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            stbi_image_free(data);
        }
        else
        {
            printf("Stb can't load this sh*t: %s\n", faces[i].c_str());
            stbi_image_free(data);
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
void Shader::setMat4(const char* char_s, const glm::mat4& mat)
{
    glUniformMatrix4fv(glGetUniformLocation(Program, "projection"), 1, GL_FALSE, glm::value_ptr(mat));
}