2015-12-21 107 views
2

我想在3D桌面遊戲中繪製一個自定義的opengl覆蓋圖(例如蒸汽)。 這個覆蓋層應該基本上能夠顯示一些變量的狀態,用戶可以通過按下一些鍵來影響這些變量。想想它就像一個遊戲教練。 目標是首先在屏幕上的特定點繪製幾個基元。後來我想在遊戲窗口中看到一個漂亮的「gui」組件。 遊戲使用GDI32.dll中的「SwapBuffers」方法。 目前我能夠注入一個自定義DLL文件到遊戲中並掛鉤「SwapBuffers」方法。 我的第一個想法是將覆蓋圖的圖形插入到該函數中。這可以通過從遊戲到2D切換3D繪圖方式來完成,然後在屏幕上繪製的2D覆蓋,並再次打開它,像這樣:dll注入:用opengl繪製簡單的遊戲覆蓋圖

//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 它仍然是非常簡單的,但我會盡量等添加一些更多的細節,文本。

謝謝。

+1

確保它的實際加載,恩。用printf。此外,如果遊戲請求核心配置文件,不推薦使用即時模式和矩陣功能,則這不起作用。 –

+0

@ColonelThirtyTwo Jup它正在被加載。我用一個簡單的glClearColor(GL_COLOR_BUFFER_BIT) - >整個屏幕呈現紅色來測試它。我懷疑反衝擊1.6是使用核心配置文件,因爲這個遊戲已經很老了。 (我認爲)它仍在使用舊的矩陣函數。我已經通過向glPopMatrix和glMatrixMode方法添加斷點來測試它。即使這不是直接模式的明確證據,只是更有意義的是,遊戲只使用它而不是着色器。 –

回答

1

如果遊戲使用OpenGL,然後掛接到SwapBuffers是去,原則的方式。理論上,可能有不同的drawable,你可能需要在交換緩衝區函數中決定哪一個是正確的修改。

有幾個問題與此類OpenGL的攔截,雖然:

  1. OpenGL是一個狀態機。應用程序可能修改了任何GL狀態變量。您提供的代碼遠遠不夠完整,以確保繪製某些內容。例如,如果應用程序恰好啓用了着色器,則您的所有矩陣設置可能都無效,屏幕上顯示的內容取決於着色器。 如果進行了深度測試,那麼您的碎片可能落在已經繪製的背後。如果多邊形剔除處於打開狀態,那麼您的原始圖層可能會錯誤地繞過翹曲剔除模式。如果顏色掩碼設置爲GL_FALSE或繪圖緩衝區未設置爲您所期望的位置,則不顯示任何內容。

    另外請注意,你的企圖「重啓」矩陣也是錯誤的。你似乎認爲當前的矩陣模式是GL_MODELVIEW。但事實並非如此。它可能是GL_PROJECTIONGL_TEXTURE。您還可以將glOrtho應用於當前的投影矩陣,而不首先加載身份,因此僅憑這一點是屏幕上不顯示任何內容的好理由。

  2. 由於OpenGL是一個狀態機,也必須還原所有你感動的狀態。您已經使用矩陣堆棧push/pop來嘗試此操作。但是,例如,您無法恢復確切的矩陣模式。正如你在1中看到的那樣,需要更多的狀態更改,因此恢復它將更加複雜。由於您使用傳統的OpenGL,因此glPushAttrib()可能會在這裏派上用場。

  3. SwapBuffers不是GL功能,但操作系統的API之一。它得到一個可繪製的參數,並且只是間接引用任何GL上下文。 可能會在另一個GL上下文被綁定到該線程時被調用,或者根本沒有。如果您想安全玩,您還必須攔截GL上下文創建功能以及MakeCurrent。在最糟糕的情況下(儘管不太可能),應用程序在調用SwapBuffers時將GL上下文綁定到另一個線程,因此掛鉤函數中的上下文沒有變化。

把所有這一切共同開闢了另一種選擇:你可以鉤住SwapBuffers通話過程中臨時創建自己的GL上下文,將其綁定,並恢復原來的再次結合。這樣,你根本不會干擾應用程序的GL狀態。您仍然可以增加應用程序渲染的圖像內容,因爲幀緩衝區是可繪製部分的一部分,而不是GL上下文。這樣做可能會對性能產生負面影響,但它可能非常小,以至於您甚至不會注意到它。

由於您只想爲單個特定應用程序執行此操作,因此另一種方法是通過觀察在SwapBuffers調用期間應用程序實際設置的GL狀態,瞭解必要的最小狀態更改。像apitrace這樣的工具可以幫助你。

+0

我絕對推薦爲疊加使用專用的OpenGL上下文。關於上下文切換開銷,'... _ARB_context_flush_control'擴展給你提供了很多擺動空間。 https://www.opengl.org/registry/specs/KHR/context_flush_control.txt – datenwolf

+0

如何使用上下文沖水控制上的東西,你沒有自己的背景?您可以使新的上下文不會刷新,但主要上下文將會。 上下文交換每SwapBuffers調用破壞性能,也沒有工作的權利至少一個AMD卡我已經試過。這就是Mumble(VOIP/overlay遊戲應用)所做的一樣,它也遭遇同樣的問題。請參閱http:// stackoverflow。com/questions/39713133/performant-hook-of-opengl-draw-an-overlay-problems-with-multiple-context – aggieNick02

+0

@ aggieNick02:好吧,從概念上講,你也可以掛鉤創建上下文...... – derhass