From fbefc4904d290205658209bbe2392b4b7f9e2711 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 4 Oct 2008 18:42:13 +0000 Subject: [PATCH] Add SimpleWindow and SimpleGLWindow Make OpenGL context support an optional feature Use pimpl to hide platform-specific parts of GLContext --- Build | 7 +++- source/gbase/glcontext.cpp | 66 ++++++++++++++++++++++++++++------- source/gbase/glcontext.h | 19 +++------- source/gbase/simplewindow.cpp | 29 +++++++++++++++ source/gbase/simplewindow.h | 57 ++++++++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 28 deletions(-) create mode 100644 source/gbase/simplewindow.cpp create mode 100644 source/gbase/simplewindow.h diff --git a/Build b/Build index e388399..eb067af 100644 --- a/Build +++ b/Build @@ -10,7 +10,6 @@ package "mspgbase" require "mspcore"; require "mspstrings"; require "sigc++-2.0"; - require "opengl"; if "arch!=win32" { require "xlib"; @@ -33,6 +32,12 @@ package "mspgbase" require "devil"; }; + feature "opengl" "Include support for OpenGL contexts"; + if "with_opengl" + { + require "opengl"; + }; + headers "gbase" { source "source/gbase"; diff --git a/source/gbase/glcontext.cpp b/source/gbase/glcontext.cpp index c002a39..4783e0c 100644 --- a/source/gbase/glcontext.cpp +++ b/source/gbase/glcontext.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -9,11 +9,17 @@ Distributed under the LGPL #ifdef WIN32 #include #endif +#ifdef WITH_OPENGL #include +#ifndef WIN32 +#include +#endif +#endif #include #include #include "display.h" #include "glcontext.h" +#include "types.h" #include "window.h" namespace Msp { @@ -27,10 +33,31 @@ GLOptions::GLOptions(): { } +#ifdef WITH_OPENGL +#ifdef WIN32 +typedef HGLRC Context; +#else +typedef GLXContext Context; +#endif + +struct GLContext::Private +{ + Context context; +#ifndef WIN32 + // In X11, we need to create a window with the chosen visual + WindowHandle subwnd; +#endif +}; +#endif + + GLContext::GLContext(Window &wnd, const GLOptions &opts): display(wnd.get_display()), window(wnd) { +#ifdef WITH_OPENGL + priv=new Private; + #ifdef WIN32 HDC dc=GetDC(window.get_handle()); @@ -54,8 +81,8 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): throw Exception("Couldn't find a suitable pixel format"); SetPixelFormat(dc, pf_index, &pfd); - context=wglCreateContext(dc); - wglMakeCurrent(dc, context); + priv->context=wglCreateContext(dc); + wglMakeCurrent(dc, priv->context); ReleaseDC(window.get_handle(), dc); #else @@ -93,17 +120,22 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front()); if(!vi) throw Exception("Couldn't find a suitable GLX visual"); - context=glXCreateContext(dpy, vi, 0, true); + priv->context=glXCreateContext(dpy, vi, 0, true); XSetWindowAttributes attr; attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone); - subwnd=XCreateWindow(dpy, window.get_handle(), 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr); - XMapWindow(display.get_display(), subwnd); + priv->subwnd=XCreateWindow(dpy, window.get_handle(), 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr); + XMapWindow(display.get_display(), priv->subwnd); XFree(vi); - glXMakeCurrent(dpy, subwnd, context); + glXMakeCurrent(dpy, priv->subwnd, priv->context); +#endif +#else + (void)wnd; + (void)opts; + throw Exception("OpenGL support not compiled in"); #endif window.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized)); @@ -111,35 +143,45 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): GLContext::~GLContext() { +#ifdef WITH_OPENGL #ifdef WIN32 wglMakeCurrent(0, 0); - wglDeleteContext(context); + wglDeleteContext(priv->context); #else ::Display *dpy=display.get_display(); glXMakeCurrent(dpy, 0, 0); - glXDestroyContext(dpy, context); - XDestroyWindow(dpy, subwnd); + glXDestroyContext(dpy, priv->context); + XDestroyWindow(dpy, priv->subwnd); +#endif + delete priv; #endif } void GLContext::swap_buffers() { +#ifdef WITH_OPENGL #ifdef WIN32 HDC dc=GetDC(window.get_handle()); SwapBuffers(dc); ReleaseDC(window.get_handle(), dc); #else - glXSwapBuffers(display.get_display(), subwnd); + glXSwapBuffers(display.get_display(), priv->subwnd); +#endif #endif } void GLContext::window_resized(unsigned w, unsigned h) { +#ifdef WITH_OPENGL #ifndef WIN32 - XMoveResizeWindow(display.get_display(), subwnd, 0, 0, w, h); + XMoveResizeWindow(display.get_display(), priv->subwnd, 0, 0, w, h); #endif glViewport(0, 0, w, h); +#else + (void)w; + (void)h; +#endif } } // namespace Graphics diff --git a/source/gbase/glcontext.h b/source/gbase/glcontext.h index 297bc34..f013df2 100644 --- a/source/gbase/glcontext.h +++ b/source/gbase/glcontext.h @@ -1,22 +1,18 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #ifndef MSP_GBASE_GLCONTEXT_H_ #define MSP_GBASE_GLCONTEXT_H_ -#ifndef WIN32 -#include -#endif -#include "types.h" - namespace Msp { namespace Graphics { class Display; +class Window; struct GLOptions { @@ -31,18 +27,11 @@ struct GLOptions class GLContext { private: -#ifdef WIN32 - typedef HGLRC Context; -#else - typedef GLXContext Context; -#endif + struct Private; Display &display; Window &window; - Context context; -#ifndef WIN32 - WindowHandle subwnd; -#endif + Private *priv; public: GLContext(Window &wnd, const GLOptions &opts=GLOptions()); diff --git a/source/gbase/simplewindow.cpp b/source/gbase/simplewindow.cpp new file mode 100644 index 0000000..4893a53 --- /dev/null +++ b/source/gbase/simplewindow.cpp @@ -0,0 +1,29 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "simplewindow.h" + +namespace Msp { +namespace Graphics { + +SimpleWindow::SimpleWindow(unsigned w, unsigned h): + Window(display, w, h) +{ } + + +SimpleGLWindow::SimpleGLWindow(unsigned w, unsigned h): + SimpleWindow(w, h), + gl_ctx(*this) +{ } + +void SimpleGLWindow::swap_buffers() +{ + gl_ctx.swap_buffers(); +} + +} // namespace Graphics +} // namespace Msp diff --git a/source/gbase/simplewindow.h b/source/gbase/simplewindow.h new file mode 100644 index 0000000..a506636 --- /dev/null +++ b/source/gbase/simplewindow.h @@ -0,0 +1,57 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_SIMPLEWINDOW_H_ +#define MSP_GBASE_SIMPLEWINDOW_H_ + +#include "display.h" +#include "glcontext.h" +#include "window.h" + +namespace Msp { +namespace Graphics { + +/** +Helper class for SimpleWindow. +*/ +class SimpleWindowBase +{ +protected: + Display dpy; + + SimpleWindowBase() { } +}; + + +/** +A simplified Window that encapsulates a Display. +*/ +class SimpleWindow: public SimpleWindowBase, public Window +{ +public: + SimpleWindow(unsigned, unsigned); +}; + + +/** +A SimpleWindow bundled with a GLContext. +*/ +class SimpleGLWindow: public SimpleWindow +{ +private: + GLContext gl_ctx; + +public: + SimpleGLWindow(unsigned, unsigned); + GLContext &get_gl_context() { return gl_ctx; } + void swap_buffers(); +}; + +} // namespace Graphics +} // namespace Msp + +#endif -- 2.43.0