在 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、宽度和高度存储为双坐标的类型)
现在的问题是,一旦我使用了这些坐标,精灵就可以正确显示,透明度也可以正常工作,只是其他一切都变得明显变暗(我猜它变得透明更正确,但是因为 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) ):
我尝试的另一件事是在我绘制播放器之前启用混合,并在我完成绘制后再次禁用它:
现在稍微好一点了,但还是明显变暗了。在这种情况下,它似乎真的“更暗”而不是“更透明”,因为当我使用白色作为清晰的颜色时它是相同的(同时仍然只在需要时启用混合并在之后立即禁用它),如下所示: