我一直在“黑客”我年轻时最喜欢的游戏之一,我设法能够拦截OpenGL调用并使用opengl32.dll封装注入C++代码。我已经能够为此提出一些很酷的用途,但是我目前的目标是在这个旧游戏中实现后处理glsl着色器,使其看起来更现代一些。该游戏最初是在90年代后期发布的,因此它对OpenGL及其渲染代码的使用是有限的/原始的/过时的。注入帧缓冲区
我已经能够通过注入代码来初始化和使用glsl着色器程序来成功地生成顶点和片段着色器,但是我的问题在于产生一个帧缓冲器/渲染我的场景到一个纹理,作为一个采样器发送给我的片段着色器。据我所知,我生产的纹理通常都是黑色的。
很难找到与我正在做的事情相关的资源,并检查原始的opengl调用(我一直试图通过阅读单帧游戏的opengl轨迹来确定插入代码的位置),所以我一直没有能够把我的头围绕我做错了什么。
我试过把代码放在很多地方,但是目前我在游戏后调用wglSwapBuffers()
绑定了framebuffer,我在下一次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 ...
Here是单个帧的gl轨迹。
它接近800行,但训练有素的opengl眼睛应该能够看到什么时候拨打电话。我删除了几百行我最近了解的绘图调用。
也许尝试通过glReadPixels更新纹理,而不是只是为了查看其余代码是否正确? – 2013-04-07 13:06:48