【问题标题】:Color error with OpenGL Texture FormatsOpenGL 纹理格式的颜色错误
【发布时间】:2016-01-11 19:32:39
【问题描述】:

我正在尝试使用 FreeImage 加载图像,然后生成 OpenGL 纹理。它加载图像并生成纹理,但颜色存在问题。

这是原始图像:

结果如下:

纹理加载代码:

void TextureManager::LoadTexture(std::string id, std::string filePath){

Texture tex;
tex.TextureId = 0;

FIBITMAP* image = FreeImage_Load(FreeImage_GetFileType(filePath.c_str(), 0), filePath.c_str());


if (FreeImage_GetBPP(image) != 32) {

    image = FreeImage_ConvertTo32Bits(image);
}


FreeImage_FlipVertical(image);

tex.Width = FreeImage_GetWidth(image);
tex.Height = FreeImage_GetHeight(image);


glGenTextures(1, &tex.TextureId);
glBindTexture(GL_TEXTURE_2D, tex.TextureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,tex.Width, tex.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(image));

AddTextureToMap(id, tex);

FreeImage_Unload(image);
}

这是绘制它的代码:

glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, TextureManager.TextureMap[textureSelector].TextureId);

glBegin(GL_TRIANGLES);
glTexCoord2d(0, 0);
glVertex3f(-0.75, 0.75, 0);//top left
glTexCoord2d(1, 0);
glVertex3f(0.75, 0.75, 0);//top right
glTexCoord2d(0, 1);
glVertex3f(-0.75, -0.75, 0);//bottom left

glTexCoord2d(1, 0);
glVertex3f(0.75, 0.75, 0);//top right
glTexCoord2d(1, 1);
glVertex3f(0.75, -0.75, 0);//bottom right
glTexCoord2d(0, 1);
glVertex3f(-0.75, -0.75, 0);//bottom left
glEnd();
glFinish();

我很确定这是 glTexImage2D 中的内部格式的问题,但我不确定如果是这种情况我会使用哪种格式。我的问题是:是格式吗,如果是,我应该使用什么;还是有其他问题导致了这种情况?

【问题讨论】:

  • 尝试删除glTexEnvf 行。还 FreeImage_ConvertTo32Bits 创建图像的克隆;你需要释放旧的。

标签: c++ opengl


【解决方案1】:

尝试改用这个

不同之处在于许多图像格式使用反向字节顺序,您应该使用 GL_BGR_EXT 或 GL_BGRA_EXT 图像格式而不是 GL_RGB 或 GL_RGBA

void TextureManager::LoadTexture(std::string id, std::string filePath){

Texture tex;
tex.TextureId = 0;

FIBITMAP* image = FreeImage_Load(FreeImage_GetFileType(filePath.c_str(), 0), filePath.c_str());


if (FreeImage_GetBPP(image) != 32) {

    image = FreeImage_ConvertTo32Bits(image);
}


FreeImage_FlipVertical(image);

tex.Width = FreeImage_GetWidth(image);
tex.Height = FreeImage_GetHeight(image);


glGenTextures(1, &tex.TextureId);
glBindTexture(GL_TEXTURE_2D, tex.TextureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,tex.Width, tex.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(image));

AddTextureToMap(id, tex);

FreeImage_Unload(image);
}

【讨论】:

  • 所以,这让我走上了正轨。我最终使用了这个: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,tex.Width, tex.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(image));我对 OpenGL 有点陌生,但我不完全确定为什么会这样。
  • 我已经在答案中解释了这一刻,但并非所有图像格式都使用这种字节顺序,如果您打算支持多种图像格式,您应该在运行时以某种方式检查正确的格式。
  • GL_BGRGL_BGRA 自 OpenGL 1.2 以来已成为标准。应该不需要使用扩展表单。
【解决方案2】:

如果 RGBA 顺序不正确,您可以在片段着色器中更改颜色,如

#version 130

uniform sampler2D tex;

in vec2 texCoordsVarying;
out vec4 color;

void main() {
  vec4 c2 = texture(tex, texCoordsVarying);
  color = vec4(c2.g, c2.b, c2.a, c2.r);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多