【发布时间】:2016-03-28 03:23:15
【问题描述】:
我正在尝试在 3d 桌面游戏中绘制自定义 opengl 叠加层(例如 Steam 就是这样做的)。 这个叠加层基本上应该能够显示用户的一些变量的状态 可以通过按一些键来影响。把它想象成一个游戏教练。 目标首先是在屏幕上的特定点绘制一些图元。稍后我想在游戏窗口中有一个漂亮的“gui”组件。 游戏使用 GDI32.dll 中的“SwapBuffers”方法。 目前,我能够将自定义 DLL 文件注入游戏并挂钩“SwapBuffers”方法。 我的第一个想法是将覆盖图插入到该函数中。这可以通过将游戏中的 3d 绘图模式切换为 2d 来完成,然后在屏幕上绘制 2d 叠加层并再次将其切换回来,如下所示:
//SwapBuffers_HOOK (HDC)
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glOrtho(0.0, 640, 480, 0.0, 1.0, -1.0);
//"OVERLAY"
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0, 0);
glVertex2f(0.5f, 0);
glVertex2f(0.5f, 0.5f);
glVertex2f(0.0f, 0.5f);
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
SwapBuffers_OLD(HDC);
但是,这对游戏根本没有任何影响。
- 我的方法是否正确合理(同时考虑到我的 3d 到 2d 切换代码)?
- 我想知道在挂钩函数中设计和显示自定义叠加层的最佳方法是什么。 (我应该使用 windows 窗体之类的东西,还是应该用 opengl 函数组装我的组件 - 线、四边形 ...?)
- SwapBuffers 方法是绘制叠加层的最佳位置吗?
任何类似的提示、源代码或教程也值得赞赏。 顺便说一下游戏是反恐精英1.6,我不打算在网上作弊。
谢谢。
编辑:
我可以通过使用 'derHass' 提出的新 opengl 上下文在游戏窗口中绘制一个简单的矩形。这是我所做的:
//1. At the beginning of the hooked gdiSwapBuffers(HDC hdc) method save the old context
GLboolean gdiSwapBuffersHOOKED(HDC hdc) {
HGLRC oldContext = wglGetCurrentContext();
//2. If the new context has not been already created - create it
//(we need the "hdc" parameter for the current window, so the initialition
//process is happening in this method - anyone has a better solution?)
//Then set the new context to the current one.
if (!contextCreated) {
thisContext = wglCreateContext(hdc);
wglMakeCurrent(hdc, thisContext);
initContext();
}
else {
wglMakeCurrent(hdc, thisContext);
}
//Draw the quad in the new context and switch back to the old one.
drawContext();
wglMakeCurrent(hdc, oldContext);
return gdiSwapBuffersOLD(hdc);
}
GLvoid drawContext() {
glColor3f(1.0f, 0, 0);
glBegin(GL_QUADS);
glVertex2f(0,190.0f);
glVertex2f(100.0f, 190.0f);
glVertex2f(100.0f,290.0f);
glVertex2f(0, 290.0f);
glEnd();
}
GLvoid initContext() {
contextCreated = true;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640, 480, 0.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 1.0);
}
结果如下: cs overlay example 它仍然很简单,但我会尝试添加更多细节、文本等。
谢谢。
【问题讨论】:
-
确保它实际上正在加载,例如。用 printf。此外,如果游戏请求核心配置文件,其中已删除不推荐使用的立即模式和矩阵函数,这将不起作用。
-
@ColonelThirtyTwo Jup 它正在加载。我用一个简单的 glClearColor(GL_COLOR_BUFFER_BIT) 对其进行了测试-> 整个屏幕呈现红色。我怀疑 Counterstrike 1.6 是否使用核心配置文件,因为这款游戏已经过时了。 (我假设)它仍在使用旧的矩阵函数。我已经通过向 glPopMatrix 和 glMatrixMode 方法添加断点对其进行了测试。即使这不是立即模式的明确证据,但游戏使用它而不是仅使用着色器更有意义。
标签: c++ opengl overlay dll-injection