From 619c41692d805eb6c52de4d6835edf70cf4dc4b2 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Wed, 16 Dec 2015 16:28:20 -0500 Subject: [PATCH 01/14] Merged in @andsve changes with the latest in the master branch. Transparent windows now work! --- examples/CMakeLists.txt | 1 + examples/transparent.c | 170 ++++++++++++++++++++++++++++++++++++++++ include/GLFW/glfw3.h | 1 + src/cocoa_window.m | 12 ++- src/context.c | 6 ++ src/internal.h | 3 + src/nsgl_context.m | 6 ++ src/wgl_context.c | 3 + src/window.c | 7 ++ 9 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 examples/transparent.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3b6e54ce3..f4123aa0c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD}) add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD}) add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD}) add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD}) +add_executable(transparent WIN32 MACOSX_BUNDLE transparent.c ${ICON} ${GLAD}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD}) target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") diff --git a/examples/transparent.c b/examples/transparent.c new file mode 100644 index 000000000..195e95623 --- /dev/null +++ b/examples/transparent.c @@ -0,0 +1,170 @@ +//======================================================================== +// Simple GLFW example +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +//! [code] + +#include +#include + +#include "linmath.h" + +#include +#include + +static const struct +{ + float x, y; + float r, g, b; +} vertices[3] = +{ + { -0.6f, -0.4f, 1.f, 0.f, 0.f }, + { 0.6f, -0.4f, 0.f, 1.f, 0.f }, + { 0.f, 0.6f, 0.f, 0.f, 1.f } +}; + +static const char* vertex_shader_text = +"uniform mat4 MVP;\n" +"attribute vec3 vCol;\n" +"attribute vec2 vPos;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" +" color = vCol;\n" +"}\n"; + +static const char* fragment_shader_text = +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_FragColor = vec4(color, 1.0);\n" +"}\n"; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +int main(void) +{ + GLFWwindow* window; + GLuint vertex_buffer, vertex_shader, fragment_shader, program; + GLint mvp_location, vpos_location, vcol_location; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + window = glfwCreateWindow(256, 256, "Transparent window example", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(window, 300, 300); + + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + // NOTE: OpenGL error checks have been omitted for brevity + + glGenBuffers(1, &vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); + glCompileShader(vertex_shader); + + fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + mvp_location = glGetUniformLocation(program, "MVP"); + vpos_location = glGetAttribLocation(program, "vPos"); + vcol_location = glGetAttribLocation(program, "vCol"); + + glEnableVertexAttribArray(vpos_location); + glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) 0); + glEnableVertexAttribArray(vcol_location); + glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) (sizeof(float) * 2)); + + while (!glfwWindowShouldClose(window)) + { + float ratio; + int width, height; + mat4x4 m, p, mvp; + + glfwGetFramebufferSize(window, &width, &height); + ratio = width / (float) height; + + glViewport(0, 0, width, height); + glClearColor(0,0,0,0.5); + glClear(GL_COLOR_BUFFER_BIT); + + mat4x4_identity(m); + mat4x4_rotate_Z(m, m, (float) glfwGetTime()); + mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_mul(mvp, p, m); + + glUseProgram(program); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + +//! [code] diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 126234215..d42be4f97 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -649,6 +649,7 @@ extern "C" { #define GLFW_SRGB_CAPABLE 0x0002100E #define GLFW_REFRESH_RATE 0x0002100F #define GLFW_DOUBLEBUFFER 0x00021010 +#define GLFW_ALPHA_MASK 0x00021011 #define GLFW_CLIENT_API 0x00022001 #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 29a8334c8..96fcb002e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -322,7 +322,11 @@ static int translateKey(unsigned int key) - (BOOL)isOpaque { - return YES; + // Set to NO even if alphaMask is not used; + // The NSView/GLFWContentView does not need to be opaque anyway, + // and to avoid keeping track of alphaMask inside the NSView we + // just return NO here instead. + return NO; } - (BOOL)canBecomeKeyView @@ -859,6 +863,12 @@ static GLFWbool createWindow(_GLFWwindow* window, [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; #endif /*_GLFW_USE_RETINA*/ + if (wndconfig->alphaMask) + { + [window->ns.object setOpaque:NO]; + [window->ns.object setBackgroundColor:[NSColor clearColor]]; + } + [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; [window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setAcceptsMouseMovedEvents:YES]; diff --git a/src/context.c b/src/context.c index 3da198649..cdec72062 100644 --- a/src/context.c +++ b/src/context.c @@ -216,6 +216,12 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, continue; } + if (desired->alphaMask > 0 && current->alphaMask == 0) + { + // Alpha mask is a hard constraint + continue; + } + // Count number of missing buffers { missing = 0; diff --git a/src/internal.h b/src/internal.h index 206b7e50f..92983f1de 100644 --- a/src/internal.h +++ b/src/internal.h @@ -185,6 +185,7 @@ struct _GLFWwndconfig GLFWbool focused; GLFWbool autoIconify; GLFWbool floating; + GLFWbool alphaMask; _GLFWmonitor* monitor; }; @@ -235,6 +236,7 @@ struct _GLFWfbconfig int samples; GLFWbool sRGB; GLFWbool doublebuffer; + int alphaMask; // This is defined in the context API's context.h _GLFW_PLATFORM_FBCONFIG; @@ -272,6 +274,7 @@ struct _GLFWwindow GLFWbool decorated; GLFWbool autoIconify; GLFWbool floating; + GLFWbool transparent; GLFWbool closed; void* userPointer; GLFWvidmode videoMode; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 714d5272e..5a16766e6 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -215,6 +215,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } + if (fbconfig->alphaMask) + { + GLint opaque = 0; + [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; + } + [window->context.nsgl.object setView:window->ns.view]; return GLFW_TRUE; } diff --git a/src/wgl_context.c b/src/wgl_context.c index 55138e70e..c07d58edb 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -236,6 +236,9 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, u->doublebuffer = GLFW_TRUE; } + // always able to create alpha mask on win + u->alphaMask = desired->alphaMask; + u->wgl = n; usableCount++; } diff --git a/src/window.c b/src/window.c index e9e01e50e..aa33231c9 100644 --- a/src/window.c +++ b/src/window.c @@ -135,12 +135,14 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, fbconfig = _glfw.hints.framebuffer; ctxconfig = _glfw.hints.context; wndconfig = _glfw.hints.window; + fbconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; wndconfig.width = width; wndconfig.height = height; wndconfig.title = title; wndconfig.monitor = (_GLFWmonitor*) monitor; ctxconfig.share = (_GLFWwindow*) share; + wndconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; if (ctxconfig.share) { @@ -177,6 +179,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->decorated = wndconfig.decorated; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; + window->transparent = wndconfig.alphaMask; window->cursorMode = GLFW_CURSOR_NORMAL; // Save the currently current context so it can be restored later @@ -265,6 +268,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; + _glfw.hints.framebuffer.alphaMask = GLFW_FALSE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -315,6 +319,9 @@ GLFWAPI void glfwWindowHint(int target, int hint) case GLFW_DOUBLEBUFFER: _glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; break; + case GLFW_ALPHA_MASK: + _glfw.hints.framebuffer.alphaMask = hint; + break; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = hint; break; From 1cdb60bb745a9fb9aa4d19fc758374d3a40b815d Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Wed, 16 Dec 2015 16:36:51 -0500 Subject: [PATCH 02/14] Updated .gitignore to ignore 'build' directory. This is a local build directory that may be in GLFW's root. Since this is just for local builds, I ignore it. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 73f819d38..451836daf 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,5 @@ tests/title tests/version tests/windows +# Local build directory +build/ From 444fe6efe94c833a7544c05a8dcef7fcd1f5dd09 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 11:09:41 -0500 Subject: [PATCH 03/14] Added tests/transparent_threads.c. This is a minor variant of tests/threads.c that uses transparent windows. You should be able to drag the windows around and see whatever is behind them. --- tests/CMakeLists.txt | 4 +- tests/transparent_threads.c | 147 ++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 tests/transparent_threads.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index af211600b..128befb74 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -37,13 +37,14 @@ add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD}) add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${GLAD}) add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GETOPT} ${GLAD}) add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD}) +add_executable(transparent_threads WIN32 MACOSX_BUNDLE transparent_threads.c ${TINYCTHREAD} ${GLAD}) add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD}) add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD}) target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") -set(WINDOWS_BINARIES empty sharing tearing threads title windows) +set(WINDOWS_BINARIES empty sharing tearing threads transparent_threads title windows) set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo iconify joysticks monitors reopen cursor) @@ -61,6 +62,7 @@ if (APPLE) set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads") + set_target_properties(transparent_threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Transparent threads") set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") diff --git a/tests/transparent_threads.c b/tests/transparent_threads.c new file mode 100644 index 000000000..766abd20c --- /dev/null +++ b/tests/transparent_threads.c @@ -0,0 +1,147 @@ +//======================================================================== +// Multi-threading test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is intended to verify whether the OpenGL context part of +// the GLFW API is able to be used from multiple threads +// +//======================================================================== + +#include "tinycthread.h" + +#include +#include + +#include +#include +#include + +typedef struct +{ + GLFWwindow* window; + const char* title; + float r, g, b, a; + thrd_t id; +} Thread; + +static volatile int running = GLFW_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + const Thread* thread = data; + + glfwMakeContextCurrent(thread->window); + glfwSwapInterval(1); + + while (running) + { + const float v = (float) fabs(sin(glfwGetTime() * 2.f)); + glClearColor(thread->r * v, thread->g * v, thread->b * v, thread->a * v); + + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(thread->window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +int main(void) +{ + int i, result; + Thread threads[] = + { + { NULL, "Red", 1.0f, 0.0f, 0.0f, 0.5f, 0 }, + { NULL, "Green", 0.0f, 1.0f, 0.0f, 0.5f, 0 }, + { NULL, "Blue", 0.0f, 0.0f, 1.0f, 0.5f, 0 } + }; + const int count = sizeof(threads) / sizeof(Thread); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + for (i = 0; i < count; i++) + { + threads[i].window = glfwCreateWindow(200, 200, + threads[i].title, + NULL, NULL); + if (!threads[i].window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); + glfwShowWindow(threads[i].window); + } + + glfwMakeContextCurrent(threads[0].window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwMakeContextCurrent(NULL); + + for (i = 0; i < count; i++) + { + if (thrd_create(&threads[i].id, thread_main, threads + i) != + thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + while (running) + { + glfwWaitEvents(); + + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(threads[i].window)) + running = GLFW_FALSE; + } + } + + for (i = 0; i < count; i++) + glfwHideWindow(threads[i].window); + + for (i = 0; i < count; i++) + thrd_join(threads[i].id, &result); + + exit(EXIT_SUCCESS); +} + From cca32549678a3263edf550979b918bcfc49da246 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 11:12:51 -0500 Subject: [PATCH 04/14] Removed 'build' directory per @elmindreda's request. --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 451836daf..d17d793b4 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,3 @@ tests/threads tests/title tests/version tests/windows - -# Local build directory -build/ From 69fca03d781c125e38d5b6c59448d0496231c3b6 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 11:18:17 -0500 Subject: [PATCH 05/14] Renamed GLFW_ALPHA_MASK as GLFW_TRANSPARENT as per @elmindreda --- examples/transparent.c | 2 +- include/GLFW/glfw3.h | 2 +- src/window.c | 2 +- tests/transparent_threads.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/transparent.c b/examples/transparent.c index 195e95623..e77b7167d 100644 --- a/examples/transparent.c +++ b/examples/transparent.c @@ -87,7 +87,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_ALPHA_BITS, 8); - glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); window = glfwCreateWindow(256, 256, "Transparent window example", NULL, NULL); diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index d42be4f97..87cb11e6f 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -649,7 +649,7 @@ extern "C" { #define GLFW_SRGB_CAPABLE 0x0002100E #define GLFW_REFRESH_RATE 0x0002100F #define GLFW_DOUBLEBUFFER 0x00021010 -#define GLFW_ALPHA_MASK 0x00021011 +#define GLFW_TRANSPARENT 0x00021011 #define GLFW_CLIENT_API 0x00022001 #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 diff --git a/src/window.c b/src/window.c index aa33231c9..f9c1e11bf 100644 --- a/src/window.c +++ b/src/window.c @@ -319,7 +319,7 @@ GLFWAPI void glfwWindowHint(int target, int hint) case GLFW_DOUBLEBUFFER: _glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; break; - case GLFW_ALPHA_MASK: + case GLFW_TRANSPARENT: _glfw.hints.framebuffer.alphaMask = hint; break; case GLFW_SAMPLES: diff --git a/tests/transparent_threads.c b/tests/transparent_threads.c index 766abd20c..705714c9b 100644 --- a/tests/transparent_threads.c +++ b/tests/transparent_threads.c @@ -91,7 +91,7 @@ int main(void) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_ALPHA_BITS, 8); - glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); for (i = 0; i < count; i++) From c8c7ad249a682590e80eb383b07771692ce8dbfa Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 11:25:45 -0500 Subject: [PATCH 06/14] Changed 'alphaMask' to 'transparent' per @elmindreda's request. --- src/cocoa_window.m | 6 +++--- src/context.c | 2 +- src/internal.h | 4 ++-- src/nsgl_context.m | 2 +- src/wgl_context.c | 4 ++-- src/window.c | 26 +++++++++++++------------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 96fcb002e..d1075d2cf 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -322,9 +322,9 @@ static int translateKey(unsigned int key) - (BOOL)isOpaque { - // Set to NO even if alphaMask is not used; + // Set to NO even if transparent is not used; // The NSView/GLFWContentView does not need to be opaque anyway, - // and to avoid keeping track of alphaMask inside the NSView we + // and to avoid keeping track of transparent inside the NSView we // just return NO here instead. return NO; } @@ -863,7 +863,7 @@ static GLFWbool createWindow(_GLFWwindow* window, [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; #endif /*_GLFW_USE_RETINA*/ - if (wndconfig->alphaMask) + if (wndconfig->transparent) { [window->ns.object setOpaque:NO]; [window->ns.object setBackgroundColor:[NSColor clearColor]]; diff --git a/src/context.c b/src/context.c index cdec72062..3767c151f 100644 --- a/src/context.c +++ b/src/context.c @@ -216,7 +216,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, continue; } - if (desired->alphaMask > 0 && current->alphaMask == 0) + if (desired->transparent > 0 && current->transparent == 0) { // Alpha mask is a hard constraint continue; diff --git a/src/internal.h b/src/internal.h index 92983f1de..a5b96454e 100644 --- a/src/internal.h +++ b/src/internal.h @@ -185,7 +185,7 @@ struct _GLFWwndconfig GLFWbool focused; GLFWbool autoIconify; GLFWbool floating; - GLFWbool alphaMask; + GLFWbool transparent; _GLFWmonitor* monitor; }; @@ -236,7 +236,7 @@ struct _GLFWfbconfig int samples; GLFWbool sRGB; GLFWbool doublebuffer; - int alphaMask; + int transparent; // This is defined in the context API's context.h _GLFW_PLATFORM_FBCONFIG; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 5a16766e6..afbef6cdd 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -215,7 +215,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } - if (fbconfig->alphaMask) + if (fbconfig->transparent) { GLint opaque = 0; [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; diff --git a/src/wgl_context.c b/src/wgl_context.c index c07d58edb..9f9a04118 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -236,8 +236,8 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, u->doublebuffer = GLFW_TRUE; } - // always able to create alpha mask on win - u->alphaMask = desired->alphaMask; + // always able to create transparent windows on Windows + u->transparent = desired->transparent; u->wgl = n; usableCount++; diff --git a/src/window.c b/src/window.c index f9c1e11bf..54e407779 100644 --- a/src/window.c +++ b/src/window.c @@ -132,17 +132,17 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, return NULL; } - fbconfig = _glfw.hints.framebuffer; - ctxconfig = _glfw.hints.context; - wndconfig = _glfw.hints.window; - fbconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; + fbconfig = _glfw.hints.framebuffer; + ctxconfig = _glfw.hints.context; + wndconfig = _glfw.hints.window; + fbconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; - wndconfig.width = width; - wndconfig.height = height; - wndconfig.title = title; - wndconfig.monitor = (_GLFWmonitor*) monitor; - ctxconfig.share = (_GLFWwindow*) share; - wndconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; + wndconfig.width = width; + wndconfig.height = height; + wndconfig.title = title; + wndconfig.monitor = (_GLFWmonitor*) monitor; + ctxconfig.share = (_GLFWwindow*) share; + wndconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; if (ctxconfig.share) { @@ -179,7 +179,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->decorated = wndconfig.decorated; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; - window->transparent = wndconfig.alphaMask; + window->transparent = wndconfig.transparent; window->cursorMode = GLFW_CURSOR_NORMAL; // Save the currently current context so it can be restored later @@ -268,7 +268,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; - _glfw.hints.framebuffer.alphaMask = GLFW_FALSE; + _glfw.hints.framebuffer.transparent = GLFW_FALSE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -320,7 +320,7 @@ GLFWAPI void glfwWindowHint(int target, int hint) _glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_TRANSPARENT: - _glfw.hints.framebuffer.alphaMask = hint; + _glfw.hints.framebuffer.transparent = hint; break; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = hint; From f5e83caeeb09ab2168f907ace3bbc0bf50cc6537 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 11:34:16 -0500 Subject: [PATCH 07/14] Moved hint clamping into glfwWindowHint() per @elmindreda --- src/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/window.c b/src/window.c index 54e407779..66e47bd9a 100644 --- a/src/window.c +++ b/src/window.c @@ -135,14 +135,14 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, fbconfig = _glfw.hints.framebuffer; ctxconfig = _glfw.hints.context; wndconfig = _glfw.hints.window; - fbconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; + fbconfig.transparent = _glfw.hints.framebuffer.transparent; wndconfig.width = width; wndconfig.height = height; wndconfig.title = title; wndconfig.monitor = (_GLFWmonitor*) monitor; ctxconfig.share = (_GLFWwindow*) share; - wndconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; + wndconfig.transparent = _glfw.hints.framebuffer.transparent; if (ctxconfig.share) { @@ -320,7 +320,7 @@ GLFWAPI void glfwWindowHint(int target, int hint) _glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_TRANSPARENT: - _glfw.hints.framebuffer.transparent = hint; + _glfw.hints.framebuffer.transparent = hint ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = hint; From 3229ae91b2e04871286ad93c618abaddea91a85f Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Thu, 17 Dec 2015 15:49:28 -0500 Subject: [PATCH 08/14] Created examples/filters.c to demonstrate how to draw in one window based on the position of a different window. This illustrates the idea of filters; windows that draw their contents based on the content of a different window (similar to what you'd see if you viewed something through a colored filter). This works on OS X. Untested on other platforms. --- examples/CMakeLists.txt | 5 +- examples/filters.c | 281 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 examples/filters.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f4123aa0c..86668fd42 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -38,10 +38,12 @@ add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD}) add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD}) add_executable(transparent WIN32 MACOSX_BUNDLE transparent.c ${ICON} ${GLAD}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD}) +add_executable(filters WIN32 MACOSX_BUNDLE filters.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD}) target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") +target_link_libraries(filters "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") -set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) +set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave filters) set_target_properties(${WINDOWS_BINARIES} PROPERTIES FOLDER "GLFW3/Examples") @@ -56,6 +58,7 @@ if (APPLE) set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") + set_target_properties(filters PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Filters") set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView") set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") diff --git a/examples/filters.c b/examples/filters.c new file mode 100644 index 000000000..8cd076a89 --- /dev/null +++ b/examples/filters.c @@ -0,0 +1,281 @@ +/** + * This code was originally derived from the threads test code that came with + * the license below. However, its purpose has changed; while it does show + * how to use threads, its real purpose is to show how to draw images on a + * window based on the location of a different window. + */ + +//======================================================================== +// Multi-threading test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is intended to verify whether the OpenGL context part of +// the GLFW API is able to be used from multiple threads +// +//======================================================================== + +#include "tinycthread.h" + +#include +#include + +#include "linmath.h" + +#include +#include +#include + +static const struct +{ + float x, y; + float r, g, b; +} vertices[3] = +{ + { -0.6f, -0.4f, 1.f, 0.f, 0.f }, + { 0.6f, -0.4f, 0.f, 1.f, 0.f }, + { 0.f, 0.6f, 0.f, 0.f, 1.f } +}; + +static const char* vertex_shader_text = +"uniform mat4 MVP;\n" +"attribute vec3 vCol;\n" +"attribute vec2 vPos;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" +" color = vCol;\n" +"}\n"; + +static const char* fragment_shader_text = +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_FragColor = vec4(color, 1.0);\n" +"}\n"; + +typedef struct +{ + GLFWwindow* primary_window; + GLFWwindow* window; + const char* title; + float r, g, b, a; + thrd_t id; +} Thread; + +static volatile int running = GLFW_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + const Thread* thread = data; + + glfwMakeContextCurrent(thread->window); + glfwSwapInterval(1); + + while (running) + { + const float v = (float) fabs(sin(glfwGetTime() * 2.f)); + glClearColor(thread->r * v, thread->g * v, thread->b * v, thread->a * v); + + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(thread->window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +static int other_thread_main(void* data) +{ + const Thread* thread = data; + + GLuint vertex_buffer, vertex_shader, fragment_shader, program; + GLint mvp_location, vpos_location, vcol_location; + + glfwMakeContextCurrent(thread->window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + // NOTE: OpenGL error checks have been omitted for brevity + + glGenBuffers(1, &vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); + glCompileShader(vertex_shader); + + fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + mvp_location = glGetUniformLocation(program, "MVP"); + vpos_location = glGetAttribLocation(program, "vPos"); + vcol_location = glGetAttribLocation(program, "vCol"); + + glEnableVertexAttribArray(vpos_location); + glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) 0); + glEnableVertexAttribArray(vcol_location); + glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) (sizeof(float) * 2)); + + while (running) + { + int primary_x_pos, primary_y_pos; + int my_x_pos, my_y_pos; + float delta_x, delta_y; + + glfwGetWindowPos(thread->primary_window, &primary_x_pos, &primary_y_pos); + glfwGetWindowPos(thread->window, &my_x_pos, &my_y_pos); + + float ratio; + int width, height; + mat4x4 m, p, mvp; + const float v = (float) fabs(sin(glfwGetTime() * 2.f)); + glfwGetFramebufferSize(thread->window, &width, &height); + ratio = width / (float) height; + glViewport(0, 0, width, height); + + delta_x = (((float)(primary_x_pos - my_x_pos)) / ((float) width)) * 2; + delta_y = (-((float)(primary_y_pos - my_y_pos)) / ((float) height)) * 2; + + glClearColor(thread->r * v, thread->g * v, thread->b * v, thread->a * v); + glClear(GL_COLOR_BUFFER_BIT); + + mat4x4_identity(m); + mat4x4_rotate_Z(m, m, (float) glfwGetTime()); + mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_translate_in_place(p, delta_x, delta_y, 0.0f); + mat4x4_mul(mvp, p, m); + //mat4x4_translate_in_place(mvp, 1.0f, 0.0f, 0.0f); + + glUseProgram(program); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(thread->window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +int main(void) +{ + int i, result; + Thread threads[] = + { + { NULL, NULL, "Red", 1.0f, 0.0f, 0.0f, 0.5f, 0 }, + { NULL, NULL, "Green", 0.0f, 1.0f, 0.0f, 0.5f, 0 }, + { NULL, NULL, "Blue", 0.0f, 0.0f, 1.0f, 0.5f, 0 } + }; + const int count = sizeof(threads) / sizeof(Thread); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + for (i = 0; i < count; i++) + { + threads[i].window = glfwCreateWindow(200, 200, + threads[i].title, + NULL, NULL); + if (!threads[i].window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); + glfwShowWindow(threads[i].window); + } + + for (i = 0; i < count; i++) + { + threads[i].primary_window = threads[0].window; + } + + glfwMakeContextCurrent(threads[0].window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwMakeContextCurrent(NULL); + + for (i = 0; i < count; i++) + { + if (i == (count - 1)) + { + result = thrd_create(&threads[i].id, other_thread_main, threads + i); + } + else + { + result = thrd_create(&threads[i].id, thread_main, threads + i); + } + + if (result != thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + while (running) + { + glfwWaitEvents(); + + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(threads[i].window)) + running = GLFW_FALSE; + } + } + + for (i = 0; i < count; i++) + glfwHideWindow(threads[i].window); + + for (i = 0; i < count; i++) + thrd_join(threads[i].id, &result); + + exit(EXIT_SUCCESS); +} + From c7c9b54459f3f2838533b9ce4f2a1fa705204830 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Fri, 18 Dec 2015 09:53:14 -0500 Subject: [PATCH 09/14] Incorporated code from Matt Reagan on the Cocoa-dev mailing list for fast window position updates. This is a direct copy of Matt's code, which is able to determine the current position of a window while it's being dragged. --- src/cocoa_window.m | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index d1075d2cf..36cf81f7d 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -938,13 +938,32 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) { - const NSRect contentRect = - [window->ns.object contentRectForFrameRect:[window->ns.object frame]]; + // Code from Matt Reagan on the Cocoa-dev mailing list. + CGRect rect; + CGWindowID windowID = (CGWindowID)[window->ns.object windowNumber]; + CFArrayRef windowArray = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, windowID); + + if (CFArrayGetCount(windowArray)) + { + CFDictionaryRef windowInfoDictionary = (CFDictionaryRef)CFArrayGetValueAtIndex ((CFArrayRef)windowArray, 0); + + if (CFDictionaryContainsKey(windowInfoDictionary, kCGWindowBounds)) + { + CFDictionaryRef bounds = (CFDictionaryRef)CFDictionaryGetValue(windowInfoDictionary, kCGWindowBounds); + + if (bounds) + { + CGRectMakeWithDictionaryRepresentation(bounds, &rect); + } + } + } + + CFRelease(windowArray); if (xpos) - *xpos = contentRect.origin.x; + *xpos = rect.origin.x; if (ypos) - *ypos = transformY(contentRect.origin.y + contentRect.size.height); + *ypos = rect.origin.y; } void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) From a676f4d5d00517e052a2e97c7e46688eeb248ce3 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Fri, 18 Dec 2015 13:41:34 -0500 Subject: [PATCH 10/14] Bug fixes to filters.c: All windows now show same contents regardless of position. The auxiliary windows now reflect what is happening in the primary window. Unfortunately, there is still a bug in the primary window code that affects the orthographic projection. Basically, the object that is drawn is resized along with the contents of the window instead of remaining a constant size while the window is resized around it. --- examples/filters.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/examples/filters.c b/examples/filters.c index 8cd076a89..292454c02 100644 --- a/examples/filters.c +++ b/examples/filters.c @@ -155,32 +155,37 @@ static int other_thread_main(void* data) while (running) { int primary_x_pos, primary_y_pos; + int primary_width, primary_height; int my_x_pos, my_y_pos; + int my_width, my_height; float delta_x, delta_y; + float ratio, x_ratio, y_ratio; + float x_offset, y_offset; + mat4x4 m, p, mvp; glfwGetWindowPos(thread->primary_window, &primary_x_pos, &primary_y_pos); + glfwGetFramebufferSize(thread->primary_window, &primary_width, &primary_height); glfwGetWindowPos(thread->window, &my_x_pos, &my_y_pos); + glfwGetFramebufferSize(thread->window, &my_width, &my_height); - float ratio; - int width, height; - mat4x4 m, p, mvp; const float v = (float) fabs(sin(glfwGetTime() * 2.f)); - glfwGetFramebufferSize(thread->window, &width, &height); - ratio = width / (float) height; - glViewport(0, 0, width, height); + ratio = my_width / (float) my_height; + x_ratio = (my_width / (float) primary_width); + y_ratio = (my_height / (float) primary_height); - delta_x = (((float)(primary_x_pos - my_x_pos)) / ((float) width)) * 2; - delta_y = (-((float)(primary_y_pos - my_y_pos)) / ((float) height)) * 2; + delta_x = (((float)(primary_x_pos - my_x_pos)) / ((float) my_width)) * x_ratio * 2 - x_ratio + 1; + delta_y = (-((float)(primary_y_pos - my_y_pos)) / ((float) my_height)) * y_ratio * 2 + y_ratio - 1; + + glViewport(0, 0, my_width, my_height); glClearColor(thread->r * v, thread->g * v, thread->b * v, thread->a * v); glClear(GL_COLOR_BUFFER_BIT); mat4x4_identity(m); mat4x4_rotate_Z(m, m, (float) glfwGetTime()); - mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_ortho(p, -x_ratio, x_ratio, -y_ratio, y_ratio, 1.f, -1.f); mat4x4_translate_in_place(p, delta_x, delta_y, 0.0f); mat4x4_mul(mvp, p, m); - //mat4x4_translate_in_place(mvp, 1.0f, 0.0f, 0.0f); glUseProgram(program); glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); @@ -241,14 +246,7 @@ int main(void) for (i = 0; i < count; i++) { - if (i == (count - 1)) - { - result = thrd_create(&threads[i].id, other_thread_main, threads + i); - } - else - { - result = thrd_create(&threads[i].id, thread_main, threads + i); - } + result = thrd_create(&threads[i].id, other_thread_main, threads + i); if (result != thrd_success) { From c63da9254790593222edce8e89abd548f0720b4d Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Fri, 18 Dec 2015 14:46:56 -0500 Subject: [PATCH 11/14] Changed the location of one vertex so the triangle is more triangular (maybe?) I haven't checked the math on this, but in playing with blending modes I noticed that one of the rotated vertices appeared to be closer to the center of rotation than the others. This adjustment makes it so they are all the same distance from the center of rotation. If the center of rotation is conincident with the triangle's center, then this will mean the triangle is equilateral, but I haven't verified this, it just looked right from the rotations. --- examples/filters.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/filters.c b/examples/filters.c index 292454c02..b5801ebb4 100644 --- a/examples/filters.c +++ b/examples/filters.c @@ -54,7 +54,7 @@ static const struct { { -0.6f, -0.4f, 1.f, 0.f, 0.f }, { 0.6f, -0.4f, 0.f, 1.f, 0.f }, - { 0.f, 0.6f, 0.f, 0.f, 1.f } + { 0.f, 0.72f, 0.f, 0.f, 1.f } }; static const char* vertex_shader_text = From 1e1def1d04d84324c846d659bce30b98064468ec Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Tue, 16 Feb 2016 13:53:32 -0500 Subject: [PATCH 12/14] Bug fix to examples/CMakeLists.txt to add transparent to WINDOWS_BINARIES. This fix is due to @thomthom on GitHub, who discovered the bug and suggested the fix. Basically, I forgot to add the 'transparent' app to the list of Windows applications, which made a mess of the linker, etc. This fix should take care of it. --- examples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 86668fd42..71a1d0d99 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -43,7 +43,7 @@ add_executable(filters WIN32 MACOSX_BUNDLE filters.c ${ICON} ${TINYCTHREAD} ${GE target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") target_link_libraries(filters "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") -set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave filters) +set(WINDOWS_BINARIES boing gears heightmap particles simple transparent splitview wave filters) set_target_properties(${WINDOWS_BINARIES} PROPERTIES FOLDER "GLFW3/Examples") From 7e8c59a3ae3556326476852158dd9e587d20d9e8 Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Tue, 16 Feb 2016 16:28:47 -0500 Subject: [PATCH 13/14] Bug fix: Forgot to put in target properties for the transparent app. --- examples/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5c7440b18..da8e30584 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -59,6 +59,7 @@ if (APPLE) set_target_properties(filters PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Filters") set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView") + set_target_properties(transparent PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Transparent") set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") set_target_properties(${WINDOWS_BINARIES} PROPERTIES From 1557990fa1b78e7f2c0131f92fee3f053b4b1bfd Mon Sep 17 00:00:00 2001 From: Cem Karan Date: Mon, 29 Aug 2016 11:33:43 -0400 Subject: [PATCH 14/14] Merged in a few changes from master. This is not a complete merge; I don't have time right now to do so. --- src/context.c | 6 ------ src/window.c | 5 ----- 2 files changed, 11 deletions(-) diff --git a/src/context.c b/src/context.c index 1961d89bb..e63348783 100644 --- a/src/context.c +++ b/src/context.c @@ -181,12 +181,6 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, continue; } - if (desired->transparent > 0 && current->transparent == 0) - { - // Alpha mask is a hard constraint - continue; - } - // Count number of missing buffers { missing = 0; diff --git a/src/window.c b/src/window.c index 53216fcba..fe741dc6f 100644 --- a/src/window.c +++ b/src/window.c @@ -178,7 +178,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->decorated = wndconfig.decorated; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; - window->transparent = wndconfig.transparent; window->cursorMode = GLFW_CURSOR_NORMAL; window->minwidth = GLFW_DONT_CARE; @@ -258,7 +257,6 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; - _glfw.hints.framebuffer.transparent = GLFW_FALSE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -309,9 +307,6 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_DOUBLEBUFFER: _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; break; - case GLFW_TRANSPARENT: - _glfw.hints.framebuffer.transparent = hint ? GLFW_TRUE : GLFW_FALSE; - break; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = value; break;