简体   繁体   English

OpenGL,调色板纹理不起作用。 我在这里错过了什么?

[英]OpenGL, paletted textures not working. What am I missing here?

I am trying to create a texture which uses a predefined palette (think of the NES).我正在尝试创建一个使用预定义调色板的纹理(想想 NES)。 However no matter what I try it does not seem to go the way I want it to.但是,无论我尝试什么,它似乎都不像我想要的那样 go 。

The sources I have used are these:我使用的来源是这些:

Paletted textures 调色板纹理

Answer to a related question 回答相关问题

This is the (WIP) code I am using at the moment:这是我目前正在使用的(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());

Here is the GLSL code for the fragment shader:这是片段着色器的 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;
};

The result: A blue texture.结果:蓝色纹理。 (ClearColor is set to purple) (ClearColor 设置为紫色)

It keeps using the first color of the palette.它一直使用调色板的第一种颜色。 No matter which index color I set it to.无论我将其设置为哪种索引颜色。

Moreover, the line:此外,该行:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 16, 16, 0, GL_R8, L_UNSIGNED_BYTE, PixelMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 16, 16, 0, GL_R8, L_UNSIGNED_BYTE, PixelMap);

Does not seem to be doing anything.似乎没有做任何事情。 I can leave it out and the result remains the same.我可以将其省略,结果保持不变。 As if GL_R8 is not supported by OpenGL 3.3.好像 OpenGL 3.3 不支持 GL_R8。 Going by my logic, it is supposed to be completely green.按照我的逻辑,它应该是完全绿色的。 What am I missing here?我在这里错过了什么? Please let me know your thoughts.请让我知道你的想法。

I have tried changing OpenGL versions.我试过更改 OpenGL 版本。

I have tried setting the Texture2D to Texture1D我试过将 Texture2D 设置为 Texture1D

and I have tried setting the uniform locations manually through:我尝试通过以下方式手动设置统一位置:

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);

When you use unsigned bytes to make a texture, 0 is treated as 0 and 255 is treated as 1. When you read the texture in the shader and the original byte value at that pixel was 255, the value you get is 1.0, not 255.0.当您使用无符号字节制作纹理时,0 被视为 0,255 被视为 1。当您在着色器中读取纹理并且该像素处的原始字节值为 255 时,您获得的值为 1.0,而不是 255.0 . Usually you just set the fragment colour to this value and it does what you expect, since fragment colour 1.0 becomes 255 when it gets written into the framebuffer.通常您只需将片段颜色设置为此值,它就会按照您的预期进行,因为片段颜色 1.0 在写入帧缓冲区时变为 255。

In your pixelmap texture you use the byte value 1, that means that index.r is 1/255.0, about 0.0039.在您的像素图纹理中,您使用字节值 1,这意味着 index.r 是 1/255.0,大约 0.0039。 Then you use 0.0039 as the U coordinate in the colourmap texture, so it reads 1/255.0 of the way along the texture, that is 1.17% of the way into the first pixel, and the first pixel is red.然后您使用 0.0039 作为颜色贴图纹理中的 U 坐标,因此它会沿着纹理读取 1/255.0 的路径,即进入第一个像素的路径的 1.17%,并且第一个像素为红色。

To get unchanged integer values you could make the pixelmap texture in GL_R8UI format, and sample it with a usampler2D which returns a uvec4.要获得不变的 integer 值,您可以制作 GL_R8UI 格式的像素贴图纹理,并使用返回 uvec4 的 usampler2D 对其进行采样。 See here for an example using this texture format.有关使用此纹理格式的示例,请参见此处 This example does not implement a paletted texture.此示例未实现调色板纹理。

Or - the lazy way - multiply the sampler output by 255.或者 - 懒惰的方式 - 将采样器 output 乘以 255。

To access the palette texture using integer coordinates, instead of floating-point coordinates 0-1, you can useimage load functions .要使用 integer 坐标访问调色板纹理,而不是浮点坐标 0-1,您可以使用图像加载函数 The palette texture must be an image and not a sampler.调色板纹理必须是图像而不是采样器。

Or - the lazy way - you can take the palette index, add 0.5 (so you get the middle of the texel and no boundary artifacts) and divide by 3 (the width of the palette texture).或者 - 懒惰的方式 - 你可以采用调色板索引,加上 0.5(所以你得到纹素的中间并且没有边界伪影)并除以 3(调色板纹理的宽度)。

Also, your palette texture doesn't need to be 2D.此外,您的调色板纹理不需要是二维的。 It could be a 1D texture.它可以是一维纹理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我的 C++ 合并排序代码不起作用。 我在这里缺少什么? - My C++ Merge Sort code isn't working. What am i missing here? 我错过了什么纹理不起作用 OpenGL - What am i missing that texture isn't working OpenGL 如果这不是boost :: lockfree :: detail :: freelist中的错误,我在这里缺少什么? - If this is not a bug in boost::lockfree::detail::freelist, what am I missing here? 纹理不适用于OpenGL - Textures not working with OpenGL OpenGL 绑定多个纹理不起作用 - OpenGL binding multiple textures not working AFAIK,下面的代码不应该编译,但它在clang和GCC中。 我在这里错过了什么? - AFAIK, the code below shouldn't compile, but it does in clang and GCC. What am I missing here? 旧版OpenGL纹理无法正常工作 - Legacy OpenGL Textures not working correctly OpenGL(核心配置文件)纹理缺失或黑色 - OpenGL (core profile) textures are missing or black 由于内存泄漏,我的析构函数似乎没有击中树中的每个节点,我在这里缺少什么? - My destructor does not appear to hit every node in the tree as I have memory leaks, what am I missing here? 我在关于c ++的陈述中遗漏了什么吗? - Am I missing anything here in my statement about c++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM