OpenGL纹理结合不(总是)工作

时间:2009-07-21 02:01:02

标签: opengl textures jogl

如果你已经看过我最近几个问题,你现在已经知道我一直在研究OpenGL的地形。我尝试使用顶点alphas和多个渲染过程在一个平铺的高度图中将一个纹理混合到另一个纹理中失败了......所以现在我有了另一个计划。

我的WorldQuad对象有'bottom'和'top'变量,两者都是Texture类型。这是一个JOGL提供的包装OpenGL纹理的类;它为我加载它,然后我可以调用enable()来执行glEnable(GL_TEXTURE_2D),并使用bind()来执行绑定。

它还有一个我自己类型的alphaMap变量,它存储了另一个纹理;但这个是纹理内部格式GL_ALPHA8(换句话说,它是一个只有alpha值的纹理)。我目前以编程方式生成它以使其像素完美。

然后我使用OpenGL“纹理合并”(或纹理喷溅它有时被称为),以便根据alpha贴图组合底部和顶部纹理。

事情是,它在我的工作笔记本电脑上工作得很漂亮!!它是带有集成英特尔芯片(GMA950或类似产品)的IBM Thinkpad T400。但是我带着分立的NVIDIA GeForce Go 7900GS卡回到我的戴尔Inspiron E1705,发现我的程序只渲染了具有“底部”纹理的四边形。这就好像根本没有应用alpha。我也尝试过两台台式机和另一台笔记本电脑。其中一个桌面崩溃,另一个显示四边形全白(这是一个旧的GeForce芯片,可能不支持OpenGL 2或其他东西),而另一台笔记本电脑的表现与我的相同;底部纹理覆盖的四边形。

我已经尝试将alpha地图格式更改为GL_RGBA,以防我的图形卡出于某种原因不喜欢GL_ALPHA8纹理。我还验证了所有三个纹理都可以渲染,通过绘制每个单独纹理的正常四边形,包括alphamap。我还将alphamap输出到一个文件,所以我基本上已经仔细检查过它是否存在并且应该正常工作。

以下是基于所有这些绘制四边形的功能。我添加了评论,希望你能跟进。请提出可能解决问题的建议。我很难过!为什么它会在一个糟糕的集成芯片上运行而不是我的显卡呢?我错过了什么?

谢谢!

编辑:好的,显然没有人可以帮助我...我现在重新开始工作,将我的闪存驱动器插入我的工作计算机,启动Eclipse并点击运行按钮......它工作正常。然后我拿出驱动器,把它放在我的个人笔记本电脑(我今天带到工作中)并做了完全相同的事情,它只是一个红色斑点。但在这里,我记录了它。首先,the output from glGetString(GL_EXTENSIONS), diffed between the two computers

接下来,screenshots of broken and working。 再次,这些采取完全相同的方式:打开Eclipse,按下运行,截图。而已。我没有触摸我的代码,我的代码只有一个副本,在我在两台计算机之间交换的闪存驱动器上。它们都具有相同版本的JDK。

现在计算机之间的区别之一是我的工作PC正在运行XP而我的笔记本电脑正在运行Windows 7.但这真的会有所作为吗?特别是因为我正在使用OpenGL 2,我认为两台计算机都会同样支持它。事实上,如果你看看上面我的差异页面,我的个人笔记本电脑支持的功能比工作笔记本电脑多得多 - 正如我所料,因为它是一个nvidia 7900gs卡,而不是intel集成。所以这似乎倒退了;如果有的话,我希望集成芯片能够阻止纹理组合,而不是我的显卡!

帮助!

public void drawWorldQuad(GL2 gl, float x, float z, WorldQuad q, WorldVertex tl, WorldVertex tr, WorldVertex bl, WorldVertex br) {
    WorldVertex[] verts = new WorldVertex[] {
        bl, br, tr, tl
    };
    final float[][] texCoords = new float[][] {
            {0.0f, 0.0f},
            {1.0f, 0.0f},
            {1.0f, 1.0f},
            {0.0f, 1.0f}
    };
    final float[][] coords = new float[][] {
            {x,z},
            {x+1,z},
            {x+1,z+1},
            {x,z+1}
    };

    gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    /* BEGIN TEXTURE BLENDING SECTION: */

    /* TEXTURE0 is the alpha map; a texture of type GL_ALPHA8, no rgb channels */
    gl.glActiveTexture(GL2.GL_TEXTURE0);
    q.alphaMap.getTexture().bind();
    q.alphaMap.getTexture().enable();
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL);

    /* TEXTURE1 is the 'bottom' texture */
    gl.glActiveTexture(GL2.GL_TEXTURE1);
    q.bottom.getTexture().bind();
    q.bottom.getTexture().enable();
    // use the rgb from the bottom texture
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_COMBINE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, GL2.GL_DECAL);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE0_RGB, GL2.GL_TEXTURE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND0_RGB, GL2.GL_SRC_COLOR);
    //------------------------
    // use the alpha value from the alphaMap
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_ALPHA, GL2.GL_DECAL);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE0_ALPHA, GL2.GL_PREVIOUS);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND0_ALPHA, GL2.GL_SRC_ALPHA);

    /* TEXTURE2 is the 'top' texture */
    gl.glActiveTexture(GL2.GL_TEXTURE2);
    q.top.getTexture().bind();
    q.top.getTexture().enable();
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_COMBINE);
    // interpolate between texture1 and texture2's colors, using the alpha values
    // from texture1 (which were taken from the alphamap)
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, GL2.GL_INTERPOLATE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE0_RGB, GL2.GL_PREVIOUS);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE1_RGB, GL2.GL_TEXTURE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE2_RGB, GL2.GL_PREVIOUS);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND0_RGB, GL2.GL_SRC_COLOR);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND1_RGB, GL2.GL_SRC_COLOR);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND2_RGB, GL2.GL_SRC_ALPHA);
    //------------------------
    // interpolate the alphas (this doesn't really matter, neither of the textures
    // really have alpha values)
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_ALPHA, GL2.GL_INTERPOLATE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE0_ALPHA, GL2.GL_PREVIOUS);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE1_ALPHA, GL2.GL_TEXTURE);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_SOURCE2_ALPHA, GL2.GL_PREVIOUS);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND0_ALPHA, GL2.GL_SRC_ALPHA);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND1_ALPHA, GL2.GL_SRC_ALPHA);
    gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_OPERAND2_ALPHA, GL2.GL_SRC_ALPHA);

    gl.glBegin(GL2.GL_QUADS);
    {
        for(int j=0;j<verts.length;j++) {
            // (this loop and the arrays used here are for convenience, it just draws
            // a quad; verts.length == 4)

            WorldVertex v = verts[j];

            gl.glMultiTexCoord2f(GL2.GL_TEXTURE0, texCoords[j][0], texCoords[j][3]);
            gl.glMultiTexCoord2f(GL2.GL_TEXTURE1, texCoords[j][0], texCoords[j][4]);
            gl.glMultiTexCoord2f(GL2.GL_TEXTURE2, texCoords[j][0], texCoords[j][5]);

            gl.glVertex3f(coords[j][0], (float)v.height * VERTICAL_SCALE, coords[j][6]);
        }
    }
    gl.glEnd();

}

1 个答案:

答案 0 :(得分:4)

IT工作!!经过几个小时的尝试,我终于明白了。

设置TEXTURE0后,我改变了这一行:

gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL);

到此:

gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);

我只是随心所欲地改变它,因为我仍然不清楚DECAL和REPLACE之间的区别,并且它有效!