glsl 非 mipmapped 纹理不显示
glsl non-mipmapped textures do not display
我已经成功地使用我自己的迷你管道(使用 mipmap)在几何体上显示纹理,但我决定不使用 mip-map,因为我的软件实际上不需要任何细节级别的更改。它是 2d 并使用像素艺术。细节不应该改变。
我要补充一点,我正在尝试在纹理图集内循环纹理并禁用 mip-mapping 可能 有助于避免问题。
但是,不调用 glGenerateMipmap
会产生空白屏幕。调用它会产生正确的纹理。
我必须调用另一个函数吗?
下面是我的纹理生成函数(我传递了一个指向已经创建的纹理id的指针。)
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(GL_TEXTURE_2D); // commenting this out yields a blank screen
// wrapping behavior
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge);
// texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // I won't want these because the texture should have constant detail / resolution
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// free the surface
SDL_FreeSurface(img);
return GL_TRUE;
}
我对 png 文件使用 SDL2_Image,纹理大小不一定是二次方。 (我还没有对此进行优化。)
我可能遗漏了什么?我应该设置哪些参数来渲染未过滤的纹理?我怀疑 mipmapping 是必需的。如果没有 mipmapping,我是否有可能无法像往常一样使用 sampler2D 或 texture()?那就奇怪了。
提前致谢。
编辑:BDL 的回答很有帮助。作为参考,以下是我修改后的代码:
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge_x, const GLint param_edge_y)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
// wrapping behavior
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge_x);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge_y);
// texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
// free the surface
SDL_FreeSurface(img);
return GL_TRUE;
}
是否需要纹理的 mipmap 取决于使用的过滤器模式。当使用带有 ..._MIPMAP_...
的 filtermode 时,必须有一个 mipmap(无论它是否被访问)。
如果您不需要 mipmap,请使用 GL_LINEAR
或 GL_NEAREST
作为 GL_TEXTURE_MIN_FILTER
。对于像素化外观,您很可能需要 GL_NEAREST
.
我已经成功地使用我自己的迷你管道(使用 mipmap)在几何体上显示纹理,但我决定不使用 mip-map,因为我的软件实际上不需要任何细节级别的更改。它是 2d 并使用像素艺术。细节不应该改变。 我要补充一点,我正在尝试在纹理图集内循环纹理并禁用 mip-mapping 可能 有助于避免问题。
但是,不调用 glGenerateMipmap
会产生空白屏幕。调用它会产生正确的纹理。
我必须调用另一个函数吗?
下面是我的纹理生成函数(我传递了一个指向已经创建的纹理id的指针。)
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(GL_TEXTURE_2D); // commenting this out yields a blank screen
// wrapping behavior
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge);
// texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // I won't want these because the texture should have constant detail / resolution
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// free the surface
SDL_FreeSurface(img);
return GL_TRUE;
}
我对 png 文件使用 SDL2_Image,纹理大小不一定是二次方。 (我还没有对此进行优化。)
我可能遗漏了什么?我应该设置哪些参数来渲染未过滤的纹理?我怀疑 mipmapping 是必需的。如果没有 mipmapping,我是否有可能无法像往常一样使用 sampler2D 或 texture()?那就奇怪了。
提前致谢。
编辑:BDL 的回答很有帮助。作为参考,以下是我修改后的代码:
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge_x, const GLint param_edge_y)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
// wrapping behavior
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge_x);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge_y);
// texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
// free the surface
SDL_FreeSurface(img);
return GL_TRUE;
}
是否需要纹理的 mipmap 取决于使用的过滤器模式。当使用带有 ..._MIPMAP_...
的 filtermode 时,必须有一个 mipmap(无论它是否被访问)。
如果您不需要 mipmap,请使用 GL_LINEAR
或 GL_NEAREST
作为 GL_TEXTURE_MIN_FILTER
。对于像素化外观,您很可能需要 GL_NEAREST
.