summaryrefslogtreecommitdiff
path: root/src/OffscreenContextWGL.cc
diff options
context:
space:
mode:
authordonbright <hugh.m.bright@gmail.com>2013-03-05 23:47:14 (GMT)
committerdonbright <hugh.m.bright@gmail.com>2013-03-05 23:47:14 (GMT)
commit42f21c3a0850083d245aa3ac346a53e876f0679e (patch)
treefacf41750e0fe27cc4cdaf352c9c8e687011d103 /src/OffscreenContextWGL.cc
parent422c668dcb538f181683ae51305bf8d3404f48d6 (diff)
parent4734172c3a16cc06b09e4d2131aa8e380bd0f226 (diff)
Merge pull request #288 from openscad/issue11_2
Issue11 2
Diffstat (limited to 'src/OffscreenContextWGL.cc')
-rw-r--r--src/OffscreenContextWGL.cc214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/OffscreenContextWGL.cc b/src/OffscreenContextWGL.cc
new file mode 100644
index 0000000..0ccd68d
--- /dev/null
+++ b/src/OffscreenContextWGL.cc
@@ -0,0 +1,214 @@
+/*
+
+Create an OpenGL context without creating an OpenGL Window. for Windows.
+
+For more info:
+
+ http://www.nullterminator.net/opengl32.html by Blaine Hodge
+ http://msdn.microsoft.com/en-us/library/ee418815(v=vs.85).aspx
+ http://www.cprogramming.com/tutorial/wgl_wiggle_functions.html by RoD
+ ( which includes robot.cc by Steven Billington )
+ http://blogs.msdn.com/b/oldnewthing/archive/2006/12/04/1205831.aspx by Tom
+*/
+
+#include <windows.h>
+#include <vector>
+
+#include "OffscreenContext.h"
+#include "printutils.h"
+#include "imageutils.h"
+#include "system-gl.h"
+#include "fbo.h"
+
+#include <GL/gl.h> // must be included after glew.h
+
+#include <map>
+#include <string>
+#include <sstream>
+
+using namespace std;
+
+struct OffscreenContext
+{
+ HWND window;
+ HDC dev_context;
+ HGLRC openGLContext;
+ int width;
+ int height;
+ fbo_t *fbo;
+};
+
+#include "OffscreenContextAll.hpp"
+
+void offscreen_context_init(OffscreenContext &ctx, int width, int height)
+{
+ ctx.window = (HWND)NULL;
+ ctx.dev_context = (HDC)NULL;
+ ctx.openGLContext = (HGLRC)NULL;
+ ctx.width = width;
+ ctx.height = height;
+ ctx.fbo = NULL;
+}
+
+string get_os_info()
+{
+ OSVERSIONINFO osvi;
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ map<WORD,const char*> archs;
+ archs[PROCESSOR_ARCHITECTURE_AMD64] = "amd64";
+ archs[PROCESSOR_ARCHITECTURE_IA64] = "itanium";
+ archs[PROCESSOR_ARCHITECTURE_INTEL] = "x86";
+ archs[PROCESSOR_ARCHITECTURE_UNKNOWN] = "unknown";
+
+ stringstream out;
+ out << "OS info: "
+ << "Microsoft(TM) Windows(TM) " << osvi.dwMajorVersion << " "
+ << osvi.dwMinorVersion << " " << osvi.dwBuildNumber << " "
+ << osvi.szCSDVersion;
+ if (archs.find(si.wProcessorArchitecture) != archs.end())
+ out << " " << archs[si.wProcessorArchitecture];
+ out << "\n";
+
+ out << "Machine: " << si.dwProcessorType;
+
+ return out.str();
+}
+
+string offscreen_context_getinfo(OffscreenContext *ctx)
+{
+ // should probably get some info from WGL context here?
+ stringstream out;
+ out << "GL context creator: WGL\n"
+ << "PNG generator: lodepng\n"
+ << get_os_info();
+ return out.str();
+}
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ return DefWindowProc( hwnd, message, wparam, lparam );
+}
+
+bool create_wgl_dummy_context(OffscreenContext &ctx)
+{
+ // this function alters ctx->window and ctx->openGLContext
+ // and ctx->dev_context if successfull
+
+ // create window
+
+ HINSTANCE inst = GetModuleHandle(0);
+ WNDCLASS wc;
+ ZeroMemory( &wc, sizeof( wc ) );
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = WndProc;
+ wc.hInstance = inst;
+ wc.lpszClassName = (LPCWSTR)"OpenSCAD";
+ RegisterClass( &wc );
+
+ HWND window = CreateWindow( (LPCWSTR)"OpenSCAD", (LPCWSTR)"OpenSCAD",
+ WS_CAPTION | WS_POPUPWINDOW, //| WS_VISIBLE,
+ 0, 0, ctx.width, ctx.height, NULL, NULL, inst, NULL );
+
+ if ( window==NULL ) {
+ cerr << "MS GDI - CreateWindow failed\n";
+ return false;
+ }
+
+ // create WGL context, make current
+
+ PIXELFORMATDESCRIPTOR pixformat;
+ int chosenformat;
+ HDC dev_context = GetDC( window );
+ if ( dev_context == NULL ) {
+ cerr << "MS GDI - GetDC failed\n";
+ return false;
+ }
+
+ ZeroMemory( &pixformat, sizeof( pixformat ) );
+ pixformat.nSize = sizeof( pixformat );
+ pixformat.nVersion = 1;
+ pixformat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pixformat.iPixelType = PFD_TYPE_RGBA;
+ pixformat.cGreenBits = 8;
+ pixformat.cRedBits = 8;
+ pixformat.cBlueBits = 8;
+ pixformat.cAlphaBits = 8;
+ pixformat.cDepthBits = 24;
+ pixformat.cStencilBits = 8;
+
+ chosenformat = ChoosePixelFormat( dev_context, &pixformat );
+ if (chosenformat==0) {
+ cerr << "MS GDI - ChoosePixelFormat failed\n";
+ return false;
+ }
+
+ bool spfok = SetPixelFormat( dev_context, chosenformat, &pixformat );
+ if (!spfok) {
+ cerr << "MS GDI - SetPixelFormat failed\n";
+ return false;
+ }
+
+ HGLRC gl_render_context = wglCreateContext( dev_context );
+ if ( gl_render_context == NULL ) {
+ cerr << "MS WGL - wglCreateContext failed\n";
+ ReleaseDC( ctx.window, ctx.dev_context );
+ return false;
+ }
+
+ bool mcok = wglMakeCurrent( dev_context, gl_render_context );
+ if (!mcok) {
+ cerr << "MS WGL - wglMakeCurrent failed\n";
+ return false;
+ }
+
+ ctx.window = window;
+ ctx.dev_context = dev_context;
+ ctx.openGLContext = gl_render_context;
+
+ return true;
+}
+
+
+OffscreenContext *create_offscreen_context(int w, int h)
+{
+ OffscreenContext *ctx = new OffscreenContext;
+ offscreen_context_init( *ctx, w, h );
+
+ // Before an FBO can be setup, a WGL context must be created.
+ // This call alters ctx->window and ctx->openGLContext
+ // and ctx->dev_context if successfull
+ if (!create_wgl_dummy_context( *ctx )) {
+ return NULL;
+ }
+
+ return create_offscreen_context_common( ctx );
+}
+
+bool teardown_offscreen_context(OffscreenContext *ctx)
+{
+ if (ctx) {
+ fbo_unbind(ctx->fbo);
+ fbo_delete(ctx->fbo);
+
+ wglMakeCurrent( NULL, NULL );
+ wglDeleteContext( ctx->openGLContext );
+ ReleaseDC( ctx->window, ctx->dev_context );
+
+ return true;
+ }
+ return false;
+}
+
+bool save_framebuffer(OffscreenContext *ctx, std::ostream &output)
+{
+ if (!ctx) return false;
+ wglSwapLayerBuffers( ctx->dev_context, WGL_SWAP_MAIN_PLANE );
+ return save_framebuffer_common( ctx, output );
+}
+
contact: Jan Huwald // Impressum