【问题标题】:OpenGL Palette Swap shader?OpenGL调色板交换着色器?
【发布时间】:2012-05-30 20:09:48
【问题描述】:

我正在编写一个格斗游戏,其中每个角色都有大量的精灵,每个角色都有几个不同的调色板交换。我一直在尝试为每个精灵使用灰度纹理,并为每个调色板使用 256x1 纹理。

我的着色器如下所示:

顶点:

varying vec2 coord;
void main(void)
{
    coord = gl_MultiTexCoord0.xy;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

片段:

uniform sampler2D palette;
uniform sampler2D texture;
varying vec2 coord;
void main()
{
    gl_FragColor = texture2D(palette, vec2(texture2D(texture, coord).r, 0));
}

使用 glGetUniformLocation 和 glUniform1i 将“调色板”设置为 1,将“纹理”设置为 0。他们编译得很好,链接也很好。我可以在我的绘图代码中使用程序对象。

问题是,我不知道如何使用多重纹理来让“调色板”和“纹理”纹理在着色器中相互协作。这是我第一次使用多重纹理,我似乎无法弄清楚如何让它适用于这种解决方案。有谁知道如何使用这些着色器(如果它们是正确的)来模拟调色板交换?

编辑:这是我现在的绘图代码:

glUseProgram(paletteProgram);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, palette);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);

glBegin(GL_QUADS);
glTexCoord2f(w1, h1);
glVertex3f(x1, y1, 0);
glTexCoord2f(w1, h2);
glVertex3f(x1, y2, 0);
glTexCoord2f(w2, h2);
glVertex3f(x2, y2, 0);
glTexCoord2f(w2, h1);
glVertex3f(x2, y1, 0);
glEnd();

glUseProgram(0);

【问题讨论】:

  • 您的代码看起来是正确的(除了 glEnable(GL_TEXTURE_2D) 在您使用着色器时没有任何效果,应该删除它)。您是否独立验证了这些纹理已加载并且可以正确采样,所有多重纹理除外?
  • 是的,我已经测试了这两种纹理,它们都可以在没有着色器的情况下独立工作。
  • 嗯,我被难住了。无论如何,我只能建议您检查 glGetError 如果您没有检查,还检查着色器信息日志(也许那里有某种非致命警告可以提供线索)。
  • 我很确定问题在于它无法从调色板纹理或 GL_TEXTURE1 中的任何内容中采样。但我无法弄清楚为什么......
  • 我所能建议的就是放置所有的 OGL 代码(着色器初始化、统一初始化等)。到目前为止,我认为您发布的内容没有任何问题。也许在别处有错误。

标签: opengl glsl shader palette


【解决方案1】:

你的逻辑似乎是合理的。您需要做的是使用glActiveTexture 设置活动纹理,然后像往常一样绑定您的纹理(对于纹理单元0 和1)。现在还将值 0 绑定到称为纹理的统一,并将值 1 绑定到称为调色板的统一。

在 GLSL 中,您可以使用 texture2D 从适当的采样器中获取纹素。

希望这会有所帮助!

这实际上在this NeHe 教程(部分:使用 GLSL 中的纹理)中有详细说明。

这是你需要做的

    glUseProgramObject(my_program);
    int my_sampler_uniform_location = glGetUniformLocation(my_program, my_color_texture);

    glActiveTexture(GL_TEXTURE0 + i);
    glBindTexture(GL_TEXTURE_2D, my_texture_object);

    glUniform1i(my_sampler_uniform_location, i);

【讨论】:

  • 可以给我一个代码示例吗?我以为我正在这样做,但结果始终只是纯黑色纹理。
  • 检查 Nehe 链接。里面用代码和示例进行了解释。
  • @MathewVelasquez 你应该发布你自己的代码,这样我们就可以看看它是否有问题,而不是让别人写它。
  • 哇,哇。将着色器上的采样器设置为纹理单元的 glUniform (opengl.org/sdk/docs/man/xhtml/glUniform.xml) 调用在哪里?
【解决方案2】:

好的,我想通了!

显然,每次使用脚本程序时都会重置统一变量……我只需要每帧都设置它们。

我现在觉得自己很愚蠢,但是,这就是调试。

【讨论】:

  • 这不应该发生;制服应该无限期地存在,你不应该每帧都覆盖它们。也许您的初始化由于某种原因失败了,或者您不小心在其他地方覆盖了它?
猜你喜欢
  • 2014-11-25
  • 2013-01-12
  • 2016-06-19
  • 1970-01-01
  • 2011-05-07
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多