【发布时间】:2013-03-17 17:16:38
【问题描述】:
在 OpenGL 中使用混合时,我遇到了一个(希望如此)小问题。 目前我使用 LWJGL 和 Slick-Util 来加载纹理。 纹理本身是一个 2048x2048 png 图形,我在其中存储大小为 128x128 的图块,因此每行/列有 16 个精灵。 由于 glTexCoord2f() 使用标准化坐标,我编写了一个小函数来缩放整个图像以仅显示我想要的精灵。 它看起来像这样:
private Rectangle4d getTexCoord(int x, int y) {
double row = 0, col = 0;
if(x > 0)
row = x/16d;
if(y > 0)
col = y/16d;
return new Rectangle4d(row, col, 1d/16d, 1d/16d);
}
(Rectangle4d 只是一种将 x、y、width 和 height 存储为双坐标的类型)
现在的问题是,一旦我使用了这些坐标,精灵就可以正确显示,透明度也可以正常工作,只是其他一切都变得明显更暗(我猜它变得透明更正确,但是因为 ClearColor 是黑色的)。然而,精灵本身是正确绘制的。我已经尝试将所有 glColor3d(..) 更改为 glColor4d(..) 并将 alpha 设置为 1d,但这并没有改变任何东西。精灵是当前唯一的图像,其他一切都只是彩色的四边形。
这是我初始化 OpenGL 的方式:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
这是我加载精灵的方式(使用 slick-util):
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/sprites.png"));
最后我像这样渲染它(使用顶部提到的辅助函数 getTexCoord()):
texture.bind();
glColor4d(1, 1, 1, 1);
glBegin(GL_QUADS);
{
Rectangle4d texCoord = getTexCoord(0, 0);
glTexCoord2f((float)texCoord.getX(), (float)texCoord.getY());
glVertex2i((Game.WIDTH-PLAYERSIZE)/2, (Game.HEIGHT-PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX()+(float)texCoord.getWidth(), (float)texCoord.getY());
glVertex2i((Game.WIDTH+PLAYERSIZE)/2, (Game.HEIGHT-PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX()+(float)texCoord.getWidth(), (float)texCoord.getY()+(float)texCoord.getHeight());
glVertex2i((Game.WIDTH+PLAYERSIZE)/2, (Game.HEIGHT+PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX(), (float)texCoord.getY()+(float)texCoord.getHeight());
glVertex2i((Game.WIDTH-PLAYERSIZE)/2, (Game.HEIGHT+PLAYERSIZE)/2);
}
glEnd();
结果是这样的(精灵被正确绘制,只是其他一切都变暗/透明): 没有纹理(只是一个灰色四边形),它看起来像这样(现在一切都正确绘制,除了我没有精灵):
感谢所有愿意阅读本文的人!
编辑:
一些附加信息,来自我试图找到问题的方法: 这是我将 ClearColor 设置为白色时的样子(使用 glClearColor(1, 1, 1, 1) ):
我尝试的另一件事是在我绘制播放器之前启用混合,并在我完成绘制后再次禁用它:
现在稍微好一点了,但还是明显变暗了。在这种情况下,它似乎真的“更暗”而不是“更透明”,因为当我使用白色作为清晰的颜色时它是相同的(同时仍然只在需要时启用混合并在之后立即禁用它),如下所示:
【问题讨论】:
-
嗯,这是一个有趣的结果。如果禁用混合,会发生什么?是不是全屏变黑了?
-
当我禁用混合时,除了原本不可见的精灵部分是白色的之外,一切都被正确绘制。
-
好吧,你把我难住了。如果您尝试注释掉代码的其他绘图部分会发生什么?如果将透明色改为白色而不是黑色会怎样?
-
感谢您的评论,我在开篇文章中添加了更多细节+屏幕。
标签: java opengl lwjgl alphablending