Module: Demos Branch: master Commit: 573f2f7ecd945d5fe166992df15266ef500bc4b2 URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=573f2f7ecd945d5fe166992df15266ef500bc4b2
Author: Keith Kriewall <keith.kriew...@attachmate.com> Date: Thu Mar 7 14:14:19 2013 +0000 wgl/wincopy: Windows port of xdemos/wincopy. Signed-off-by: José Fonseca <jfons...@vmware.com> --- src/wgl/CMakeLists.txt | 10 ++- src/wgl/wglutil.c | 235 +++++++++++++++++++++++++++++++++++++++++++++ src/wgl/wglutil.h | 123 ++++++++++++++++++++++++ src/wgl/wincopy.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 615 insertions(+), 1 deletions(-) diff --git a/src/wgl/CMakeLists.txt b/src/wgl/CMakeLists.txt index 02f31f0..a32a664 100644 --- a/src/wgl/CMakeLists.txt +++ b/src/wgl/CMakeLists.txt @@ -14,7 +14,15 @@ set_target_properties (wgl_sharedtex_mt PROPERTIES OUTPUT_NAME sharedtex_mt) add_executable (wglinfo wglinfo.c) add_executable (wglcontext wglcontext.c) +add_executable (wincopy WIN32 wincopy.c wglutil.c) -install (TARGETS wglthreads wgl_sharedtex_mt wglinfo DESTINATION wgl) +install ( + TARGETS + wglthreads + wgl_sharedtex_mt + wglinfo + wglcontext + wincopy + DESTINATION wgl) add_subdirectory (rtotex) diff --git a/src/wgl/wglutil.c b/src/wgl/wglutil.c new file mode 100644 index 0000000..1cd943b --- /dev/null +++ b/src/wgl/wglutil.c @@ -0,0 +1,235 @@ +/* + * Author: kenc + * + * Created: March 1, 2013 + * Copyright (c) 2013, Attachmate Corporation All Rights Reserved + */ +#include <windows.h> +#include <assert.h> +#include <GL/gl.h> +#include "wglutil.h" + +#define STYLE WS_OVERLAPPEDWINDOW +#define EXSTYLE WS_EX_OVERLAPPEDWINDOW +#define GL_CLASS "GL" + +static PFNWGLMAKECONTEXTCURRENTARBPROC WGLMakeContextCurrent = NULL; +static PFNWGLCHOOSEPIXELFORMATARBPROC WGLChoosePixelFormat = NULL; + +LRESULT +storeDC(HWND hWnd) +{ + HDC hDC; + + if ((hDC = GetDC(hWnd)) != NULL) { + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)hDC); + + assert(GetWindowLongPtr(hWnd, GWLP_USERDATA) == (LONG_PTR)hDC); + return 0; + } + return -1; +} + +HDC +fetchDC(HWND hWnd) +{ + assert(hWnd != NULL); + if (hWnd != NULL) { + HDC hDC = (HDC)(INT_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + assert(hDC != NULL); + return hDC; + } + return NULL; +} + +HWND +getWindow(HINSTANCE hInst, int x, int y, int w, int h, int format) +{ + HWND hParent; + + if ((hParent = GetDesktopWindow()) != NULL) { + HWND hWnd = CreateWindowEx(EXSTYLE, GL_CLASS, "wincopy", STYLE, x, y, w, h, hParent, NULL, hInst, NULL); + HDC hDC; + BOOL ret; + + assert(hWnd != NULL); + if ((hDC = (HDC)(INT_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA)) != NULL) { + PIXELFORMATDESCRIPTOR pfd; + + if ((ret = SetPixelFormat(hDC, format, &pfd)) != FALSE) + return hWnd; + ret = DestroyWindow(hWnd); + assert(ret != FALSE); + } + } + assert(hParent != NULL); + return NULL; +} + +static int +getFormat(HDC hDC, PIXELFORMATDESCRIPTOR *pfd) +{ + int format; + + int size = sizeof(PIXELFORMATDESCRIPTOR); + memset(pfd, 0, size); + pfd->nSize = size; + pfd->nVersion = 1; + pfd->dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL; + pfd->iLayerType = PFD_MAIN_PLANE; + pfd->iPixelType = PFD_TYPE_RGBA; + format = ChoosePixelFormat(hDC, pfd); + assert(format > 0); + return format; +} + +static HGLRC +createCurrentContext(HDC hDC) +{ + HGLRC hGLRC = NULL; + + if ((hGLRC = wglCreateContext(hDC)) != NULL) { + BOOL current; + + if ((current = wglMakeCurrent(hDC, hGLRC)) == FALSE) { + BOOL ret = wglDeleteContext(hGLRC); + + assert(ret != FALSE); + hGLRC = NULL; + } + } + else + assert(hGLRC != NULL); + return hGLRC; +} + +static BOOL +checkWGLExtensions(HINSTANCE hInst) +{ + HWND hWnd; + BOOL rval, ret = FALSE; + + if ((hWnd = CreateWindowEx(EXSTYLE, GL_CLASS, "tmp", STYLE, 0, 0, 1, 1, + GetDesktopWindow(), NULL, hInst, NULL)) != NULL) { + HDC hDC; + + if ((hDC = fetchDC(hWnd)) != NULL) { + PIXELFORMATDESCRIPTOR pfd; + int format; + + if ((format = getFormat(hDC, &pfd)) > 0) { + BOOL setFormat; + + if ((setFormat = SetPixelFormat(hDC, format, &pfd)) != FALSE) { + HGLRC hGLRC = createCurrentContext(hDC); + + if (hGLRC != NULL) { + PFNWGLGETEXTENSIONSSTRINGPROC WGLGetExtensionsStringFunc; + + WGLGetExtensionsStringFunc = (PFNWGLGETEXTENSIONSSTRINGPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + assert(WGLGetExtensionsStringFunc != NULL); + if (WGLGetExtensionsStringFunc != NULL) { + const char *wglExtensionString = (*WGLGetExtensionsStringFunc)(hDC); + + if (wglExtensionString != NULL) { + WGLMakeContextCurrent = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetProcAddress("wglMakeContextCurrentARB"); + assert(WGLMakeContextCurrent != NULL); + WGLChoosePixelFormat = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + assert(WGLChoosePixelFormat != NULL); + if (WGLMakeContextCurrent != NULL && WGLChoosePixelFormat != NULL) + ret = TRUE; + } + } + rval = wglDeleteContext(hGLRC); + assert(rval != FALSE); + } + } + } + } + rval = DestroyWindow(hWnd); + assert(rval != FALSE); + } + return ret; +} + + +BOOL +wglExtInit(HINSTANCE hInst, WNDPROC proc) +{ + WNDCLASS glClass; + ATOM atom; + + memset(&glClass, 0, sizeof(WNDCLASS)); + glClass.style = CS_PARENTDC; + glClass.lpfnWndProc = proc; + glClass.hInstance = hInst; + glClass.lpszClassName = GL_CLASS; + glClass.cbWndExtra = sizeof(HANDLE); + if ((atom = RegisterClass(&glClass)) == 0) { + assert(atom != 0); + return FALSE; + } + return checkWGLExtensions(hInst); +} + +void +wglExtDispose(HINSTANCE hInst) +{ + BOOL ret; + + ret = UnregisterClass(GL_CLASS, hInst); + assert(ret != FALSE); +} + +BOOL +wglExtMakeContextCurrent(HWND did, HWND rid, HGLRC gid) +{ + HDC hDrawDC; + BOOL ret = FALSE; + + if ((hDrawDC = (HDC)(INT_PTR)GetWindowLongPtr(did, GWLP_USERDATA)) != NULL) { + if (did != rid) { + HDC hReadDC; + + if ((hReadDC = (HDC)(INT_PTR)GetWindowLongPtr(rid, GWLP_USERDATA)) != NULL) { + ret = (*WGLMakeContextCurrent)(hDrawDC, hReadDC, gid); + assert(ret != FALSE); + } + } + else + ret = wglMakeCurrent(hDrawDC, gid); + } + assert(ret != FALSE); + return ret; +} + +BOOL +wglExtSwapBuffers(HWND hWnd) +{ + HDC hDC; + + if ((hDC = (HDC)(INT_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA)) != NULL); + return wglSwapLayerBuffers(hDC, WGL_SWAP_MAIN_PLANE); + return FALSE; +} + +int +wglExtChoosePixelFormat(const int *attrs) +{ + HDC hDC; + HWND hWnd = GetDesktopWindow(); + + if ((hDC = (HDC)GetDC(hWnd)) != NULL) { + int format = 0; + UINT nFormats; + BOOL ret; + + WGLChoosePixelFormat(hDC, attrs, NULL, 1, &format, &nFormats); + assert(nFormats > 0 && format != 0); + ret = ReleaseDC(hWnd, hDC); + assert(ret != FALSE); + return format; + } + return 0; +} diff --git a/src/wgl/wglutil.h b/src/wgl/wglutil.h new file mode 100644 index 0000000..4df1209 --- /dev/null +++ b/src/wgl/wglutil.h @@ -0,0 +1,123 @@ +/* + * Author: kenc + * + * Created: March 1, 2013 + * Copyright (c) 2013, Attachmate Corporation All Rights Reserved + */ +#ifndef wglExt_h +#define wglExt_h + +/* + * Derrived from... at http://developer.download.nvidia.com/opengl/includes/wglext.h + */ + +#define WGL_WGLEXT_PROTOTYPES 1 + +/* WGL_extensions_string extension */ +typedef const char * (WINAPI *PFNWGLGETEXTENSIONSSTRINGPROC)(HDC); + +/* WGL_pixel_format extension */ +typedef BOOL (WINAPI *PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC, const int *, const FLOAT *, UINT, int *, UINT *); + +/* + * Accepted in the <piAttributes> parameter array of + * wglGetPixelFormatAttribivARB, and wglGetPixelFormatAttribfvARB, and + * as a type in the <piAttribIList> and <pfAttribFList> parameter + * arrays of wglChoosePixelFormatARB: + */ + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#define WGL_NUMBER_PIXEL_FORMATS 0x2000 +#define WGL_DRAW_TO_WINDOW 0x2001 +#define WGL_DRAW_TO_BITMAP 0x2002 +#define WGL_ACCELERATION 0x2003 +#define WGL_NEED_PALETTE 0x2004 +#define WGL_NEED_SYSTEM_PALETTE 0x2005 +#define WGL_SWAP_LAYER_BUFFERS 0x2006 +#define WGL_SWAP_METHOD 0x2007 +#define WGL_NUMBER_OVERLAYS 0x2008 +#define WGL_NUMBER_UNDERLAYS 0x2009 +#define WGL_TRANSPARENT 0x200A +#define WGL_TRANSPARENT_RED_VALUE 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE 0x203B +#define WGL_SHARE_DEPTH 0x200C +#define WGL_SHARE_STENCIL 0x200D +#define WGL_SHARE_ACCUM 0x200E +#define WGL_SUPPORT_GDI 0x200F +#define WGL_SUPPORT_OPENGL 0x2010 +#define WGL_DOUBLE_BUFFER 0x2011 +#define WGL_STEREO 0x2012 +#define WGL_PIXEL_TYPE 0x2013 +#define WGL_COLOR_BITS 0x2014 +#define WGL_RED_BITS 0x2015 +#define WGL_RED_SHIFT 0x2016 +#define WGL_GREEN_BITS 0x2017 +#define WGL_GREEN_SHIFT 0x2018 +#define WGL_BLUE_BITS 0x2019 +#define WGL_BLUE_SHIFT 0x201A +#define WGL_ALPHA_BITS 0x201B +#define WGL_ALPHA_SHIFT 0x201C +#define WGL_ACCUM_BITS 0x201D +#define WGL_ACCUM_RED_BITS 0x201E +#define WGL_ACCUM_GREEN_BITS 0x201F +#define WGL_ACCUM_BLUE_BITS 0x2020 +#define WGL_ACCUM_ALPHA_BITS 0x2021 +#define WGL_DEPTH_BITS 0x2022 +#define WGL_STENCIL_BITS 0x2023 +#define WGL_AUX_BUFFERS 0x2024 +#define WGL_SAMPLE_BUFFERS 0x2041 +#define WGL_SAMPLES 0x2042 +#define PFD_DRAW_TO_PBUFFER 0x4000 + +/* + * Accepted as a value in the <piAttribIList> and <pfAttribFList> + * parameter arrays of wglChoosePixelFormatARB, and returned in the + * <piValues> parameter array of wglGetPixelFormatAttribivARB, and the + * <pfValues> parameter array of wglGetPixelFormatAttribfvARB: + */ +#define WGL_NO_ACCELERATION 0x2025 +#define WGL_GENERIC_ACCELERATION 0x2026 +#define WGL_FULL_ACCELERATION 0x2027 + +#define WGL_SWAP_EXCHANGE 0x2028 +#define WGL_SWAP_COPY 0x2029 +#define WGL_SWAP_UNDEFINED 0x202A + +#define WGL_TYPE_RGBA 0x202B +#define WGL_TYPE_COLORINDEX 0x202C +#define PFD_TYPE_FLOAT_RGBA 2 + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB(HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB(void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI *PFNWGLMAKECONTEXTCURRENTARBPROC)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void); +#endif + +/* + * Inits some function pointers and return number of formats. + * Returns 0 on failure. + */ +extern HWND getWindow(HINSTANCE hInst, int x, int y, int w, int h, int format); +extern BOOL wglExtMakeContextCurrent(HWND did, HWND rid, HGLRC gid); +extern BOOL wglExtSwapBuffers(HWND); +extern int wglExtChoosePixelFormat(const int *); +extern BOOL wglExtInit(HINSTANCE, WNDPROC); +extern void wglExtDispose(HINSTANCE); +LRESULT storeDC(HWND hWnd); +HDC fetchDC(HWND hWnd); +#endif diff --git a/src/wgl/wincopy.c b/src/wgl/wincopy.c new file mode 100644 index 0000000..e802aee --- /dev/null +++ b/src/wgl/wincopy.c @@ -0,0 +1,248 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * This program opens two windows, renders into one and uses + * glCopyPixels to copy the image from the first window into the + * second by means of the extension function wglMakeContextCurrentARB(). + */ +/* + * Author: kenc + * + * Created: March 1, 2013 + * Copyright (c) 2013, Attachmate Corporation All Rights Reserved + */ +#include <windows.h> +#include <GL/gl.h> +#include <assert.h> +#include "wglutil.h" + +static HGLRC Context = NULL; +static HWND Win[2] = {NULL, NULL}; +static int Width[2] = {0, 0}, Height[2] = {0, 0}; +static float Angle = 0.0f; + + +static BOOL +Redraw(BOOL DrawFront) +{ + assert(Context != NULL); + if (!wglExtMakeContextCurrent(Win[0], Win[0], Context)) + return FALSE; + + Angle += 1.0f; + if (DrawFront) { + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } + else { + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + } + + glViewport(0, 0, Width[0], Height[0]); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glShadeModel(GL_FLAT); + glClearColor(0.5, 0.5, 0.5, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* draw blue quad */ + glColor3f(0.3f, 0.3f, 1.0f); + glPushMatrix(); + glRotatef(Angle, 0, 0, 1); + glBegin(GL_POLYGON); + glVertex2f(-0.5, -0.25); + glVertex2f(0.5, -0.25); + glVertex2f(0.5, 0.25); + glVertex2f(-0.5, 0.25); + glEnd(); + glPopMatrix(); + + if (DrawFront) + glFinish(); + else + wglExtSwapBuffers(Win[0]); + + /* copy image from window 0 to window 1 */ + if (!wglExtMakeContextCurrent(Win[1], Win[0], Context)) + return FALSE; + + /* copy the image between windows */ + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR); + if (DrawFront) + glFinish(); + else + wglExtSwapBuffers(Win[1]); + return TRUE; +} + + +static void +Resize(HWND win, int width, int height) +{ + int i; + HDC hDC; + + if (win == Win[0]) + i = 0; + else + i = 1; + + if ((hDC = (HDC)(INT_PTR)GetWindowLongPtr(win, GWLP_USERDATA)) != NULL) { + BOOL ret; + + if ((ret = wglMakeCurrent(hDC, Context)) != FALSE) { + Width[i] = width; + Height[i] = height; + } + assert(ret != FALSE); + } +} + +static LRESULT CALLBACK +EventLoop(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HDC hDC; + RECT rect; + LRESULT ret; + LPWINDOWPOS pWinPos; + static BOOL drawFront = FALSE; + + switch (msg) { + case WM_CREATE: + ret = (LRESULT)storeDC(hWnd); + assert(ret == 0); + break; + + case WM_PAINT: + GetUpdateRect(hWnd, &rect, FALSE); + Redraw(drawFront); + ret = 0; + break; + + case WM_WINDOWPOSCHANGED: + pWinPos = (LPWINDOWPOS)lParam; + //if (!(pWinPos->flags&SWP_NOSIZE)) + Resize(hWnd, pWinPos->cx, pWinPos->cy); + ret = 0; + break; + + case WM_CHAR: + if (wParam == 'f') { // 'f' key + drawFront = !drawFront; + Redraw(drawFront); + } + else if (wParam == VK_ESCAPE) + PostQuitMessage(0); + ret = 0; + break; + + case WM_DESTROY: + if ((hDC = fetchDC(hWnd)) != NULL) { + ret = ReleaseDC(hWnd, hDC); + assert(ret != FALSE); + } + ret = 1; + break; + + default: + ret = DefWindowProc(hWnd, msg, wParam, lParam); + break; + } + return ret; +} + + +static BOOL +Init(HINSTANCE hInst, int show) +{ + BOOL rval = FALSE; + + if (wglExtInit(hInst, EventLoop) != FALSE) { + const int attribList[] = { + WGL_DRAW_TO_WINDOW, GL_TRUE, + WGL_SUPPORT_OPENGL, GL_TRUE, + WGL_DOUBLE_BUFFER, GL_TRUE, + WGL_PIXEL_TYPE, WGL_TYPE_RGBA, + WGL_COLOR_BITS, 32, + WGL_DEPTH_BITS, 24, + 0}; + int format; + + if ((format = wglExtChoosePixelFormat(attribList)) != 0) { + if ((Win[0] = getWindow(hInst, 0, 0, 300, 300, format)) != NULL) { + if ((Win[1] = getWindow(hInst, 350, 0, 300, 300, format)) != NULL) { + ShowWindow(Win[0], show); + ShowWindow(Win[1], show); + rval = TRUE; + } + } + } + } + return rval; +} + + +int CALLBACK +WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) +{ + int ret = -1; + + if (Init(hInst, nCmdShow) != FALSE) { + MSG msg; + HDC hDC; + + if ((hDC = fetchDC(Win[0])) != NULL) { + if ((Context = wglCreateContext(hDC)) != NULL) { + BOOL rval; + + while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (Win[0] != NULL) { + rval = DestroyWindow(Win[0]); + assert(rval != FALSE); + } + if (Win[1] != NULL) { + rval = DestroyWindow(Win[1]); + assert(rval != FALSE); + } + rval = wglDeleteContext(Context); + assert(rval != FALSE); + } + } + wglExtDispose(hInst); + ret = (int)msg.wParam; + } + if (Context != NULL) + wglDeleteContext(Context); + return ret; +} _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-commit