c++ OpenGL,调色板纹理不工作,我错过了什么?

rur96b6h  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在尝试创建一个使用预定义调色板的纹理(想想内斯)。然而,无论我尝试什么,它似乎都不会按照我想要的方式进行。
我使用的资料来源如下:
调色板纹理
对相关问题的回答
这是我现在使用的(WIP)代码:

//UV and Vertex are already set-up and can confirm they work   

//A Sprite of 16 x 16 
for (int i = 0; i < 16 * 16; i++) {
        PixelMap[i] = 1; //indexed colour for green, as seen below
    }
    glGenTextures(1, &pixelmap_texture_buffer);
    glBindTexture(GL_TEXTURE_2D, pixelmap_texture_buffer);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 16, 16, 0, GL_R8, GL_UNSIGNED_BYTE, PixelMap);

//Now to set up the palette
//Blue colour
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(255);
   pixelcanvas.push_back(255);

//Green colour
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(255);
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(255);

//Red colour
   pixelcanvas.push_back(255);
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(0);
   pixelcanvas.push_back(255);

//Palette with a width of 3 for the three colours
   glGenBuffers(1, &palette);
   glBindTexture(GL_TEXTURE_2D, palette);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelcanvas.data());

以下是片段着色器的GLSL代码:

#version 330 core
in vec2 UV;
uniform sampler2D myTextureSampler;
uniform sampler2D myColorTable;
void main()
{
    vec4 index = texture2D(myTextureSampler, UV);
    vec4 texel = texture2D(myColorTable, index.xy);
    gl_FragColor = texel;
};

结果:A blue texture. (ClearColor is set to purple)
它一直使用调色板的第一种颜色。无论我将它设置为哪个索引颜色。
此外,行:
glTex 2D图像(GL_2D文本,0,GL_R8,16,16,0,GL_R8,L未签名字节,像素Map);
似乎没有做任何事情。我可以忽略它,结果保持不变。好像GL_R8不支持OpenGL 3.3。按照我的逻辑,它应该是完全绿色的。我错过了什么?请让我知道你的想法。
我尝试过更改OpenGL版本。
我尝试将纹理2D设置为纹理1D
我尝试通过以下方式手动设置统一位置:

GLuint unit = 0;

glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, pixelmap_texture_buffer);
glUniform1i(glGetUniformLocation(shaderRef, "myTextureSampler"), unit);

unit = 1;

glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, palette);
glUniform1i(glGetUniformLocation(shaderRef, "myColorTable"), unit);
n6lpvg4x

n6lpvg4x1#

使用无符号字节创建纹理时,0被视为0,255被视为1。在着色器中读取纹理时,如果该像素处的原始字节值为255,则获得的值为1.0,而不是255.0。通常,只需将片段颜色设置为该值,它就会执行预期操作,因为当片段颜色1.0被写入到帧缓冲器中时它变成255。
在pixelmap纹理中,使用字节值1,这意味着index.r为1/255.0,大约为0.0039。然后使用0.0039作为colourmap纹理中的U坐标,因此它读取纹理路径的1/255.0,即进入第一个像素路径的1.17%,第一个像素为红色。
要获得未更改的整数值,您可以将pixelmap纹理设置为GL_R8UI格式,并使用返回uvec 4的usampler 2D对其进行采样。有关使用此纹理格式的示例,请参见here。此示例不实现调色板纹理。
或者-懒惰的方式-将采样器输出乘以255。
要使用整数坐标而不是浮点坐标0-1访问调色板纹理,可以使用图像加载函数。调色板纹理必须是图像而不是采样器。
或者--懒惰的方法--你可以取调色板索引,加0. 5(这样你就得到了纹理元素的中间,没有边界伪像),然后除以3(调色板纹理的宽度)。
另外,你的调色板纹理不需要是2D的,它可以是1D纹理。

相关问题