diff --git a/configure.ac b/configure.ac index c3782c673..d870cb0c0 100644 --- a/configure.ac +++ b/configure.ac @@ -228,8 +228,11 @@ AC_DEFUN([DEFINE_GL], [ if test "$system" = MacOSX; then GL_COMMON_OBJ="src/mac_gl_common.o src/gl_context.o" - else + else if test "$system" = Linux; then GL_COMMON_OBJ="src/glx_common.o src/gl_context.o" + else + GL_COMMON_OBJ="src/win32_gl_common.o src/gl_context.o" + fi fi AC_SUBST(GL_COMMON_OBJ) ]) @@ -1474,6 +1477,13 @@ then OPENGL_LIB="-framework OpenGL -framework Cocoa" fi +# Win32 +if test "$system" = Windows -a "$FOUND_GLEW" = yes +then + OPENGL=yes + OPENGL_LIB="-lopengl32 -lglew32 -lgdi32" +fi + # ------------------------------------------------------------------------------------------------- # SW Mix Stuff # ------------------------------------------------------------------------------------------------- diff --git a/src/gl_context.c b/src/gl_context.c index 8c0e20867..5fb0a1a0e 100644 --- a/src/gl_context.c +++ b/src/gl_context.c @@ -3,23 +3,26 @@ #ifdef HAVE_CONFIG_H #include "config.h" #include "config_unix.h" +#include "config_win32.h" #endif -#if defined HAVE_MACOSX || (defined HAVE_LINUX && defined HAVE_LIBGL) +#if defined HAVE_MACOSX || (defined HAVE_LINUX && defined HAVE_LIBGL) || defined WIN32 #ifdef HAVE_MACOSX #include "mac_gl_common.h" -#else +#elif defined HAVE_LINUX #include "x11_common.h" #include "glx_common.h" +#else // WIN32 +#include "win32_gl_common.h" #endif #include "gl_context.h" bool init_gl_context(struct gl_context *context, int which) { -#ifndef HAVE_MACOSX - x11_enter_thread(); context->context = NULL; +#ifdef HAVE_LINUX + x11_enter_thread(); if(which == GL_CONTEXT_ANY) { printf("Trying OpenGL 3.1 first.\n"); context->context = glx_init(MK_OPENGL_VERSION(3,1)); @@ -35,8 +38,7 @@ bool init_gl_context(struct gl_context *context, int which) { if(context->context) { glx_validate(context->context); } -#else - context->context = NULL; +#elif defined HAVE_MACOSX if(which == GL_CONTEXT_ANY) { if(get_mac_kernel_version_major() >= 11) { printf("[RTDXT] Mac 10.7 or latter detected. Trying OpenGL 3.2 Core profile first.\n"); @@ -53,6 +55,14 @@ bool init_gl_context(struct gl_context *context, int which) { context->context = mac_gl_init(MAC_GL_PROFILE_LEGACY); context->legacy = TRUE; } +#else // WIN32 + if(which == GL_CONTEXT_ANY) { + context->context = win32_context_init(OPENGL_VERSION_UNSPECIFIED); + } else if(which == GL_CONTEXT_LEGACY) { + context->context = win32_context_init(OPENGL_VERSION_LEGACY); + } + + context->legacy = TRUE; #endif if(context->context) { @@ -66,8 +76,10 @@ bool init_gl_context(struct gl_context *context, int which) { void destroy_gl_context(struct gl_context *context) { #ifdef HAVE_MACOSX mac_gl_free(context->context); -#else +#elif defined HAVE_LINUX glx_free(context->context); +#else + win32_context_free(context->context); #endif } @@ -79,8 +91,10 @@ void gl_context_make_current(struct gl_context *context) } #ifdef HAVE_LINUX glx_make_current(context_state); -#else +#elif defined HAVE_MACOSX mac_gl_make_current(context_state); +#else + win32_context_make_current(context_state); #endif } diff --git a/src/gl_context.h b/src/gl_context.h index e64169920..72f1689ea 100644 --- a/src/gl_context.h +++ b/src/gl_context.h @@ -7,7 +7,7 @@ #include "config_unix.h" #endif // HAVE_CONFIG_H -#ifdef HAVE_LINUX +#if defined HAVE_LINUX || defined WIN32 #include #else #include diff --git a/src/glx_common.c b/src/glx_common.c index 1937bf119..8580d8228 100644 --- a/src/glx_common.c +++ b/src/glx_common.c @@ -180,6 +180,8 @@ void *glx_init(glx_opengl_version_t version) { Display *display; struct state_glx *context; + + x11_enter_thread(); context = (struct state_glx *) malloc(sizeof(struct state_glx)); context->magic = GLX_MAGIC; diff --git a/src/vo_postprocess/scale.c b/src/vo_postprocess/scale.c index c158a7c4e..b4608eb28 100644 --- a/src/vo_postprocess/scale.c +++ b/src/vo_postprocess/scale.c @@ -54,12 +54,6 @@ #include #include -#ifdef HAVE_LINUX -#include -#else -#include -#endif /* HAVE_LINUX */ - #include "debug.h" #include "gl_context.h" #include "video_codec.h" @@ -67,16 +61,6 @@ #include "vo_postprocess.h" #include "vo_postprocess/scale.h" -#if defined HAVE_MACOSX && OS_VERSION_MAJOR < 11 -#define glGenFramebuffers glGenFramebuffersEXT -#define glBindFramebuffer glBindFramebufferEXT -#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT -#define glFramebufferTexture2D glFramebufferTexture2DEXT -#define glDeleteFramebuffers glDeleteFramebuffersEXT -#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT -#define glCheckFramebufferStatus glCheckFramebufferStatusEXT -#endif - struct state_scale { struct video_frame *in; struct gl_context context; diff --git a/src/win32_gl_common.c b/src/win32_gl_common.c new file mode 100644 index 000000000..5e3c316a4 --- /dev/null +++ b/src/win32_gl_common.c @@ -0,0 +1,298 @@ +/* + * FILE: win32_gl_common.c + * AUTHORS: Martin Benes + * Lukas Hejtmanek + * Petr Holub + * Milos Liska + * Jiri Matela + * Dalibor Matura <255899@mail.muni.cz> + * Ian Wesley-Smith + * + * Copyright (c) 2005-2010 CESNET z.s.p.o. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_unix.h" +#include "config_win32.h" +#endif + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "win32_gl_common.h" + +#define VERSION_GET_MAJOR(version) (version >> 8u) +#define VERSION_GET_MINOR(version) (version & 0xFF) +#define VERSION_IS_UNSPECIFIED(version) (!version) +#define VERSION_IS_LEGACY(version) (version == OPENGL_VERSION_LEGACY) + +#define WNDCLASSNAME "GLClass" + +struct state_win32_gl_context +{ + HWND win; + HDC hdc; + HGLRC hglrc; +}; + +static HWND CreateWnd (int width, int height); +static BOOL SetGLFormat(HDC hdc); +static void PrintError(DWORD err); +static void create_and_register_windows_class(void); + +static void PrintError(DWORD err) +{ + // Retrieve the system error message for the last-error code + + LPVOID lpMsgBuf; + DWORD dw = err; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message and exit the process + fprintf(stderr, "%ld: %s\n", err, (char *) lpMsgBuf); + + LocalFree(lpMsgBuf); +} + +static BOOL SetGLFormat(HDC hdc) +{ + // number of available formats + int indexPixelFormat = 0; + + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, + 0,0,0,0,0,0,0,0,0,0,0,0,0, // useles parameters + 16, + 0,0,0,0,0,0,0 + }; + + // Choose the closest pixel format available + indexPixelFormat = ChoosePixelFormat(hdc, &pfd); + + // Set the pixel format for the provided window DC + return SetPixelFormat(hdc, indexPixelFormat, &pfd);// number of available formats +} + +static void create_and_register_windows_class(void) +{ + WNDCLASSEX ex; + + ex.cbSize = sizeof(WNDCLASSEX); + ex.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC; + ex.lpfnWndProc = DefWindowProc; + ex.cbClsExtra = 0; + ex.cbWndExtra = 0; + ex.hInstance = NULL; + ex.hIcon = LoadIcon(NULL, IDI_APPLICATION); + ex.hCursor = LoadCursor(NULL, IDC_ARROW); + ex.hbrBackground = NULL; + ex.lpszMenuName = NULL; + ex.lpszClassName = WNDCLASSNAME; + ex.hIconSm = NULL; + + ATOM res = RegisterClassEx(&ex); + assert(res != 0); +} + +static HWND CreateWnd (int width, int height) +{ + HWND win; + // center position of the window + int posx = (GetSystemMetrics(SM_CXSCREEN) / 2) - (width / 2); + int posy = (GetSystemMetrics(SM_CYSCREEN) / 2) - (height / 2); + + // set up the window for a windowed application by default + long wndStyle = WS_OVERLAPPEDWINDOW; + + // create the window + win = CreateWindowEx(0, + WNDCLASSNAME, + "OpenGL Context Window", + wndStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, + posx, posy, + width, height, + NULL, + NULL, + NULL, + NULL); + + if(!win) { + PrintError(GetLastError()); + } + + // at this point WM_CREATE message is sent/received + // the WM_CREATE branch inside WinProc function will execute here + return win; +} + +void *win32_context_init(win32_opengl_version_t version) +{ + struct state_win32_gl_context *context; + + context = malloc(sizeof(struct state_win32_gl_context)); + if(!context) { + fprintf(stderr, "Unable to allocate memory.\n"); + return NULL; + } + + create_and_register_windows_class(); + + context->win = CreateWnd(512, 512); + assert(context->win != NULL); + + if ((context->hdc = GetDC(context->win)) == NULL) // get device context + { + fprintf(stderr, "Failed to Get the Window Device Context\n"); + free(context); + return NULL; + } + + if(!SetGLFormat(context->hdc)) { + fprintf(stderr, "Unable to set pixel format.\n"); + free(context); + return NULL; + } + + if ((context->hglrc = wglCreateContext(context->hdc)) == NULL) // create the rendering context + { + fprintf(stderr, "Failed to Create the OpenGL Rendering Context.\n"); + goto release_context; + } + + if(wglMakeCurrent(context->hdc, context->hglrc) == FALSE) { + fprintf(stderr, "Unable to make context current.\n"); + PrintError(GetLastError()); + goto release_context; + } + + int err = glewInit(); + if(err != GLEW_OK) { + fprintf(stderr, "Error intializing GLEW.\n"); + goto release_context; + } + + if(!VERSION_IS_UNSPECIFIED(version) && + !VERSION_IS_LEGACY(version)) { + if(!glewIsSupported("GL_ARB_create_context_profile") + != GLEW_OK) { + fprintf(stderr, "OpenGL implementation is not capable " + "of selecting profile.\n"); + goto release_context; + } else { + // first destroy current context + wglMakeCurrent(context->hdc, NULL); + wglDeleteContext(context->hglrc); + + const int attrib_list[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, VERSION_GET_MAJOR(version), + WGL_CONTEXT_MINOR_VERSION_ARB, VERSION_GET_MINOR(version), + 0 + }; + + if ((context->hglrc = wglCreateContextAttribsARB(context->hdc, NULL, attrib_list)) == NULL) + { + fprintf(stderr, "Failed to Create the OpenGL Rendering Context %d,%d.\n", + VERSION_GET_MAJOR(version), + VERSION_GET_MINOR(version)); + goto release_context; + } + } + } + + + //ShowWindow(context->win, SW_SHOW); + //UpdateWindow(context->win); + + return context; + +release_context: + wglMakeCurrent(context->hdc, NULL); + wglDeleteContext(context->hglrc); + free(context); + return NULL; +} + +void win32_context_make_current(void *arg) +{ + struct state_win32_gl_context *context = arg; + BOOL ret; + + if(!arg) { + ret = wglMakeCurrent(NULL, NULL); + } else { + ret = wglMakeCurrent(context->hdc, context->hglrc); + } + if(ret == FALSE) { + fprintf(stderr, "Warning: wglMakeCurrent did not succeeded!\n"); + PrintError(GetLastError()); + } +} + +void win32_context_free(void *arg) +{ + if(!arg) + return; + + struct state_win32_gl_context *context = arg; + + wglMakeCurrent(context->hdc, NULL); + wglDeleteContext(context->hglrc); + + PostQuitMessage(0); + + free(context); +} + diff --git a/src/win32_gl_common.h b/src/win32_gl_common.h new file mode 100644 index 000000000..8210dc9f2 --- /dev/null +++ b/src/win32_gl_common.h @@ -0,0 +1,56 @@ +/* + * FILE: win32_gl_common.h + * AUTHORS: Martin Benes + * Lukas Hejtmanek + * Petr Holub + * Milos Liska + * Jiri Matela + * Dalibor Matura <255899@mail.muni.cz> + * Ian Wesley-Smith + * + * Copyright (c) 2005-2010 CESNET z.s.p.o. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +typedef uint32_t win32_opengl_version_t; +#define OPENGL_VERSION_UNSPECIFIED 0u +#define OPENGL_VERSION_LEGACY 1u +#define MK_OPENGL_VERSION(major,minor) (major << 8u | minor) + +void *win32_context_init(win32_opengl_version_t version_t); +void win32_context_make_current(void *context); +void win32_context_free(void *); +