Skip to content

Instantly share code, notes, and snippets.

@neshume
Created October 14, 2012 13:31
Show Gist options
  • Save neshume/3888598 to your computer and use it in GitHub Desktop.
Save neshume/3888598 to your computer and use it in GitHub Desktop.
Create a DC OpenGL for multiple cards
#include <string.h>
#include <windows.h>
#include <gl/gl.h>
#include "glext.h"
#include "wglext.h"
HWND WINAPI window_from_dc_replacement(HDC dc)
{
static HWND wnd = NULL;
if (dc == NULL)
return NULL;
if (wnd == NULL) {
WNDCLASSA wc;
memset(&amp;wc, 0, sizeof(wc));
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = GetModuleHandleA(NULL);
wc.lpszClassName = "_dummy_window_class_";
RegisterClassA(&amp;wc);
wnd = CreateWindowA(wc.lpszClassName, NULL, WS_POPUP, 0, 0, 32, 32, NULL, NULL, wc.hInstance, NULL);
}
return wnd;
}
void patch_window_from_dc()
{
DWORD old_prot;
unsigned __int64 wfdc = (unsigned __int64)GetProcAddress(GetModuleHandleA("user32.dll"), "WindowFromDC");
VirtualProtect((void *)wfdc, 14, PAGE_EXECUTE_WRITECOPY, &amp;old_prot);
// jmp [eip + 0]
*(char *)(wfdc + 0) = 0xFF;
*(char *)(wfdc + 1) = 0x25;
*(unsigned *)(wfdc + 2) = 0x00000000;
*(unsigned __int64 *)(wfdc + 6) = (unsigned __int64)&amp;window_from_dc_replacement;
}
unsigned char buf[4*256*256];
void test_pbuffer()
{
PIXELFORMATDESCRIPTOR pfd;
int pfi;
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
int attribs[] = {
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_DRAW_TO_PBUFFER_ARB, 1,
WGL_COLOR_BITS_ARB, 24,
0 };
int pbf, n;
HPBUFFERARB pb;
HDC pbdc;
const char *vendor;
HGLRC glrc;
HDC dc = CreateDCA("\\\\.\\DISPLAY3", "\\\\.\\DISPLAY3", NULL, NULL);
memset(&amp;pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE|PFD_DEPTH_DONTCARE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfi = ChoosePixelFormat(dc, &amp;pfd);
SetPixelFormat(dc, pfi, &amp;pfd);
glrc = wglCreateContext(dc);
wglMakeCurrent(dc, glrc);
vendor = glGetString(GL_VENDOR);
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
wglChoosePixelFormatARB(dc, attribs, NULL, 1, &amp;pbf, &amp;n);
pb = wglCreatePbufferARB(dc, pbf, 256, 256, NULL);
pbdc = wglGetPbufferDCARB(pb);
wglMakeCurrent(pbdc, glrc);
glClearColor(0.5f, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glScissor(64, 64, 128, 128);
glEnable(GL_SCISSOR_TEST);
glClearColor(0, 1, 0.5f, 0);
glClear(GL_COLOR_BUFFER_BIT);
glReadPixels(0, 0, 256,256, GL_RGBA, GL_UNSIGNED_BYTE, buf);
}
void test_fbo()
{
PIXELFORMATDESCRIPTOR pfd;
int pfi;
void (_stdcall *glGenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
void (_stdcall *glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
void (_stdcall *glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
void (_stdcall *glGenFramebuffers)(GLsizei n, GLuint *framebuffers);
void (_stdcall *glBindFramebuffer)(GLenum target, GLuint framebuffer);
void (_stdcall *glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
GLenum (_stdcall *glCheckFramebufferStatus)(GLenum target);
const char *vendor;
GLuint cb, fb;
GLenum res;
HGLRC glrc;
HDC dc = CreateDCA("\\\\.\\DISPLAY1", "\\\\.\\DISPLAY1", NULL, NULL);
memset(&amp;pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE|PFD_DEPTH_DONTCARE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfi = ChoosePixelFormat(dc, &amp;pfd);
SetPixelFormat(dc, pfi, &amp;pfd);
glrc = wglCreateContext(dc);
wglMakeCurrent(dc, glrc);
vendor = glGetString(GL_VENDOR);
*(PROC *)&amp;glGenRenderbuffers = wglGetProcAddress("glGenRenderbuffers");
*(PROC *)&amp;glBindRenderbuffer = wglGetProcAddress("glBindRenderbuffer");
*(PROC *)&amp;glRenderbufferStorage = wglGetProcAddress("glRenderbufferStorage");
*(PROC *)&amp;glGenFramebuffers = wglGetProcAddress("glGenFramebuffers");
*(PROC *)&amp;glBindFramebuffer = wglGetProcAddress("glBindFramebuffer");
*(PROC *)&amp;glFramebufferRenderbuffer = wglGetProcAddress("glFramebufferRenderbuffer");
*(PROC *)&amp;glCheckFramebufferStatus = wglGetProcAddress("glCheckFramebufferStatus");
glGenRenderbuffers(1, &amp;cb);
glBindRenderbuffer(GL_RENDERBUFFER, cb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 256, 256);
glGenFramebuffers(1, &amp;fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cb);
res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
// if (res != GL_FRAMEBUFFER_COMPLETE) _asm int 3
glClearColor(0.5f, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glReadPixels(0, 0, 256,256, GL_RGBA, GL_UNSIGNED_BYTE, buf);
}
int WINAPI WinMain(HINSTANCE i, HINSTANCE pi, LPSTR cl, int s)
{
patch_window_from_dc();
if (0) {
DISPLAY_DEVICEA dev;
int k = 0;
dev.cb = sizeof(dev);
while (EnumDisplayDevicesA(NULL, k, &amp;dev, 0))
k += 1;
}
test_fbo();
//test_pbuffer();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment