私は若い頃からお気に入りのゲームの 1 つを「ハッキング」しており、opengl32.dll ラッパーを使用して OpenGL 呼び出しをインターセプトし、C++ コードを挿入することができました。このためのいくつかのクールな使用法を思いつくことができましたが、私の現在の目標は、この古いゲームにポスト プロセッシング glsl シェーダーを実装して、もう少し現代的に見えるようにすることです。このゲームはもともと 90 年代後半にリリースされたものであるため、OpenGL の使用とそのレンダリング コードは限定的/原始的/時代遅れです。
コードを挿入して glsl シェーダー プログラムを初期化して使用することにより、頂点シェーダーとフラグメント シェーダーを正常に生成できましたが、問題はフレーム バッファーの生成/シーンをテクスチャにレンダリングして、フラグメント シェーダーにサンプラーとして送信することにあります。私の知る限り、私が作成するテクスチャは通常すべて黒です。
私がしていることに関連するリソースを見つけたり、生のopengl呼び出しを調べたりするのは難しいです(ゲームプレイの単一フレームのopenglトレースを読んで、コードを挿入する場所を決定しようとしています)。私が間違っていることに頭を包むことができます。
コードをいろいろな場所に入れてみましたが、現在、ゲーム呼び出しの後にフレームバッファをバインドしwglSwapBuffers()
、次の呼び出しが行われる直前にバインドを解除していglFlush()
ますが、複数のビューポートがセットアップされているかどうかはわかりません。または行列演算、またはこれらの時間の間に作成されたその他のものは、どういうわけかフレームバッファをいじっています。
フレームバッファを初期化するコードは次のとおりです。
void initFB()
{
/* Texture */
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &fbo_texture);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
/* Depth buffer */
glGenRenderbuffers(1, &fbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1920, 1080);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
/* Framebuffer to link everything together */
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
GLenum status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "glCheckFramebufferStatus: error %p", status);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
これは後に呼び出されるコードですwglSwapBuffers
:
GLenum fboBuff[] = { GL_COLOR_ATTACHMENT0 };
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDrawBuffers(1, fboBuff);
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
これは前に呼び出されたコードですglFlush()
:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopAttrib(); // Restore our glEnable and glViewport states
... Draw an Overlay containing with fbo texture binded ...
これは、単一フレームの gl トレースです。
これは 800 行近くありますが、訓練された OpenGL の目があれば、いつどのような呼び出しが行われたかを確認できるはずです。少なくとも理解できる数百行の描画呼び出しを削除しました。