2D LWJGL结合OpenGL - 如何启用深度测试以便对2D纹理进行分层?

3
我需要在我的OpenGL初始化方法中添加什么以启用深度测试,我如何将其用于纹理层叠?
我必须将glOrtho的最后一个参数扩展到比-1更极端的值,并且当然要启用深度测试。然后要使用它,我可以假设我改变glVertex的第三个参数为不为0的值,以便将其发送到其他纹理的前面或后面。
我尝试了这个方法,但是该死的纹理甚至都没有显示。 xD 我应该漏掉了什么。
编辑:关于Tim的回复
每当我将图像的z坐标设置得比-1更极端时,它就不会显示,屏幕只会变成黑色。
void initGL(){

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_DEPTH_TEST); //depth test enabled

    GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glOrtho(-width/2, width/2, -height/2, height/2, 1, -10);//far changed to -10
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

}

并且

void loadBG(int theLoadedOne){

GL11.glBindTexture(GL11.GL_TEXTURE_2D, theLoadedOne);
GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2f(0,0);
GL11.glVertex3f(-width/2,height/2, -2);//new z value

    GL11.glTexCoord2f(1,0);
GL11.glVertex3f(width/2,height/2,-2);//new z value

    GL11.glTexCoord2f(1,1);
GL11.glVertex3f(width/2,-height/2,-2);//new z value

    GL11.glTexCoord2f(0,1);
GL11.glVertex3f(-width/2,-height/2,-2);//new z value

GL11.glEnd();
GL11.glFlush();

}

并且

while(!Display.isCloseRequested()){
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

...

            for(int i=0;i<1;i++){  //dont mind this for loop
                bg.loadThisBG(0);  //its here for reasons
            }
            updateFPS();

        Display.update();

    } Display.destroy();

}

我不明白。纹理层叠如何影响深度测试?为什么必须扩展投影体积?啊,你使用多个在“z”方向上移动的四边形,结合混合吗?所以你没有使用着色器?请详细说明/重新表述你的问题。 - Stefan Hanke
是的,你说得对。使用z来在视图中分层它们,以便一些会比其他的更靠后。 - GlassZee
你能展示一下实现这个的代码吗?使用这种多重纹理,你需要按照从后往前的顺序排列四边形以使混合工作。你使用屏幕对齐的四边形吗? - Stefan Hanke
我不知道为什么需要混合。我不确定什么是屏幕对齐;每个四边形都有自己的坐标。 - GlassZee
2个回答

1

如果您的上下文包括深度缓冲区(不确定lwjgl缓冲区创建...)

您所需要的只是:

  • 在初始化期间调用glEnable(GL_DEPTH_TEST)
  • 将深度缓冲区位添加到glClear中glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  • 将z坐标定义为正交矩阵的近和远值之间。

我尝试了你说的,但背景仍然是黑色。原帖中有更多细节。 - GlassZee
@GlassZee:如果您不使用深度测试,这段代码实际上是否有效?首先,您需要在每次调用glOrtho之前调用glLoadIdentity(它将正交矩阵乘以当前堆栈中的内容)。此外,我不是100%确定,但我相信near的值必须小于far的值(目前您的near> far),这可能会搞砸事情。 - Tim
@Tim 哦,好吧,我正在为此撰写一个不错的答案,然后才看到你的评论... - Stefan Hanke
是的,即使没有深度测试,它也可以工作,但明显纹理是从背面视图查看的。我会尝试把一切都修复好,然后再尝试你说的方法。我今天实际上要坐飞机,所以直到稍后才能做这件事。 - GlassZee

1

看起来你把近平面和远平面搞反了。看一下gluOrtho2D。它只是调用glOrtho,并将near=-1far=+1,导致z坐标的符号切换(m33=-2/(far-near))。然而,根据上面给出的值,m33=-2/(-10-1)是正数,z轴反转到标准工作流程。

这会导致四边形从后面被查看。

OpenGL矩阵操作方法不关心你输入什么;除非值会导致除以零。


假设没有模型视图变换,只有一个矩阵对投影矩阵产生贡献,我认为发生了以下情况:

从世界空间到NDC空间的z值变换为z_ndc = -9/11 * z_w + 2/11(将近和远设置到正交矩阵中并取第三行)。现在,z_w=-2,因此z_ndc = 20/11。这超出了NDC空间边界并被抛弃。

好的,我假设这个测试是隐式启用/禁用的Z测试本身。下一个嫌疑对象将是背面剔除...


你坚持认为我应该使用gluOrtho2D,然后尝试添加深度测试吗? - GlassZee
不,我只是指向了gluOrtho2D来展示它如何调用glOrtho。将最后两个参数更改为类似near=-10far=+10的值。重新启用深度测试后,四边形现在应该是可见的。 - Stefan Hanke
谢谢,伙计,它起作用了。我现在遇到的问题是,当我将带有透明度的纹理放在另一个纹理上时,第二个纹理不会显示在透明度应该存在的地方下面。http://i.imgur.com/sTNU8.png?1 这是我用透明文本覆盖蓝色纹理正方形做的一个快速演示。文本的z值为0,正方形的z值为-9。如何使纹理在其他纹理的透明度后面显示? - GlassZee
1
你需要设置混合。查找 glBlendFunc这里有一个不错的游乐场。 - Stefan Hanke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接