【问题标题】:LWJGL: Discolored TexturesLWJGL:变色纹理
【发布时间】:2014-02-04 23:32:21
【问题描述】:

所以我正在开发一个小型 Pong 复制品,只是为了使用 LWJGL 进行一些练习。由于没有简单的方法可以在 LWJGL 中编写可自定义的文本,因此我将纹理用于开始按钮、其他按钮等。然而,当我绘制纹理时,结果发现它在我的紫色背景上变色了。如果我将背景更改为白色,则不会变色。帮忙?

另外,我的开始按钮纹理类似于 50x22,但我将其放在 64x64 图像上,因为 Slick 只能加载为 2 的指数的分辨率。我调整了正在绘制的矩形,使其不变形,并且图像的其余部分是透明的,所以一旦我解决了上述问题,它就不应该是可见的。我的方法有其他替代方法吗?

这是我初始化 OpenGL 的地方:

public static void setCamera()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,width,0,height,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

这是我绘制纹理的地方:

public void draw()
{
    logic();
    glPushMatrix();
    glTranslated(x,y,0);
    texture.bind();
    glBegin(GL_QUADS);
    glTexCoord2d(0,1); glVertex2d(0,-196.875);
    glTexCoord2d(1,1); glVertex2d(width+18.75,-196.875);
    glTexCoord2d(1,0); glVertex2d(width+18.75,height);
    glTexCoord2d(0,0); glVertex2d(0,height);
    glEnd();
    glPopMatrix();
}

谢谢:)

【问题讨论】:

  • 如果您解释了如何“将背景设置为白色”,将会很有帮助。是否清除颜色缓冲区,是否使用glColor3f (...) 绘制全屏四边形,是否在纹理中设置颜色?有许多可能的原因,从良性(忘记重置当前颜色)到更复杂的情况,例如在混合函数中不正确地应用预乘 alpha。
  • 清除颜色缓冲区并在名为setCamera (...) 的函数中启用GL_TEXTURE_2D 也没有多大意义。对我来说,这个名字意味着它应该做的唯一一件事就是设置您的查看体积(例如视口、投影和模型视图矩阵)。
  • @andon 好吧,这个名字现在并不重要。那个 setCamera() 方法在游戏循环中运行,还有另一个方法叫做 drawBackground(),这是我绘制背景颜色的地方。当我说“将背景设置为白色”时,我的意思是我使用 glColor3d() 更改了 drawBackground() 中的颜色。
  • 那是你的问题。您需要在绘制前景之前重置当前颜色,否则它将通过背景颜色调整您的纹理。在draw() 中的texture.bind(); 之后添加对glColor3f (1.0f, 1.0f, 1.0f) 的调用。而且我反对的不是函数的名称,而是函数的功能。你在那个函数中做的事情比你应该做的要多,其中许多是不相关的,特别是启用GL_TEXTURE_2D - 你应该只在你真正需要应用纹理时才这样做。
  • @andon 非常感谢!这解决了我的问题!

标签: java opengl textures lwjgl


【解决方案1】:

正如 cmets 中所讨论的,您最初的问题是您在绘制纹理之前忽略了重置“当前颜色”。 GL 是一个荣耀的状态机,它会继续使用您为其他绘制操作设置的颜色...所以在绘制背景时设置glColor3d (...) 也会影响您的前景图像。

在绘制纹理四边形之前添加以下内容将解决此问题:

glColor3f (1.0f, 1.0f, 1.0f);

但是,您在 cmets 中提出了一个与混合相关的新问题。这个问题归结为缺乏混合功能。默认情况下,当您在 OpenGL 中绘制某些内容时,它只会覆盖帧缓冲区中的其他内容。

要使透明度起作用,您需要启用混合并使用此功能:

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

这有效地执行了以下操作:

NewColor = (NewColor.RGB * NewColor.A) + OldColor.RGB * (1.0 - NewColor.A)

这样,纹理中具有 alpha 值的部分!= 1.0 将混合帧缓冲区中已有的内容和您刚刚绘制的内容。

记得在绘制透明对象之前启用混合:

glEnable (GL_BLEND);

并在不需要时禁用它:

glDisable (GL_BLEND);

最后,您应该知道在 OpenGL 中绘制半透​​明对象的顺序非常重要。首先需要绘制不透明的对象(例如您的背景)。通常,您需要从后向前绘制,以使 Alpha 混合正常工作。这是不透明几何体理想情况下想要的相反顺序(因为如果您先在对象前面绘制对象,硬件可以跳过遮挡对象的着色)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多