aboutsummaryrefslogtreecommitdiffstats
path: root/pugl/pugl_win_gl.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-07-27 21:24:36 +0200
committerDavid Robillard <d@drobilla.net>2019-07-29 01:59:19 +0200
commit37fe29ab9c4a5ea22bc5996b020fa39c854965fa (patch)
tree5ac433830c4113d07c51b662ca6d4707d4be12e8 /pugl/pugl_win_gl.c
parent41dea932f866c10eb9c303298545d6b7151cfcd0 (diff)
downloadpugl-37fe29ab9c4a5ea22bc5996b020fa39c854965fa.tar.gz
pugl-37fe29ab9c4a5ea22bc5996b020fa39c854965fa.tar.bz2
pugl-37fe29ab9c4a5ea22bc5996b020fa39c854965fa.zip
Reorganize source to separate private implementation details
Taking a page from C++ convention, where "detail" is for things that should not be included in user code.
Diffstat (limited to 'pugl/pugl_win_gl.c')
-rw-r--r--pugl/pugl_win_gl.c306
1 files changed, 0 insertions, 306 deletions
diff --git a/pugl/pugl_win_gl.c b/pugl/pugl_win_gl.c
deleted file mode 100644
index 17528d5..0000000
--- a/pugl/pugl_win_gl.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- Copyright 2012-2019 David Robillard <http://drobilla.net>
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/**
- @file pugl_win_gl.c OpenGL graphics backend for Windows.
-*/
-
-#include "pugl/pugl_gl_backend.h"
-#include "pugl/pugl_internal_types.h"
-#include "pugl/pugl_win.h"
-
-#include <windows.h>
-
-#include <GL/gl.h>
-
-#include <stdbool.h>
-#include <stdlib.h>
-
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_ALPHA_BITS_ARB 0x201b
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_TYPE_RGBA_ARB 0x202b
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-
-typedef HGLRC (*WglCreateContextAttribs)(HDC, HGLRC, const int*);
-typedef BOOL (*WglSwapInterval)(int);
-typedef BOOL (*WglChoosePixelFormat)(
- HDC, const int*, const FLOAT*, UINT, int*, UINT*);
-
-typedef struct {
- WglChoosePixelFormat wglChoosePixelFormat;
- WglCreateContextAttribs wglCreateContextAttribs;
- WglSwapInterval wglSwapInterval;
-} PuglWinGlProcs;
-
-typedef struct {
- PuglWinGlProcs procs;
- HGLRC hglrc;
-} PuglWinGlSurface;
-
-// Struct to manage the fake window used during configuration
-typedef struct {
- HWND hwnd;
- HDC hdc;
-} PuglFakeWindow;
-
-static int
-puglWinError(PuglFakeWindow* fakeWin, const int status)
-{
- if (fakeWin->hwnd) {
- ReleaseDC(fakeWin->hwnd, fakeWin->hdc);
- DestroyWindow(fakeWin->hwnd);
- }
-
- return status;
-}
-
-static PuglWinGlProcs puglWinGlGetProcs(void)
-{
- const PuglWinGlProcs procs = {
- (WglChoosePixelFormat)(
- wglGetProcAddress("wglChoosePixelFormatARB")),
- (WglCreateContextAttribs)(
- wglGetProcAddress("wglCreateContextAttribsARB")),
- (WglSwapInterval)(
- wglGetProcAddress("wglSwapIntervalEXT"))
- };
-
- return procs;
-}
-
-static int
-puglWinGlConfigure(PuglView* view)
-{
- PuglInternals* impl = view->impl;
-
- const int pixelAttrs[] = {
- WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
- WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
- WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
- WGL_DOUBLE_BUFFER_ARB, view->hints.double_buffer,
- WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
- WGL_SAMPLE_BUFFERS_ARB, view->hints.samples ? 1 : 0,
- WGL_SAMPLES_ARB, view->hints.samples,
- WGL_RED_BITS_ARB, view->hints.red_bits,
- WGL_GREEN_BITS_ARB, view->hints.green_bits,
- WGL_BLUE_BITS_ARB, view->hints.blue_bits,
- WGL_ALPHA_BITS_ARB, view->hints.alpha_bits,
- WGL_DEPTH_BITS_ARB, view->hints.depth_bits,
- WGL_STENCIL_BITS_ARB, view->hints.stencil_bits,
- 0,
- };
-
- PuglWinGlSurface* const surface =
- (PuglWinGlSurface*)calloc(1, sizeof(PuglWinGlSurface));
- impl->surface = surface;
-
- // Create fake window for getting at GL context
- PuglStatus st = PUGL_SUCCESS;
- PuglFakeWindow fakeWin = { 0, 0 };
- if ((st = puglWinCreateWindow(view, "Pugl Configuration",
- &fakeWin.hwnd, &fakeWin.hdc))) {
- return puglWinError(&fakeWin, st);
- }
-
- // Set pixel format for fake window
- const PuglWinPFD fakePfd = puglWinGetPixelFormatDescriptor(&view->hints);
- const int fakePfId = ChoosePixelFormat(fakeWin.hdc, &fakePfd);
- if (!fakePfId) {
- return puglWinError(&fakeWin, PUGL_ERR_SET_FORMAT);
- } else if (!SetPixelFormat(fakeWin.hdc, fakePfId, &fakePfd)) {
- return puglWinError(&fakeWin, PUGL_ERR_SET_FORMAT);
- }
-
- // Create fake GL context to get at the functions we need
- HGLRC fakeRc = wglCreateContext(fakeWin.hdc);
- if (!fakeRc) {
- return puglWinError(&fakeWin, PUGL_ERR_CREATE_CONTEXT);
- }
-
- // Enter fake context and get extension functions
- wglMakeCurrent(fakeWin.hdc, fakeRc);
- surface->procs = puglWinGlGetProcs();
-
- if (surface->procs.wglChoosePixelFormat) {
- // Choose pixel format based on attributes
- UINT numFormats = 0;
- if (!surface->procs.wglChoosePixelFormat(
- fakeWin.hdc, pixelAttrs, NULL, 1u, &impl->pfId, &numFormats)) {
- return puglWinError(&fakeWin, PUGL_ERR_SET_FORMAT);
- }
-
- DescribePixelFormat(
- impl->hdc, impl->pfId, sizeof(impl->pfd), &impl->pfd);
- } else {
- // Modern extensions not available, use basic pixel format
- impl->pfd = fakePfd;
- impl->pfId = fakePfId;
- }
-
- // Dispose of fake window and context
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(fakeRc);
- ReleaseDC(fakeWin.hwnd, fakeWin.hdc);
- DestroyWindow(fakeWin.hwnd);
-
- return 0;
-}
-
-static int
-puglWinGlCreate(PuglView* view)
-{
- PuglInternals* const impl = view->impl;
- PuglWinGlSurface* const surface = (PuglWinGlSurface*)impl->surface;
- PuglStatus st = PUGL_SUCCESS;
-
- const int contextAttribs[] = {
- WGL_CONTEXT_MAJOR_VERSION_ARB, view->hints.context_version_major,
- WGL_CONTEXT_MINOR_VERSION_ARB, view->hints.context_version_minor,
- WGL_CONTEXT_PROFILE_MASK_ARB,
- (view->hints.use_compat_profile
- ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB
- : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB),
- 0
- };
-
- // Create real window with desired pixel format
- if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
- return st;
- } else if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) {
- ReleaseDC(impl->hwnd, impl->hdc);
- DestroyWindow(impl->hwnd);
- impl->hwnd = NULL;
- impl->hdc = NULL;
- return PUGL_ERR_SET_FORMAT;
- }
-
- // Create GL context
- if (surface->procs.wglCreateContextAttribs &&
- !(surface->hglrc = surface->procs.wglCreateContextAttribs(
- impl->hdc, 0, contextAttribs))) {
- return PUGL_ERR_CREATE_CONTEXT;
- } else if (!(surface->hglrc = wglCreateContext(impl->hdc))) {
- return PUGL_ERR_CREATE_CONTEXT;
- }
-
- // Enter context and set swap interval
- wglMakeCurrent(impl->hdc, surface->hglrc);
- if (surface->procs.wglSwapInterval) {
- surface->procs.wglSwapInterval(1);
- }
-
- return 0;
-}
-
-static int
-puglWinGlDestroy(PuglView* view)
-{
- PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
- if (surface) {
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(surface->hglrc);
- free(surface);
- view->impl->surface = NULL;
- }
-
- return 0;
-}
-
-static int
-puglWinGlEnter(PuglView* view, bool drawing)
-{
- PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
-
- wglMakeCurrent(view->impl->hdc, surface->hglrc);
-
- if (drawing) {
- PAINTSTRUCT ps;
- BeginPaint(view->impl->hwnd, &ps);
- }
-
- return 0;
-}
-
-static int
-puglWinGlLeave(PuglView* view, bool drawing)
-{
- if (drawing) {
- PAINTSTRUCT ps;
- EndPaint(view->impl->hwnd, &ps);
- SwapBuffers(view->impl->hdc);
- }
-
- wglMakeCurrent(NULL, NULL);
-
- return 0;
-}
-
-static int
-puglWinGlResize(PuglView* PUGL_UNUSED(view),
- int PUGL_UNUSED(width),
- int PUGL_UNUSED(height))
-{
- return 0;
-}
-
-static void*
-puglWinGlGetContext(PuglView* PUGL_UNUSED(view))
-{
- return NULL;
-}
-
-PuglGlFunc
-puglGetProcAddress(const char* name)
-{
- return (PuglGlFunc)wglGetProcAddress(name);
-}
-
-const PuglBackend*
-puglGlBackend()
-{
- static const PuglBackend backend = {
- puglWinGlConfigure,
- puglWinGlCreate,
- puglWinGlDestroy,
- puglWinGlEnter,
- puglWinGlLeave,
- puglWinGlResize,
- puglWinGlGetContext
- };
-
- return &backend;
-}