いくつかの 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 秒ごとにオンとオフを切り替えました)、すべてのアルファとテクスチャリングはゲーム レンダラーによって完全に無視されます。この関数の前に、ブレンドやテクスチャリングをオフにすることはありません (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 を使用するのは初めてなので、何が問題なのか (またはそれを修正する方法) がまったくわかりません。私は何が欠けていますか?