簡體   English   中英

Stb_image 創建奇怪的偽影

[英]Stb_image creates weird artifacts

您好,我正在為我的 openGL 項目制作圖像和紋理 class,當我添加 stb_image 時,一些紋理開始在圖像邊緣添加噪聲。

圖片 class:

    Image::Image() {
        width = 0;
        height = 0;
        channels = 0;
        data = NULL;
    }

    Image::Image(const Image& image) {
        width = image.width;
        height = image.height;
        channels = image.channels;

        int allocation = image.width * image.height * image.channels;
        data = new unsigned char[allocation];
        std::memcpy(data, image.data, allocation);
    }

    Image& Image::operator=(const Image& image) {
        if (this != &image && image.data != nullptr) {
            if(data != NULL)
                delete[] data;
            data = NULL;

            int allocation = image.width * image.height * image.channels;
            data = new unsigned char[allocation];
            std::memcpy(data, image.data, allocation);

            width = image.width;
            height = image.height;
            channels = image.channels;
            filepath = image.filepath;
        }

        return *this;
    }

    Image::Image(const std::string& _filepath) {
        width = 0;
        height = 0;
        channels = 0;
        data = NULL;
        filepath = _filepath;

        data = stbi_load(filepath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
        
        if (data == NULL) {
            Debug::systemErr("Couldn't load image: " + filepath);
        }
    }

    Image::~Image() {
        if (data != NULL) {
            delete[] data;
        }

        data = NULL;
    }

    bool Image::hasData() const{
        return (data != NULL);
    }

紋理 class:

Texture::Texture() {
        textureID = 0;
    }

    Texture::Texture(const Texture& texture) {
        image = Image(texture.image);
        textureID = 0;
    }

    Texture::Texture(const std::string& path) {
        image = Image(path);
        textureID = 0;
    }

    Texture& Texture::operator=(const Texture& texture) {
        textureID = texture.textureID;
        image = texture.image;

        return *this;
    }

    Texture::~Texture() {
        destroy();
    }

    void Texture::destroy() {
        glDeleteTextures(1, &textureID);
    }

    void Texture::create() {
        if (!isCreated && image.hasData()) {

            glGenTextures(1, &textureID);
            glBindTexture(GL_TEXTURE_2D, textureID);

            //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data);

            glGenerateMipmap(GL_TEXTURE_2D);

            isCreated = true;
        }
    }

圖像為 128x128 像素

這是它在paint.net中的樣子:

在此處輸入圖像描述

這是渲染時的樣子:

在此處輸入圖像描述

我相信圖像加載很好,因為我用圖像 class 設置了 window 的圖標,看起來很好。 我認為問題源於紋理 class。

Jérôme Richard 解決了這個問題。 這不起作用的原因是,即使我將 rgba 用於通道,圖像仍然以 rgb 形式返回。 然后當我嘗試復制數據時,而不是做 4 * width * height 的大小。 我會做 3 * 寬度 * 高度。 所以在 stbi_load() 之后,我只放了 channels = 4。

您應該更仔細地閱讀 stbi 文檔。 它在一開始就在那里:

 int x,y,n; unsigned char *data = stbi_load(filename, &x, &y, &n, 0);

... 將 '0' 替換為 '1'..'4' 以強制每個像素有那么多分量
...但是“n”將始終是您說 0 時的數字

因此,如果您將0以外的任何值作為最后一個參數傳遞,這就是您將獲得的通道數。 在這種情況下,您應該忽略n並按您請求的通道數忽略 go。 另一方面,您的代碼以另一種方式執行此操作:它請求四個通道,但隨后使用返回的n (在您的代碼中稱為channels )作為事實來源。

暫無
暫無

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

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