OpenGL包装器中的Alpha /纹理问题

时间:2010-02-10 23:20:32

标签: c++ windows opengl textures render-to-texture

我正在为一些OpenGL函数编写包装器。目标是包装游戏Neverwinter Nights使用的上下文,以便应用后处理着色器效果。在学习OpenGL(这是我第一次尝试使用它)并且大量使用DLL和重定向之后,我有一个有点工作的系统。

但是,当后处理全屏四边形处于活动状态时,游戏绘制的所有纹理和透明度都将丢失。这是不可能的,因为我的所有功能在游戏完成自己的渲染后生效。

代码不使用renderbuffers或framebuffers(尽管被其他程序支持和使用,但两者都拒绝在我的系统上使用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的新手,我真的不知道出了什么问题(或者如何修复它),而且我尝试过的任何东西都没有帮助。我错过了什么?

1 个答案:

答案 0 :(得分:2)

我不太明白你的代码应该如何与Neverwinter Nights代码集成。然而...

您似乎最有可能更改现有代码不会发生变化的某些设置。

根据问题的描述,我尝试删除以下行:

glDisable(GL_TEXTURE_2D);

该行禁用纹理,这肯定听起来像你正在看到的问题。