LWJGL 使用纹理时颜色混乱 + 经常禁用纹理时会降低 FPS
Posted
技术标签:
【中文标题】LWJGL 使用纹理时颜色混乱 + 经常禁用纹理时会降低 FPS【英文标题】:LWJGL Colors messed up when using textures + lower FPS when disabling texturing often 【发布时间】:2011-08-28 13:26:35 【问题描述】:我最初在使用纹理时遇到了颜色混乱的问题,但我设法修复了它(问题是我没有在需要时禁用纹理)。这样做之后,颜色发生了变化,但仍然不是我想要的颜色 - 白色而不是纯蓝色 (0,0,255) RGB。 下面是完整的渲染方法:
private void render()
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
GL11.glLoadIdentity(); // Reset The View
GL11.glRotatef(lookupdown, 1.0f, 0, 0);
GL11.glRotatef(360.0f - yrot, 0, 1.0f, 0);
GL11.glTranslatef(-xpos, 0, -zpos);
/* RENDERING BLOCKS */
for (Block block : lvLoader.currentLevel.blocks)
if (block.created)
if (block.texturePos != null)
if (block.texturePos.pos != -1)
Texture txt = TextureManager.getInstance().blocks[block.texturePos.pos];
if (txt != null)
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, txt.getTextureID());
GL11.glColor3ub(block.color.getRedByte(), block.color.getGreenByte(), block.color.getBlueByte());
GL11.glBegin(GL11.GL_QUADS);
for (int i = 0; i < 6; i++)
for (int j = 0; j < 4; j++)
if (block.texturePos != null)
switch (j)
case 0:
GL11.glTexCoord2f(1.0f, 1.0f);
break;
case 1:
GL11.glTexCoord2f(0.0f, 1.0f);
break;
case 2:
GL11.glTexCoord2f(0.0f, 0.0f);
break;
case 3:
GL11.glTexCoord2f(1.0f, 0.0f);
break;
default:
break;
GL11.glVertex3f(block.walls[i].vertices[j].x, block.walls[i].vertices[j].y, block.walls[i].vertices[j].z);
GL11.glEnd();
//if (block.texturePos != null)
//if (block.texturePos.pos != -1)
GL11.glDisable(GL11.GL_TEXTURE_2D);
/* RENDERING TILES */
for (Tile tile : lvLoader.currentLevel.tiles)
if (tile.created)
if (tile.texturePos != null)
GL11.glEnable(GL11.GL_TEXTURE_2D);
if (tile.texturePos.pos != -1)
Texture txt = TextureManager.getInstance().tiles[tile.texturePos.pos];
if (txt != null)
GL11.glBindTexture(GL11.GL_TEXTURE_2D, txt.getTextureID());
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3ub(tile.color.getRedByte(), tile.color.getGreenByte(), tile.color.getBlueByte());
for (int jj = 0; jj < 4; jj++)
if (tile.texturePos != null)
switch (jj)
case 0:
GL11.glTexCoord2f(1.0f, 1.0f);
break;
case 1:
GL11.glTexCoord2f(0.0f, 1.0f);
break;
case 2:
GL11.glTexCoord2f(0.0f, 0.0f);
break;
case 3:
GL11.glTexCoord2f(1.0f, 0.0f);
break;
default:
break;
GL11.glVertex3f(tile.surface.vertices[jj].x, tile.surface.vertices[jj].y, tile.surface.vertices[jj].z);
GL11.glEnd();
//if (tile.texturePos != null)
//if (tile.texturePos.pos != -1)
GL11.glDisable(GL11.GL_TEXTURE_2D);
/* RENDERING ROOF */
for (Tile rTile : lvLoader.currentLevel.roof)
if (rTile != null)
if (rTile.created)
if (rTile.texturePos != null)
if (rTile.texturePos.pos != -1)
Texture txt = TextureManager.getInstance().tiles[rTile.texturePos.pos];
if (txt != null)
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, txt.getTextureID());
GL11.glColor3ub(rTile.color.getRedByte(), rTile.color.getGreenByte(), rTile.color.getBlueByte());
GL11.glBegin(GL11.GL_QUADS);
for (int k = 0; k < 4; k++)
if (rTile.texturePos != null)
switch (k)
case 0:
GL11.glTexCoord2f(1.0f, 1.0f);
break;
case 1:
GL11.glTexCoord2f(0.0f, 1.0f);
break;
case 2:
GL11.glTexCoord2f(0.0f, 0.0f);
break;
case 3:
GL11.glTexCoord2f(1.0f, 0.0f);
break;
default:
break;
GL11.glVertex3f(rTile.surface.vertices[k].x, rTile.surface.vertices[k].y, rTile.surface.vertices[k].z);
GL11.glEnd();
//if (rTile.texturePos != null)
//if (rTile.texturePos.pos != -1)
GL11.glDisable(GL11.GL_TEXTURE_2D);
RENDERING TILES 部分出现问题。那些没有纹理(目前),我希望它们只是彩色方块 - 红色(用于熔岩)和蓝色(用于水)。颜色取自静态变量并且是正确的(我通过 System.out.ln(tile.color.getRed()...... - 输出为 0,0,255 进行了检查)。这是静态变量:
/* TILES */
//ShallowWater
public static ColorStruct V00255 = new ColorStruct(new Color(0, 0, 255), "Tile", "ShallowWater"); //Pure blue
输出如下所示:Rendered scene
白色的田野是水——它们应该是蓝色的!
另一个问题是 FPS - 正如您在屏幕上看到的那样,它是 41。在渲染部分中添加多个 glEnable 和 glDisable 纹理之前,FPS 是 60。是那些多个启用和禁用导致这个吗?可以避免吗?
我是 openGL 的新手,这也是我在这里的第一个问题,如果我做错了什么,请原谅我。
【问题讨论】:
【参考方案1】:glColor3ub
采用无符号字节。也许您正在使用有符号字节?你试过glColor3ub(0,0,255)
或glColor3f(0,0,1)
吗?如果它确实有效,请确保 getRedByte
等返回正确的值。
为了提高性能:
如果您的场景大部分是静态的,请使用display lists。
优化 OpenGL 调用。避免使用glDisable
/glEnable
和glBindTexture
。只要您不经常更改状态,现代图形卡就会非常快。你可以通过使用空白的白色纹理来避免glEnable
/glDisable
。使用texture atlas 可以避免glBindTexture
。
如果显示列表太慢,请使用VBOs。
【讨论】:
谢谢,我要试试空白色纹理的想法,听起来不错!几天前我尝试制作地图集,但失败了,所以我辞职了。然而,现在我想我知道为什么我失败了,所以我会再试一次。是否可以以静态模式(显示列表)渲染场景的一部分并动态渲染其余部分?在我开始在渲染功能的启用/禁用之间切换之前,颜色很好,具有相同的值。 glColor3ub(0, 0, 255) 给出相同的效果,与 glColor3f(0, 0, 1) 相同。 getBlueByte 返回 255,其余为 0,所以看起来是正确的。 @Myzreal:如果我没记错的话,使用纹理 0 (glBindTexture(GL_TEXTURE2D,0)
) 将具有与白色纹理相同的效果(至少在您的情况下)。据我了解,它应该可以解决您的问题。您可以使用显示列表仅渲染场景的静态部分。其余的可以正常渲染。
我设法使用纹理图集并使用空白纹理,但没有使用纹理 0。我只是在图集的末尾添加了一个白色方块并使用它,所以我只能使用 glBind一次,在初始化部分。我相信它会产生相同的效果?然而颜色仍然不存在——“无纹理”的水现在是白色的,我无法让纹理着色。其他纹理,如墙壁、地面和天花板,也不能着色。如何为纹理着色?以上是关于LWJGL 使用纹理时颜色混乱 + 经常禁用纹理时会降低 FPS的主要内容,如果未能解决你的问题,请参考以下文章