我正在为一些 OpenGL 函数编写一个包装器。目标是包装游戏 Neverwinter Nights 使用的上下文,以便应用后处理着色器效果。在学习了 OpenGL(这是我第一次尝试使用它)并玩了很多 DLL 和重定向之后,我有了一个可以工作的系统。
但是,当后处理全屏四边形处于活动状态时,游戏绘制的所有纹理和透明度都会丢失。这应该是不可能的,因为我所有的功能都是在游戏完全完成自己的渲染之后才生效的。
该代码不使用渲染缓冲区或帧缓冲区(两者都拒绝以任何方式在我的系统上编译,无论是否使用 GLEW 或 GLee,尽管其他程序支持和使用)。最终,我将这段代码放在一起处理从缓冲区复制纹理并渲染全屏四边形:
extern "C" SEND BOOL WINAPI hook_wglSwapLayerBuffers(HDC h, UINT v)
{
if ( frameCount > 250 )
{
frameCount++;
if ( frameCount == 750 ) frameCount = 0;
if ( nwshader->thisframe == NULL )
{
createTextures();
}
glBindTexture(GL_TEXTURE_2D, nwshader->thisframe);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, nwshader->width, nwshader->height, 0);
glClearColor(0.0f, 0.5f, 0.0f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_BLEND);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho( 0, nwshader->width , nwshader->height , 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 1.0f);
glVertex2d(0, 0);
glTexCoord2f(0.0f, 0.0f);
glVertex2d(0, nwshader->height);
glTexCoord2f(1.0f, 0.0f);
glVertex2d(nwshader->width, nwshader->height);
glTexCoord2f(1.0f, 1.0f);
glVertex2d(nwshader->width, 0);
glEnd();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
} else {
frameCount++;
}
if ( h == grabbedDevice )
{
Log->logline("Swapping buffer on cached device.");
}
return wglSwapLayerBuffers(h,v);
}
这段代码的功能几乎完美无缺,并且没有明显的减速。但是,当它处于活动状态时(我添加了 frameCount 条件以每隔约 5 秒打开和关闭它),游戏渲染器会完全忽略所有 alpha 和纹理。在这个函数之前我没有关闭任何类型的混合或纹理(唯一的 OpenGL 调用是创建 nwshader->thisframe 纹理)。我能够捕捉到一些正在发生的事情的屏幕截图:
破碎的 A:http: //i4.photobucket.com/albums/y145/peachykeen000/outside_brokenA.png
破碎的 B:http: //i4.photobucket.com/albums/y145/peachykeen000/outside_brokenB.png
(注意,在 B 中,后面的烟雾没有损坏,它是正确透明的。HUD 也是如此。)
损坏的内部:http: //i4.photobucket.com/albums/y145/peachykeen000/transparency_broken.png
正确的内部(用于比较):http ://i4.photobucket.com/albums/y145/peachykeen000/transparency_proper.png
四边形的绘制也打破了菜单,将整个东西变成了一个黑色的表面,带有一个白色的盒子。我怀疑这是深度或游戏如何绘制某些对象的问题,或者是未正确重置的状态。我已经使用 GLintercept 转储了一帧中所有调用的完整日志,并且没有发现任何错误(对 wglSwapLayerBuffers 的调用始终是最后一个)。
作为使用 OpenGL 的新手,我真的不知道出了什么问题(或如何修复它),而且我尝试过的没有任何帮助。我错过了什么?