win-capture: Add game capture fix for darkest dungeon
Darkest dungeon uses an unusual technique for drawing its frames: a fixed 1920x1080 frame buffer used in place of the backbuffer, which is then stretched to fit the size of the screen (whether the screen is bigger or smaller than the actual texture). The custom frame would cause glReadBuffer to initially fail with an error. When this happens, their custom frame buffer is in use, so all that needs to be done is simply reset the capture and force the current output size to 1920x1080 while that custom frame is in use. They presumably did this in order to ensure the game looks the same at any resolution. Instead of having to use power-of-two sprites and mipmaps for every single game sprite and stretch/skew each of them (which would risk the final output "not looking quite right" at different resolutions), they simply use non-pow-2 sprites with no mipmaps and render them all on to one texture of a fixed size and then stretch that final output texture. That ensures that the actual composite of the game still looks the same at any resolution, while reducing texture memory by not requiring each sprite to use a power-of-two texture and mipmaps.
This commit is contained in:
parent
7f0f3d25c9
commit
2591f24594
@ -27,6 +27,8 @@ static struct func_hook wgl_swap_layer_buffers;
|
||||
static struct func_hook wgl_swap_buffers;
|
||||
static struct func_hook wgl_delete_context;
|
||||
|
||||
static bool darkest_dungeon_fix = false;
|
||||
|
||||
struct gl_data {
|
||||
HDC hdc;
|
||||
uint32_t base_cx;
|
||||
@ -231,9 +233,14 @@ static void get_window_size(HDC hdc, uint32_t *cx, uint32_t *cy)
|
||||
HWND hwnd = WindowFromDC(hdc);
|
||||
RECT rc = {0};
|
||||
|
||||
GetClientRect(hwnd, &rc);
|
||||
*cx = rc.right;
|
||||
*cy = rc.bottom;
|
||||
if (darkest_dungeon_fix) {
|
||||
*cx = 1920;
|
||||
*cy = 1080;
|
||||
} else {
|
||||
GetClientRect(hwnd, &rc);
|
||||
*cx = rc.right;
|
||||
*cy = rc.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool gl_shtex_init_window(void)
|
||||
@ -532,10 +539,15 @@ static int gl_init(HDC hdc)
|
||||
bool success = false;
|
||||
RECT rc = {0};
|
||||
|
||||
GetClientRect(window, &rc);
|
||||
if (darkest_dungeon_fix) {
|
||||
data.base_cx = 1920;
|
||||
data.base_cy = 1080;
|
||||
} else {
|
||||
GetClientRect(window, &rc);
|
||||
data.base_cx = rc.right;
|
||||
data.base_cy = rc.bottom;
|
||||
}
|
||||
|
||||
data.base_cx = rc.right;
|
||||
data.base_cy = rc.bottom;
|
||||
data.hdc = hdc;
|
||||
data.format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
data.using_scale = global_hook_info->use_scale;
|
||||
@ -586,9 +598,11 @@ static void gl_copy_backbuffer(GLuint dst)
|
||||
}
|
||||
|
||||
glReadBuffer(GL_BACK);
|
||||
if (gl_error("gl_copy_backbuffer", "failed to set read buffer")) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* darkest dungeon fix */
|
||||
darkest_dungeon_fix =
|
||||
glGetError() == GL_INVALID_OPERATION &&
|
||||
_strcmpi(process_name, "Darkest.exe") == 0;
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
if (gl_error("gl_copy_backbuffer", "failed to set draw buffer")) {
|
||||
|
@ -22,6 +22,8 @@ typedef ptrdiff_t GLsizeiptrARB;
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
|
||||
#define GL_RGB 0x1907
|
||||
|
Loading…
x
Reference in New Issue
Block a user