这可能听起来像一个奇怪的问题,但这就是故事:
有一个小但顽固的社区,仍然在玩2005-6岁的游戏(帝国时代III +扩张)。有些在Windows上播放,有些在OS X上播放(游戏也在OS X上播放)。
问题是当游戏在OS X上启动时,每个人都可以在中高着色器设置上播放,似乎当时显卡已被正确识别。然而,一旦新型号获得英特尔图形芯片(Intel HD 4000,Iris等),中等和更高着色器设置就会停止工作。
同一款游戏现在可以在Windows上正确显示中高度着色器,但在同一台机器上的OS X中无法显示(使用双启动)。所以,它不是硬件问题。相同的图形芯片可以在Windows上显示高着色器(在DirectX环境中),但在OS X(在OpenGL环境中)中无法显示。
我首先想到这是因为移植此游戏的公司(Macsoft)没有调整OpenGL的着色器编程,但显然他们做到了。而且由于高着色器曾经在OS X中工作,这意味着他们的OpenGL适应性适用于不同的硬件。所以,这似乎是游戏制作者如何编写配置文件以识别硬件设备的问题,不知何故,较新的英特尔图形芯片无法识别为支持DirectX 8/9 Shader model v 2.0,并且默认为基本的DirectX 7功能没有任何着色器。
我在游戏文件中做了一些研究,试图追踪哪个文件让游戏识别图形芯片,我从这个文件夹中找到了它的devices.xml(我上传了所有着色器googledrive中的文件,以防有人想看一下):
我发现游戏忽略了devices.xml文件中的所有内容,并跳转到具有最低着色器设置的最后一个通用设备:
<device name="GenericFF">
generic dx7
<low>Generic DX7</low>
</device>
如果我用Generic DX8设置替换此设备,游戏会开始显示更多着色器,但水渲染会产生一些奇怪的颜色范围,从绿色到紫色。
此Generic DX7配置文件也在一个名为Generic DX7.d3dconfig的单独文件中编码,您可以在我之前提到的/ Config /文件夹中找到它。在此文件中,您可以找到许多设置,例如:
<d3dconfig>
<fixedfunctionverts>true</fixedfunctionverts>
<techniques>
<enable>alpha transparency</enable>
<enable>alphatest</enable>
<enable>alphatest_flatcolor</enable>
<enable>alphatest_blendcolor</enable>
每个着色器功能都有自己的设置文件,例如alphatest(在/ techniques /文件夹中):
<technique>
<pass>
<texture stage="0">diffuse</texture>
<rs>alphatest</rs>
<tss>default</tss>
</pass>
</technique>
当然,最后所有这些以XML格式编码的配置文件指向着色器编程文件,例如/ Render / ps /文件夹中的default_shader.psh:
ps.1.1
def c7, 1, 0, 0, 0
tex t0 //base texture
#ifdef ENVMAP
tex t2 //envmap texture
#endif
mul_x2 r0.rgb, t0, v0 // texture * light
+mul r0.a, t0, v0 // texture * light
#ifdef ENVMAP
// reflectivity is a float value in the r component so the dp3 is a
// clunky way to propogate this value into all components before the lerp
dp3 r1, c6, c7
lrp r0, r1, t2, r0
#endif
#ifdef TREE
add r0, r0, c1
#endif
#ifdef TINT
add r0, r0, c0
#endif
问题是: 是否有可能使这个老游戏(使用旧的着色器编程,支持Shader模型2.0)识别更新的英特尔图形芯片,或者这是OS X上的游戏如何移植到OpenGL环境的问题?
更新:
还有另一个文件夹似乎未被游戏使用,其中一个与我上面提到的文件同名的文件包含如下代码:
// default_shader.psh
#ifdef TREE
uniform vec4 pc1;
#endif
#ifdef TINT
uniform vec4 pc0;
#endif
uniform sampler2D tx0;
void main()
{
vec4 diffuse = vec4( texture2D(tx0, gl_TexCoord[0].st) ) * gl_Color;
diffuse.xyz *= 2.0;
#ifdef TREE
diffuse += pc1;
#endif
#ifdef TINT
diffuse += pc0;
#endif
gl_FragColor = diffuse;
}
/*
ps.1.1
def c7, 1, 0, 0, 0
tex t0 //base texture
#ifdef ENVMAP
tex t2 //envmap texture
#endif
mul_x2 r0.rgb, t0, v0 // texture * light
+mul r0.a, t0, v0 // texture * light
#ifdef ENVMAP
// reflectivity is a float value in the r component so the dp3 is a
// clunky way to propogate this value into all components before the lerp
dp3 r1, c6, c7
lrp r0, r1, t2, r0
#endif
#ifdef TREE
add r0, r0, c1
#endif
#ifdef TINT
add r0, r0, c0
#endif
*/
答案 0 :(得分:0)
我的结论是,这很可能是不可能的,因为OpenGL移植的很大一部分涉及为每个专有设备进行单独的着色器编程。
例如,在/ shaders /文件夹中,为每个主要制造商提供了单独的地形阴影渲染文件,为运行OS X(ATI和nVidia)的机器提供了图形卡:terrain shadow only_ati.vsh和terrain shadow only_nv .psh。它们有不同的方法来渲染相同的东西:
// terrain shadow only_ati.vsh
uniform mat4 vc0; // worldViewProj
uniform mat4 vc4;
uniform mat4 vc8;
uniform vec4 vc12;
void main()
{
// transform position
gl_Position = gl_Vertex * vc0;
// Set to constant color
gl_FrontColor = vec4(0.0);
// transform
gl_TexCoord[0] = gl_Vertex * vc4;
// Depth in light space
vec4 r1 = gl_Vertex * vc8;
gl_TexCoord[1].s = r1.z * vc12.x;
}
和
// terrain shadow only_nv.vsh
uniform mat4 vc0; // worldViewProj
uniform mat4 vc4;
uniform vec4 vc15; // texture filtering offsets
uniform vec4 vc16;
uniform vec4 vc17;
void main()
{
// transform position
gl_Position = gl_Vertex * vc0;
// Set to constant color
gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
// transform
vec4 r0 = gl_Vertex * vc4;
r0.y = 1.0 - r0.y; // Invert y (reading from a GL buffer)
//-- compute PCF Filter texture offsets
gl_TexCoord[0] = r0 + vc15;
gl_TexCoord[2] = r0 + vc16;
gl_TexCoord[3] = r0 + vc17;
}
由于英特尔芯片没有这样的OpenGL移植,这意味着在这款游戏的OpenGL部分可能不支持中等和更高的阴影。