如果你看过我最后的几个问题,你现在就会知道我一直在使用 OpenGL 处理地形问题。我尝试使用顶点 alpha 和多个渲染通道将一个纹理混合到另一个纹理中的平铺高度图中失败了……所以现在,我有了另一个计划。
我的 WorldQuad 对象有 'bottom' 和 'top' 变量,两者都是 Texture 类型。这是一个 JOGL 提供的封装 OpenGL 纹理的类;它为我加载它,然后我可以调用 enable() 让它执行 glEnable(GL_TEXTURE_2D),并调用 bind() 让它执行绑定。
它还有一个我自己类型的 alphaMap 变量,它存储了另一个纹理;但是这个是纹理内部格式 GL_ALPHA8 (换句话说,它是一个只有 alpha 值的纹理)。我目前以编程方式生成它以使其像素完美。
然后我使用 OpenGL“纹理组合”(或有时称为纹理喷溅)来根据 alpha 贴图组合底部和顶部纹理。
问题是,它工作得很好!......在我的工作笔记本电脑上。它是带有集成 Intel 芯片(GMA950 或类似芯片)的 IBM Thinkpad T400。但当我回到我的戴尔 Inspiron E1705 时,我发现我的程序只渲染了具有“底部”纹理的四边形。就好像根本没有应用 alpha。我还在两台台式机和另一台笔记本电脑上尝试过。其中一台台式机崩溃了,另一台显示四边形全白(它是旧的 GeForce 芯片,可能不支持 OpenGL 2 或其他东西),另一台笔记本电脑的性能与我的相同;覆盖在底部纹理中的四边形。
我已经尝试将 alpha 映射格式更改为 GL_RGBA,以防我的显卡由于某种原因不喜欢 GL_ALPHA8 纹理。我还验证了所有三个纹理都存在并且可以通过使用每个单独的纹理(包括 alphamap)绘制法线四边形来渲染。我还将 alphamap 输出到一个文件中,所以我基本上仔细检查了它是否存在并且应该可以工作。
下面是我基于所有这些绘制四边形的函数。我添加了评论,希望您能继续关注。请提出任何可能解决问题的建议。我难住了!为什么它可以在一个蹩脚的集成芯片上工作,而不是我的显卡?我错过了什么??
谢谢!!
编辑:好的,显然没有人可以帮助我......我现在回到工作岗位,将我的闪存驱动器插入我的工作计算机,启动 Eclipse 并点击运行按钮......它工作了。然后我把驱动器拿出来,放进我的个人笔记本电脑(我今天带去上班),做了同样的事情,它只是一个红色的斑点。但是在这里,我记录了它。首先,来自 glGetString(GL_EXTENSIONS) 的输出在两台计算机之间存在差异。
接下来,损坏和工作的屏幕截图。同样,这些都是以完全相同的方式拍摄的:打开 Eclipse,按运行,截屏。就是这样。我没有碰我的代码,我的代码只有一个副本,在我在两台计算机之间交换的闪存驱动器上。它们都具有相同版本的 JDK。
现在,两台计算机之间的区别之一是我的工作 PC 运行的是 XP,而我的笔记本电脑运行的是 Windows 7。但这真的会有所作为吗?特别是因为我使用的是 OpenGL 2,我认为两台计算机都会同样支持它。事实上,如果你看看我上面的差异页面,我的个人笔记本电脑支持的扩展比工作笔记本电脑多得多——正如我所预料的那样,因为与英特尔集成相比,它是一个 nvidia 7900gs 卡。所以这似乎倒退了;如果有的话,我希望集成芯片会阻塞纹理组合,但不是我的显卡!
帮助!
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();
}