簡體   English   中英

如果現代OpenGL中有多個紋理,則沒有紋理

[英]No texture if multiple textures in modern opengl

我正在使用帶有SDL2和glew的C ++和OpenGL 4.6。 我有一堂課Texture:

#include "stb_image/stb_image.h"
class Texture {
private:
    unsigned int m_RendererID;
    std::string m_FilePath;
    unsigned char *m_LocalBuffer;
    int m_Width, m_Height, m_BPP;
public:
    Texture(const std::string &path);
    ~Texture();

    void Bind(unsigned int slot = 0) const;
    void Unbind() const;

    inline int GetWidth() const { return m_Width; }
    inline int GetHeight() const { return m_Height; }
    inline int GetID() const { return m_RendererID; }
};

Texture::Texture(const std::string &path) 
    : m_RendererID(0), m_FilePath(path), m_LocalBuffer(nullptr), m_Width(0), m_Height(0), m_BPP(0) 
{
    stbi_set_flip_vertically_on_load(1); //Flip vertically because OpenGL renders texture in the opposite way
    m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);

    GLCall(glGenTextures(1, &m_RendererID));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));

    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));

    GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer));
    GLCall(glBindTexture(GL_TEXTURE_2D, 0));

    if (m_LocalBuffer) {
        stbi_image_free(m_LocalBuffer);
    }
}

Texture::~Texture() {
    GLCall(glDeleteTextures(1, &m_RendererID));
}

void Texture::Bind(unsigned int slot) const {
    GLCall(glActiveTexture(GL_TEXTURE0 + slot));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
}

void Texture::Unbind() const {
    GLCall(glBindTexture(GL_TEXTURE_2D, 0));
}

如果創建一個紋理,該紋理將顯示:

Texture texture("ship.png");
texture.Bind(0);
shader.Bind();
va.Bind();
ib.Bind();
shader.SetUniform1i("u_Texture", 0);
glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);

但是,如果我創建兩個紋理,我只會得到黑屏:

Texture texture("ship.png");
texture.Bind(0);
Texture texture2("ship2.png");
texture2.Bind(1);
shader.Bind();
va.Bind();
ib.Bind();
shader.SetUniform1i("u_Texture", 0);
glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);

這應該工作。 我在互聯網上搜索了2個小時,但似乎找不到為什么無法正常工作的原因。 你們能幫我嗎?

在以下代碼行的末尾

  Texture texture("ship.png"); texture.Bind(0); Texture texture2("ship2.png"); texture2.Bind(1); 

第二個紋理對象( “ ship2.png” )綁定到紋理單元1,但是默認紋理對象(0)綁定到紋理單元0。

注意當Texture texture("ship.png"); 被調用,然后創建紋理對象並將其綁定到當前紋理單元,然后將默認紋理對象(0)綁定到當前紋理單元:

  Texture::Texture(const std::string &path) { GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID)); // [...] GLCall(glBindTexture(GL_TEXTURE_2D, 0)); } 

請注意,您所謂的“ unbind”不會解除任何綁定。 glBindTexture(GL_TEXTURE_2D, 0)將默認紋理對象( glBindTexture(GL_TEXTURE_2D, 0)綁定到當前處於活動狀態的紋理單元。 沒有必要這樣做。


只需更改說明的順序即可解決您的問題。 首先創建並加載紋理對象。 然后將紋理對象綁定到紋理單元:

Texture texture("ship.png");
Texture texture2("ship2.png");

texture.Bind(0);
texture2.Bind(1);

shader.Bind();
va.Bind();
ib.Bind();
shader.SetUniform1i("u_Texture", 0);
glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);

或者,可以避免使用紋理單位0。僅將紋理單位0用於創建紋理對象:

Texture::Texture(const std::string &path, unsigned int slot) {

    GLCall(glActiveTexture(GL_TEXTURE0));

    // [...]
}
Texture texture("ship.png");
texture.Bind(1);                     // <--- 1
Texture texture2("ship2.png");
texture2.Bind(2);                    // <--- 2
shader.Bind();
va.Bind();
ib.Bind();
shader.SetUniform1i("u_Texture", 1); // <--- 1
glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);

或者將紋理單元的參數添加到Texture類的構造函數中:

Texture::Texture(const std::string &path, unsigned int slot) {

    GLCall(glGenTextures(1, &m_RendererID));

    GLCall(glActiveTexture(GL_TEXTURE0 + slot));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));

    // [...]

    // GLCall(glBindTexture(GL_TEXTURE_2D, 0)); <--- delete
}
Texture texture("ship.png", 0);
Texture texture2("ship2.png", 1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM