From fe6fb57df00f64cc23f2d72172b67a01b80d09f1 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 14 Oct 2010 13:54:19 +0200 Subject: [PATCH 01/22] Updated Win32 implementation of gamma ramp API. --- src/win32/platform.h | 1 - src/win32/win32_gamma.c | 19 +++++-------------- src/win32/win32_init.c | 19 +++---------------- 3 files changed, 8 insertions(+), 31 deletions(-) mode change 100644 => 100755 src/win32/platform.h mode change 100644 => 100755 src/win32/win32_gamma.c mode change 100644 => 100755 src/win32/win32_init.c diff --git a/src/win32/platform.h b/src/win32/platform.h old mode 100644 new mode 100755 index fb9107b8..3ce580f2 --- a/src/win32/platform.h +++ b/src/win32/platform.h @@ -270,7 +270,6 @@ typedef struct _GLFWlibraryWin32 ATOM classAtom; // Window class atom HHOOK keyboardHook; // Keyboard hook handle DWORD foregroundLockTimeout; - HDC desktopDC; // Default monitor struct { diff --git a/src/win32/win32_gamma.c b/src/win32/win32_gamma.c old mode 100644 new mode 100755 index 71d2645f..f25df6e6 --- a/src/win32/win32_gamma.c +++ b/src/win32/win32_gamma.c @@ -41,14 +41,9 @@ // Save the gamma ramp to our internal copy //======================================================================== -void _glfwPlatformSaveGammaRamp(int ramp) +void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) { - if (!_glfwLibrary.gammaSize) - { - return; - } - _glfw_GetDeviceGammaRamp(_glfwLibrary.Win32.desktopDC, - _glfwLibrary.gammaRamp[ramp]); + _glfw_GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp); } @@ -56,12 +51,8 @@ void _glfwPlatformSaveGammaRamp(int ramp) // Restore the gamma ramp to our internal copy of the gamma ramp //======================================================================== -void _glfwPlatformRestoreGammaRamp(int ramp) +void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) { - if (!_glfwLibrary.gammaSize) - { - return; - } - _glfw_SetDeviceGammaRamp(_glfwLibrary.Win32.desktopDC, - _glfwLibrary.gammaRamp[ramp]); + _glfw_SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp); } + diff --git a/src/win32/win32_init.c b/src/win32/win32_init.c old mode 100644 new mode 100755 index 54939cc3..4c8bfb22 --- a/src/win32/win32_init.c +++ b/src/win32/win32_init.c @@ -160,18 +160,9 @@ int _glfwPlatformInit(void) _glfwLibrary.Win32.instance = GetModuleHandle(NULL); - // Initialise the internal gamma ramp - _glfwLibrary.gammaSize = 256; - _glfwLibrary.gammaRamp[GLFW_GAMMA_ORIG] = - malloc(256 * sizeof(unsigned short) * 3); - _glfwLibrary.gammaRamp[GLFW_GAMMA_CURR] = - malloc(256 * sizeof(unsigned short) * 3); - - // Get the desktop DC - _glfwLibrary.Win32.desktopDC = GetDC(GetDesktopWindow()); - // Save the original gamma ramp - _glfwPlatformSaveGammaRamp(GLFW_GAMMA_ORIG); + _glfwLibrary.originalRampSize = 256; + _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); _glfwInitTimer(); @@ -186,11 +177,7 @@ int _glfwPlatformInit(void) int _glfwPlatformTerminate(void) { // Restore the original gamma ramp - _glfwPlatformRestoreGammaRamp(GLFW_GAMMA_ORIG); - - // Free the gamma ramps - free(_glfwLibrary.gammaRamp[GLFW_GAMMA_ORIG]); - free(_glfwLibrary.gammaRamp[GLFW_GAMMA_CURR]); + _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); if (_glfwLibrary.Win32.classAtom) { From 0374c11c438cbbebf0cd59620308be49c02e9d63 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 14 Oct 2010 14:09:26 +0200 Subject: [PATCH 02/22] Corrected API version. --- src/win32/win32_gamma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/win32_gamma.c b/src/win32/win32_gamma.c index f25df6e6..6208909a 100755 --- a/src/win32/win32_gamma.c +++ b/src/win32/win32_gamma.c @@ -1,7 +1,7 @@ //======================================================================== // GLFW - An OpenGL framework // Platform: Win32/WGL -// API version: 2.7 +// API version: 3.0 // WWW: http://www.glfw.org/ //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard From 21f6f695a658277e01143a0499aba2d4a54679e6 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 14 Oct 2010 14:10:07 +0200 Subject: [PATCH 03/22] Corrected copyright. --- src/win32/win32_gamma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/win32/win32_gamma.c b/src/win32/win32_gamma.c index 6208909a..c85a66d2 100755 --- a/src/win32/win32_gamma.c +++ b/src/win32/win32_gamma.c @@ -4,8 +4,7 @@ // API version: 3.0 // WWW: http://www.glfw.org/ //------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund +// Copyright (c) 2010 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 From c592cd5dbfcb87541afc42b75a1e9ab94641c9a9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 14 Oct 2010 14:13:39 +0200 Subject: [PATCH 04/22] Function comment header updates. --- src/gamma.c | 2 +- src/win32/win32_gamma.c | 10 +++++----- src/x11/x11_gamma.c | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) mode change 100644 => 100755 src/gamma.c mode change 100644 => 100755 src/x11/x11_gamma.c diff --git a/src/gamma.c b/src/gamma.c old mode 100644 new mode 100755 index ff97d600..b2416a98 --- a/src/gamma.c +++ b/src/gamma.c @@ -82,7 +82,7 @@ GLFWAPI void glfwSetGammaFormula(float gamma, float blacklevel, float gain) //======================================================================== -// Return the currently set gamma ramp +// Return the cached currently set gamma ramp //======================================================================== GLFWAPI void glfwGetGammaRamp(GLFWgammaramp* ramp) diff --git a/src/win32/win32_gamma.c b/src/win32/win32_gamma.c index c85a66d2..fc01cc44 100755 --- a/src/win32/win32_gamma.c +++ b/src/win32/win32_gamma.c @@ -32,12 +32,12 @@ #include -//************************************************************************ -//**** GLFW internal functions **** -//************************************************************************ +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// //======================================================================== -// Save the gamma ramp to our internal copy +// Retrieve the currently set gamma ramp //======================================================================== void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) @@ -47,7 +47,7 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) //======================================================================== -// Restore the gamma ramp to our internal copy of the gamma ramp +// Push the specified gamma ramp to the monitor //======================================================================== void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) diff --git a/src/x11/x11_gamma.c b/src/x11/x11_gamma.c old mode 100644 new mode 100755 index 264e4c98..85522bef --- a/src/x11/x11_gamma.c +++ b/src/x11/x11_gamma.c @@ -33,12 +33,12 @@ #include -//************************************************************************ -//**** GLFW internal functions **** -//************************************************************************ +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// //======================================================================== -// Save the original gamma ramp so that we can restore it later +// Retrieve the currently set gamma ramp //======================================================================== void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) @@ -78,7 +78,7 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) //======================================================================== -// Make the specified gamma ramp current +// Push the specified gamma ramp to the monitor //======================================================================== void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) From 66754f135889ed625d9fb7ae16fdc9b5e954d6d9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 14 Oct 2010 14:14:50 +0200 Subject: [PATCH 05/22] Removed executable bits (gah). --- src/gamma.c | 0 src/win32/platform.h | 0 src/win32/win32_gamma.c | 0 src/win32/win32_init.c | 0 src/x11/x11_gamma.c | 0 5 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/gamma.c mode change 100755 => 100644 src/win32/platform.h mode change 100755 => 100644 src/win32/win32_gamma.c mode change 100755 => 100644 src/win32/win32_init.c mode change 100755 => 100644 src/x11/x11_gamma.c diff --git a/src/gamma.c b/src/gamma.c old mode 100755 new mode 100644 diff --git a/src/win32/platform.h b/src/win32/platform.h old mode 100755 new mode 100644 diff --git a/src/win32/win32_gamma.c b/src/win32/win32_gamma.c old mode 100755 new mode 100644 diff --git a/src/win32/win32_init.c b/src/win32/win32_init.c old mode 100755 new mode 100644 diff --git a/src/x11/x11_gamma.c b/src/x11/x11_gamma.c old mode 100755 new mode 100644 From 0e1a004b7deb2464e9a51f35c8712cc6bb1246e3 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Fri, 15 Oct 2010 17:22:30 +0200 Subject: [PATCH 06/22] Formatting. --- CMakeLists.txt | 6 ++---- src/cocoa/CMakeLists.txt | 31 ++++++++++++---------------- src/win32/CMakeLists.txt | 44 ++++++++++++++++++++-------------------- src/x11/CMakeLists.txt | 31 +++++++++++++--------------- 4 files changed, 51 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cf2a4e..c99d1fc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,7 @@ set(GLFW_VERSION_MINOR "0") set(GLFW_VERSION_PATCH "0") set(GLFW_VERSION_EXTRA "") set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") -set(GLFW_VERSION_FULL - "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") +set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") include(CheckFunctionExists) include(CheckSymbolExists) @@ -159,8 +158,7 @@ install(FILES COPYING.txt readme.html # Uninstall operation #-------------------------------------------------------------------- configure_file(${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in - ${GLFW_BINARY_DIR}/cmake_uninstall.cmake - IMMEDIATE @ONLY) + ${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) add_custom_target(uninstall ${CMAKE_COMMAND} -P diff --git a/src/cocoa/CMakeLists.txt b/src/cocoa/CMakeLists.txt index 37c3b0a8..e2bfa194 100644 --- a/src/cocoa/CMakeLists.txt +++ b/src/cocoa/CMakeLists.txt @@ -1,41 +1,36 @@ -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${GLFW_INCLUDE_DIR}) -set(cocoa_SOURCES - cocoa_enable.m - cocoa_fullscreen.m - cocoa_glext.m - cocoa_init.m - cocoa_joystick.m - cocoa_time.m - cocoa_window.m) +set(cocoa_SOURCES cocoa_enable.m + cocoa_fullscreen.m + cocoa_glext.m + cocoa_init.m + cocoa_joystick.m + cocoa_time.m + cocoa_window.m) # For some reason, CMake doesn't know about .m set_source_files_properties(${cocoa_SOURCES} PROPERTIES LANGUAGE C) -set(libglfw_SOURCES - ${common_SOURCES} - ${cocoa_SOURCES}) +set(libglfw_SOURCES ${common_SOURCES} ${cocoa_SOURCES}) add_library(libglfwStatic STATIC ${libglfw_SOURCES}) add_library(libglfwShared SHARED ${libglfw_SOURCES}) target_link_libraries(libglfwShared ${GLFW_LIBRARIES}) set_target_properties(libglfwStatic libglfwShared PROPERTIES - CLEAN_DIRECT_OUTPUT 1 - OUTPUT_NAME glfw -) + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME glfw) # Append -fno-common to the compile flags to work around a bug in the Apple GCC get_target_property(CFLAGS libglfwShared COMPILE_FLAGS) if(NOT CFLAGS) - set(CFLAGS "") + set(CFLAGS "") endif(NOT CFLAGS) set_target_properties(libglfwShared PROPERTIES COMPILE_FLAGS "${CFLAGS} -fno-common") diff --git a/src/win32/CMakeLists.txt b/src/win32/CMakeLists.txt index f7df1ff7..4886d7ba 100644 --- a/src/win32/CMakeLists.txt +++ b/src/win32/CMakeLists.txt @@ -1,8 +1,8 @@ if(CYGWIN) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) # These lines are intended to remove the --export-all-symbols # flag added in the Modules/Platform/CYGWIN.cmake file of the @@ -19,36 +19,36 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${GLFW_BINARY_DIR}/src ${GLFW_INCLUDE_DIR}) -set(libglfw_SOURCES - ${common_SOURCES} - win32_enable.c - win32_fullscreen.c - win32_gamma.c - win32_glext.c - win32_init.c - win32_joystick.c - win32_time.c - win32_window.c - win32_dllmain.c) +set(libglfw_SOURCES ${common_SOURCES} + win32_enable.c + win32_fullscreen.c + win32_gamma.c + win32_glext.c + win32_init.c + win32_joystick.c + win32_time.c + win32_window.c + win32_dllmain.c) add_library(libglfwStatic STATIC ${libglfw_SOURCES}) add_library(libglfwShared SHARED ${libglfw_SOURCES}) target_link_libraries(libglfwShared ${OPENGL_gl_LIBRARY}) set_target_properties(libglfwShared PROPERTIES - DEFINE_SYMBOL GLFW_BUILD_DLL - PREFIX "" - IMPORT_PREFIX "" - IMPORT_SUFFIX "dll.lib") + DEFINE_SYMBOL GLFW_BUILD_DLL + PREFIX "" + IMPORT_PREFIX "" + IMPORT_SUFFIX "dll.lib") set_target_properties(libglfwStatic libglfwShared PROPERTIES - CLEAN_DIRECT_OUTPUT 1 - OUTPUT_NAME glfw) + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME glfw) if(CYGWIN) # Build for the regular Win32 environment (not Cygwin) - set_target_properties(libglfwStatic libglfwShared PROPERTIES COMPILE_FLAGS "-mwin32 -mno-cygwin") - set_target_properties(libglfwStatic libglfwShared PROPERTIES LINK_FLAGS "-mwin32 -mno-cygwin") + set_target_properties(libglfwStatic libglfwShared PROPERTIES + COMPILE_FLAGS "-mwin32 -mno-cygwin" + LINK_FLAGS "-mwin32 -mno-cygwin") endif(CYGWIN) install(TARGETS libglfwStatic libglfwShared DESTINATION lib) diff --git a/src/x11/CMakeLists.txt b/src/x11/CMakeLists.txt index a75adf7b..4fe09c49 100644 --- a/src/x11/CMakeLists.txt +++ b/src/x11/CMakeLists.txt @@ -1,32 +1,29 @@ -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${GLFW_INCLUDE_DIR}) -set(libglfw_SOURCES - ${common_SOURCES} - x11_enable.c - x11_fullscreen.c - x11_gamma.c - x11_glext.c - x11_init.c - x11_joystick.c - x11_keysym2unicode.c - x11_time.c - x11_window.c) +set(libglfw_SOURCES ${common_SOURCES} + x11_enable.c + x11_fullscreen.c + x11_gamma.c + x11_glext.c + x11_init.c + x11_joystick.c + x11_keysym2unicode.c + x11_time.c + x11_window.c) add_library(libglfwStatic STATIC ${libglfw_SOURCES}) add_library(libglfwShared SHARED ${libglfw_SOURCES}) target_link_libraries(libglfwShared ${GLFW_LIBRARIES}) set_target_properties(libglfwStatic libglfwShared PROPERTIES - CLEAN_DIRECT_OUTPUT 1 - OUTPUT_NAME glfw -) + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME glfw) install(TARGETS libglfwStatic libglfwShared DESTINATION lib) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc DESTINATION lib/pkgconfig) From 68e58143f850adee011993bf129380c8fad67ac6 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 14:31:46 +0200 Subject: [PATCH 07/22] Renamed dlopen entry point mode name. --- src/x11/x11_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index 4290be7c..55d8d630 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -310,7 +310,7 @@ const char* _glfwPlatformGetVersionString(void) #elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) " glXGetProcAddressEXT" #elif defined(_GLFW_DLOPEN_LIBGL) - " dlopen(libGL)" + " dlsym(libGL)" #else " (no OpenGL extension support)" #endif From a4a2eaaa0ff7b373ddf59c7414d3fedcff6d9bbc Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 14:35:37 +0200 Subject: [PATCH 08/22] Removed whitespace in version string joystick keys. --- src/x11/x11_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index 55d8d630..62f02eee 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -315,9 +315,9 @@ const char* _glfwPlatformGetVersionString(void) " (no OpenGL extension support)" #endif #if defined(_GLFW_USE_LINUX_JOYSTICKS) - " Linux joystick API" + " Linux-joystick-API" #else - " (no joystick support)" + " no-joystick-support" #endif ; From cba8d35c650deffcb9f91501670cee885a58d074 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 14:56:35 +0200 Subject: [PATCH 09/22] Formatting. --- examples/splitview.c | 310 +++++++++++++++++++++---------------------- 1 file changed, 150 insertions(+), 160 deletions(-) diff --git a/examples/splitview.c b/examples/splitview.c index 1611ad90..42c5ec16 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -50,48 +50,49 @@ static int do_redraw = 1; #define TORUS_MAJOR_RES 32 #define TORUS_MINOR_RES 32 -static void drawTorus( void ) +static void drawTorus(void) { static GLuint torus_list = 0; int i, j, k; double s, t, x, y, z, nx, ny, nz, scale, twopi; - if( !torus_list ) + if (!torus_list) { // Start recording displaylist - torus_list = glGenLists( 1 ); - glNewList( torus_list, GL_COMPILE_AND_EXECUTE ); + torus_list = glGenLists(1); + glNewList(torus_list, GL_COMPILE_AND_EXECUTE); // Draw torus twopi = 2.0 * M_PI; - for( i = 0; i < TORUS_MINOR_RES; i++ ) + for (i = 0; i < TORUS_MINOR_RES; i++) { - glBegin( GL_QUAD_STRIP ); - for( j = 0; j <= TORUS_MAJOR_RES; j++ ) + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= TORUS_MAJOR_RES; j++) { - for( k = 1; k >= 0; k-- ) + for (k = 1; k >= 0; k--) { s = (i + k) % TORUS_MINOR_RES + 0.5; t = j % TORUS_MAJOR_RES; // Calculate point on surface - x = (TORUS_MAJOR+TORUS_MINOR*cos(s*twopi/TORUS_MINOR_RES))*cos(t*twopi/TORUS_MAJOR_RES); + x = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * cos(t * twopi / TORUS_MAJOR_RES); y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES); - z = (TORUS_MAJOR+TORUS_MINOR*cos(s*twopi/TORUS_MINOR_RES))*sin(t*twopi/TORUS_MAJOR_RES); + z = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * sin(t * twopi / TORUS_MAJOR_RES); // Calculate surface normal - nx = x - TORUS_MAJOR*cos(t*twopi/TORUS_MAJOR_RES); + nx = x - TORUS_MAJOR * cos(t * twopi / TORUS_MAJOR_RES); ny = y; - nz = z - TORUS_MAJOR*sin(t*twopi/TORUS_MAJOR_RES); - scale = 1.0 / sqrt( nx*nx + ny*ny + nz*nz ); + nz = z - TORUS_MAJOR * sin(t * twopi / TORUS_MAJOR_RES); + scale = 1.0 / sqrt(nx*nx + ny*ny + nz*nz); nx *= scale; ny *= scale; nz *= scale; - glNormal3f( (float)nx, (float)ny, (float)nz ); - glVertex3f( (float)x, (float)y, (float)z ); + glNormal3f((float) nx, (float) ny, (float) nz); + glVertex3f((float) x, (float) y, (float) z); } } + glEnd(); } @@ -101,7 +102,7 @@ static void drawTorus( void ) else { // Playback displaylist - glCallList( torus_list ); + glCallList(torus_list); } } @@ -110,7 +111,7 @@ static void drawTorus( void ) // Draw the scene (a rotating torus) //======================================================================== -static void drawScene( void ) +static void drawScene(void) { const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f}; const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f}; @@ -119,17 +120,17 @@ static void drawScene( void ) glPushMatrix(); // Rotate the object - glRotatef( (GLfloat)rot_x*0.5f, 1.0f, 0.0f, 0.0f ); - glRotatef( (GLfloat)rot_y*0.5f, 0.0f, 1.0f, 0.0f ); - glRotatef( (GLfloat)rot_z*0.5f, 0.0f, 0.0f, 1.0f ); + glRotatef((GLfloat) rot_x * 0.5f, 1.0f, 0.0f, 0.0f); + glRotatef((GLfloat) rot_y * 0.5f, 0.0f, 1.0f, 0.0f); + glRotatef((GLfloat) rot_z * 0.5f, 0.0f, 0.0f, 1.0f); // Set model color (used for orthogonal views, lighting disabled) - glColor4fv( model_diffuse ); + glColor4fv(model_diffuse); // Set model material (used for perspective view, lighting enabled) - glMaterialfv( GL_FRONT, GL_DIFFUSE, model_diffuse ); - glMaterialfv( GL_FRONT, GL_SPECULAR, model_specular ); - glMaterialf( GL_FRONT, GL_SHININESS, model_shininess ); + glMaterialfv(GL_FRONT, GL_DIFFUSE, model_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, model_specular); + glMaterialf(GL_FRONT, GL_SHININESS, model_shininess); // Draw torus drawTorus(); @@ -142,55 +143,55 @@ static void drawScene( void ) // Draw a 2D grid (used for orthogonal views) //======================================================================== -static void drawGrid( float scale, int steps ) +static void drawGrid(float scale, int steps) { - int i; + int i; float x, y; glPushMatrix(); // Set background to some dark bluish grey - glClearColor( 0.05f, 0.05f, 0.2f, 0.0f); - glClear( GL_COLOR_BUFFER_BIT ); + glClearColor(0.05f, 0.05f, 0.2f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); // Setup modelview matrix (flat XY view) glLoadIdentity(); - gluLookAt( 0.0, 0.0, 1.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0 ); + gluLookAt(0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); // We don't want to update the Z-buffer - glDepthMask( GL_FALSE ); + glDepthMask(GL_FALSE); // Set grid color - glColor3f( 0.0f, 0.5f, 0.5f ); + glColor3f(0.0f, 0.5f, 0.5f); - glBegin( GL_LINES ); + glBegin(GL_LINES); // Horizontal lines - x = scale * 0.5f * (float)(steps-1); - y = -scale * 0.5f * (float)(steps-1); - for( i = 0; i < steps; i ++ ) + x = scale * 0.5f * (float) (steps - 1); + y = -scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) { - glVertex3f( -x, y, 0.0f ); - glVertex3f( x, y, 0.0f ); + glVertex3f(-x, y, 0.0f); + glVertex3f(x, y, 0.0f); y += scale; } // Vertical lines - x = -scale * 0.5f * (float)(steps-1); - y = scale * 0.5f * (float)(steps-1); - for( i = 0; i < steps; i ++ ) + x = -scale * 0.5f * (float) (steps - 1); + y = scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) { - glVertex3f( x, -y, 0.0f ); - glVertex3f( x, y, 0.0f ); + glVertex3f(x, -y, 0.0f); + glVertex3f(x, y, 0.0f); x += scale; } glEnd(); // Enable Z-buffer writing again - glDepthMask( GL_TRUE ); + glDepthMask(GL_TRUE); glPopMatrix(); } @@ -200,7 +201,7 @@ static void drawGrid( float scale, int steps ) // Draw all views //======================================================================== -static void drawAllViews( void ) +static void drawAllViews(void) { const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f}; const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; @@ -209,145 +210,142 @@ static void drawAllViews( void ) double aspect; // Calculate aspect of window - if( height > 0 ) - { - aspect = (double)width / (double)height; - } + if (height > 0) + aspect = (double) width / (double) height; else - { aspect = 1.0; - } // Clear screen - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enable scissor test - glEnable( GL_SCISSOR_TEST ); + glEnable(GL_SCISSOR_TEST); // Enable depth test - glEnable( GL_DEPTH_TEST ); - glDepthFunc( GL_LEQUAL ); - + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); // ** ORTHOGONAL VIEWS ** // For orthogonal views, use wireframe rendering - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Enable line anti-aliasing - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Setup orthogonal projection matrix - glMatrixMode( GL_PROJECTION ); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho( -3.0*aspect, 3.0*aspect, -3.0, 3.0, 1.0, 50.0 ); + glOrtho(-3.0 * aspect, 3.0 * aspect, -3.0, 3.0, 1.0, 50.0); // Upper left view (TOP VIEW) - glViewport( 0, height/2, width/2, height/2 ); - glScissor( 0, height/2, width/2, height/2 ); - glMatrixMode( GL_MODELVIEW ); + glViewport(0, height / 2, width / 2, height / 2); + glScissor(0, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt( 0.0f, 10.0f, 1e-3f, // Eye-position (above) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f ); // Up-vector - drawGrid( 0.5, 12 ); + gluLookAt(0.0f, 10.0f, 1e-3f, // Eye-position (above) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); drawScene(); // Lower left view (FRONT VIEW) - glViewport( 0, 0, width/2, height/2 ); - glScissor( 0, 0, width/2, height/2 ); - glMatrixMode( GL_MODELVIEW ); + glViewport(0, 0, width / 2, height / 2); + glScissor(0, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt( 0.0f, 0.0f, 10.0f, // Eye-position (in front of) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f ); // Up-vector - drawGrid( 0.5, 12 ); + gluLookAt(0.0f, 0.0f, 10.0f, // Eye-position (in front of) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); drawScene(); // Lower right view (SIDE VIEW) - glViewport( width/2, 0, width/2, height/2 ); - glScissor( width/2, 0, width/2, height/2 ); - glMatrixMode( GL_MODELVIEW ); + glViewport(width / 2, 0, width / 2, height / 2); + glScissor(width / 2, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt( 10.0f, 0.0f, 0.0f, // Eye-position (to the right) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f ); // Up-vector - drawGrid( 0.5, 12 ); + gluLookAt(10.0f, 0.0f, 0.0f, // Eye-position (to the right) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); drawScene(); // Disable line anti-aliasing - glDisable( GL_LINE_SMOOTH ); - glDisable( GL_BLEND ); - + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); // ** PERSPECTIVE VIEW ** // For perspective view, use solid rendering - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Enable face culling (faster rendering) - glEnable( GL_CULL_FACE ); - glCullFace( GL_BACK ); - glFrontFace( GL_CW ); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); // Setup perspective projection matrix - glMatrixMode( GL_PROJECTION ); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective( 65.0f, aspect, 1.0f, 50.0f ); + gluPerspective(65.0f, aspect, 1.0f, 50.0f); // Upper right view (PERSPECTIVE VIEW) - glViewport( width/2, height/2, width/2, height/2 ); - glScissor( width/2, height/2, width/2, height/2 ); - glMatrixMode( GL_MODELVIEW ); + glViewport(width / 2, height / 2, width / 2, height / 2); + glScissor(width / 2, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt( 3.0f, 1.5f, 3.0f, // Eye-position - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f ); // Up-vector + gluLookAt(3.0f, 1.5f, 3.0f, // Eye-position + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector // Configure and enable light source 1 - glLightfv( GL_LIGHT1, GL_POSITION, light_position ); - glLightfv( GL_LIGHT1, GL_AMBIENT, light_ambient ); - glLightfv( GL_LIGHT1, GL_DIFFUSE, light_diffuse ); - glLightfv( GL_LIGHT1, GL_SPECULAR, light_specular ); - glEnable( GL_LIGHT1 ); - glEnable( GL_LIGHTING ); + glLightfv(GL_LIGHT1, GL_POSITION, light_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHTING); // Draw scene drawScene(); // Disable lighting - glDisable( GL_LIGHTING ); + glDisable(GL_LIGHTING); // Disable face culling - glDisable( GL_CULL_FACE ); + glDisable(GL_CULL_FACE); // Disable depth test - glDisable( GL_DEPTH_TEST ); + glDisable(GL_DEPTH_TEST); // Disable scissor test - glDisable( GL_SCISSOR_TEST ); - + glDisable(GL_SCISSOR_TEST); // Draw a border around the active view - if( active_view > 0 && active_view != 2 ) + if (active_view > 0 && active_view != 2) { - glViewport( 0, 0, width, height ); - glMatrixMode( GL_PROJECTION ); + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho( 0.0, 2.0, 0.0, 2.0, 0.0, 1.0 ); - glMatrixMode( GL_MODELVIEW ); + glOrtho(0.0, 2.0, 0.0, 2.0, 0.0, 1.0); + + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glColor3f( 1.0f, 1.0f, 0.6f ); - glTranslatef( (GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f ); - glBegin( GL_LINE_STRIP ); - glVertex2i( 0, 0 ); - glVertex2i( 1, 0 ); - glVertex2i( 1, 1 ); - glVertex2i( 0, 1 ); - glVertex2i( 0, 0 ); + glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f); + + glColor3f(1.0f, 1.0f, 0.6f); + + glBegin(GL_LINE_STRIP); + glVertex2i(0, 0); + glVertex2i(1, 0); + glVertex2i(1, 1); + glVertex2i(0, 1); + glVertex2i(0, 0); glEnd(); } } @@ -357,7 +355,7 @@ static void drawAllViews( void ) // Window size callback function //======================================================================== -static void windowSizeFun( GLFWwindow window, int w, int h ) +static void windowSizeFun(GLFWwindow window, int w, int h) { width = w; height = h > 0 ? h : 1; @@ -369,7 +367,7 @@ static void windowSizeFun( GLFWwindow window, int w, int h ) // Window refresh callback function //======================================================================== -static void windowRefreshFun( GLFWwindow window ) +static void windowRefreshFun(GLFWwindow window) { do_redraw = 1; } @@ -379,10 +377,10 @@ static void windowRefreshFun( GLFWwindow window ) // Mouse position callback function //======================================================================== -static void mousePosFun( GLFWwindow window, int x, int y ) +static void mousePosFun(GLFWwindow window, int x, int y) { // Depending on which view was selected, rotate around different axes - switch( active_view ) + switch (active_view) { case 1: rot_x += y - ypos; @@ -414,25 +412,18 @@ static void mousePosFun( GLFWwindow window, int x, int y ) // Mouse button callback function //======================================================================== -static void mouseButtonFun( GLFWwindow window, int button, int action ) +static void mouseButtonFun(GLFWwindow window, int button, int action) { - // Button clicked? - if( ( button == GLFW_MOUSE_BUTTON_LEFT ) && action == GLFW_PRESS ) + if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS) { // Detect which of the four views was clicked active_view = 1; - if( xpos >= width/2 ) - { + if (xpos >= width / 2) active_view += 1; - } - if( ypos >= height/2 ) - { + if (ypos >= height / 2) active_view += 2; - } } - - // Button released? - else if( button == GLFW_MOUSE_BUTTON_LEFT ) + else if (button == GLFW_MOUSE_BUTTON_LEFT) { // Deselect any previously selected view active_view = 0; @@ -443,51 +434,50 @@ static void mouseButtonFun( GLFWwindow window, int button, int action ) //======================================================================== -// main() +// main //======================================================================== -int main( void ) +int main(void) { GLFWwindow window; // Initialise GLFW - if( !glfwInit() ) + if (!glfwInit()) { - fprintf( stderr, "Failed to initialize GLFW\n" ); - exit( EXIT_FAILURE ); + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); } glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); // Open OpenGL window - window = glfwOpenWindow( 500, 500, GLFW_WINDOWED, "Split view demo", NULL ); + window = glfwOpenWindow(500, 500, GLFW_WINDOWED, "Split view demo", NULL); if (!window) { - fprintf( stderr, "Failed to open GLFW window\n" ); - glfwTerminate(); - exit( EXIT_FAILURE ); + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); } // Enable vsync - glfwSwapInterval( 1 ); + glfwSwapInterval(1); // Enable sticky keys - glfwEnable( window, GLFW_STICKY_KEYS ); + glfwEnable(window, GLFW_STICKY_KEYS); // Enable mouse cursor (only needed for fullscreen mode) - glfwEnable( window, GLFW_MOUSE_CURSOR ); + glfwEnable(window, GLFW_MOUSE_CURSOR); // Set callback functions - glfwSetWindowSizeCallback( window, windowSizeFun ); - glfwSetWindowRefreshCallback( window, windowRefreshFun ); - glfwSetMousePosCallback( window, mousePosFun ); - glfwSetMouseButtonCallback( window, mouseButtonFun ); + glfwSetWindowSizeCallback(window, windowSizeFun); + glfwSetWindowRefreshCallback(window, windowRefreshFun); + glfwSetMousePosCallback(window, mousePosFun); + glfwSetMouseButtonCallback(window, mouseButtonFun); // Main loop do { // Only redraw if we need to - if( do_redraw ) + if (do_redraw) { // Draw all views drawAllViews(); @@ -502,12 +492,12 @@ int main( void ) glfwWaitEvents(); } // Check if the ESC key was pressed or the window was closed - while( glfwIsWindow(window) && - glfwGetKey(window, GLFW_KEY_ESC) != GLFW_PRESS ); + while (glfwIsWindow(window) && + glfwGetKey(window, GLFW_KEY_ESC) != GLFW_PRESS); // Close OpenGL window and terminate GLFW glfwTerminate(); - exit( EXIT_SUCCESS ); + exit(EXIT_SUCCESS); } From 8f78d5df3ae48cc797fcad53ae1fd5efe7ec64e2 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 14:58:29 +0200 Subject: [PATCH 10/22] Removed legacy example. --- examples/mipmaps.c | 122 ------------------------------------------- examples/mipmaps.tga | Bin 66322 -> 0 bytes 2 files changed, 122 deletions(-) delete mode 100644 examples/mipmaps.c delete mode 100644 examples/mipmaps.tga diff --git a/examples/mipmaps.c b/examples/mipmaps.c deleted file mode 100644 index 59bbef2e..00000000 --- a/examples/mipmaps.c +++ /dev/null @@ -1,122 +0,0 @@ -//======================================================================== -// This is an example program for the GLFW library -// -// It shows texture loading with mipmap generation and rendering with -// trilienar texture filtering -//======================================================================== - -#include -#include - -#include - -int main( void ) -{ - int width, height, x; - double time; - GLboolean running; - GLuint textureID; - char* texturePath = "mipmaps.tga"; - - // Initialise GLFW - if( !glfwInit() ) - { - fprintf( stderr, "Failed to initialize GLFW\n" ); - exit( EXIT_FAILURE ); - } - - // Open OpenGL window - if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_WINDOW ) ) - { - fprintf( stderr, "Failed to open GLFW window\n" ); - glfwTerminate(); - exit( EXIT_FAILURE ); - } - - glfwSetWindowTitle( "Trilinear interpolation" ); - - // Enable sticky keys - glfwEnable( GLFW_STICKY_KEYS ); - - // Enable vertical sync (on cards that support it) - glfwSwapInterval( 1 ); - - // Generate and bind our texture ID - glGenTextures( 1, &textureID ); - glBindTexture( GL_TEXTURE_2D, textureID ); - - // Load texture from file into video memory, including mipmap levels - if( !glfwLoadTexture2D( texturePath, GLFW_BUILD_MIPMAPS_BIT ) ) - { - fprintf( stderr, "Failed to load texture %s\n", texturePath ); - glfwTerminate(); - exit( EXIT_FAILURE ); - } - - // Use trilinear interpolation (GL_LINEAR_MIPMAP_LINEAR) - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_LINEAR ); - - // Enable plain 2D texturing - glEnable( GL_TEXTURE_2D ); - - running = GL_TRUE; - while( running ) - { - // Get time and mouse position - time = glfwGetTime(); - glfwGetMousePos( &x, NULL ); - - // Get window size (may be different than the requested size) - glfwGetWindowSize( &width, &height ); - height = height > 0 ? height : 1; - - // Set viewport - glViewport( 0, 0, width, height ); - - // Clear color buffer - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f); - glClear( GL_COLOR_BUFFER_BIT ); - - // Select and setup the projection matrix - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - gluPerspective( 65.0f, (GLfloat)width / (GLfloat)height, 1.0f, - 50.0f ); - - // Select and setup the modelview matrix - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - gluLookAt( 0.0f, 3.0f, -20.0f, // Eye-position - 0.0f, -4.0f, -11.0f, // View-point - 0.0f, 1.0f, 0.0f ); // Up-vector - - // Draw a textured quad - glRotatef( 0.05f * (GLfloat)x + (GLfloat)time * 5.0f, 0.0f, 1.0f, 0.0f ); - glBegin( GL_QUADS ); - glTexCoord2f( -20.0f, 20.0f ); - glVertex3f( -50.0f, 0.0f, -50.0f ); - glTexCoord2f( 20.0f, 20.0f ); - glVertex3f( 50.0f, 0.0f, -50.0f ); - glTexCoord2f( 20.0f, -20.0f ); - glVertex3f( 50.0f, 0.0f, 50.0f ); - glTexCoord2f( -20.0f, -20.0f ); - glVertex3f( -50.0f, 0.0f, 50.0f ); - glEnd(); - - // Swap buffers - glfwSwapBuffers(); - - // Check if the ESC key was pressed or the window was closed - running = !glfwGetKey( GLFW_KEY_ESC ) && - glfwGetWindowParam( GLFW_OPENED ); - } - - // Close OpenGL window and terminate GLFW - glfwTerminate(); - - exit( EXIT_SUCCESS ); -} - diff --git a/examples/mipmaps.tga b/examples/mipmaps.tga deleted file mode 100644 index 55f913b0fa48f69b163664da1db6f9b1fe80e2ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66322 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 Date: Sun, 24 Oct 2010 15:02:59 +0200 Subject: [PATCH 11/22] Formatting. --- examples/triangle.c | 68 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/examples/triangle.c b/examples/triangle.c index 5e1e2423..ea1fcdd0 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -9,74 +9,72 @@ #include -int main( void ) +int main(void) { int width, height, x; - double t; GLFWwindow window; // Initialise GLFW - if( !glfwInit() ) + if (!glfwInit()) { - fprintf( stderr, "Failed to initialize GLFW\n" ); - exit( EXIT_FAILURE ); + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); } // Open a window and create its OpenGL context - window = glfwOpenWindow( 640, 480, GLFW_WINDOWED, "Spinning Triangle", NULL ); + window = glfwOpenWindow(640, 480, GLFW_WINDOWED, "Spinning Triangle", NULL); if (!window) { - fprintf( stderr, "Failed to open GLFW window\n" ); - - glfwTerminate(); - exit( EXIT_FAILURE ); + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); } // Ensure we can capture the escape key being pressed below - glfwEnable( window, GLFW_STICKY_KEYS ); + glfwEnable(window, GLFW_STICKY_KEYS); // Enable vertical sync (on cards that support it) - glfwSwapInterval( 1 ); + glfwSwapInterval(1); do { - t = glfwGetTime(); - glfwGetMousePos( window, &x, NULL ); + double t = glfwGetTime(); + glfwGetMousePos(window, &x, NULL); // Get window size (may be different than the requested size) - glfwGetWindowSize( window, &width, &height ); + glfwGetWindowSize(window, &width, &height); // Special case: avoid division by zero below height = height > 0 ? height : 1; - glViewport( 0, 0, width, height ); + glViewport(0, 0, width, height); // Clear color buffer to black - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - glClear( GL_COLOR_BUFFER_BIT ); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); // Select and setup the projection matrix - glMatrixMode( GL_PROJECTION ); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective( 65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f ); + gluPerspective(65.0f, (GLfloat)width/(GLfloat)height, 1.f, 100.0f); // Select and setup the modelview matrix glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); - gluLookAt( 0.0f, 1.0f, 0.0f, // Eye-position - 0.0f, 20.0f, 0.0f, // View-point - 0.0f, 0.0f, 1.0f ); // Up-vector + gluLookAt(0.f, 1.f, 0.f, // Eye-position + 0.f, 20.f, 0.f, // View-point + 0.f, 0.f, 1.f); // Up-vector // Draw a rotating colorful triangle - glTranslatef( 0.0f, 14.0f, 0.0f ); - glRotatef( 0.3f*(GLfloat)x + (GLfloat)t*100.0f, 0.0f, 0.0f, 1.0f ); - glBegin( GL_TRIANGLES ); - glColor3f( 1.0f, 0.0f, 0.0f ); - glVertex3f( -5.0f, 0.0f, -4.0f ); - glColor3f( 0.0f, 1.0f, 0.0f ); - glVertex3f( 5.0f, 0.0f, -4.0f ); - glColor3f( 0.0f, 0.0f, 1.0f ); - glVertex3f( 0.0f, 0.0f, 6.0f ); + glTranslatef(0.f, 14.f, 0.f); + glRotatef(0.3f * (GLfloat) x + (GLfloat) t * 100.f, 0.f, 0.f, 1.f); + + glBegin(GL_TRIANGLES); + glColor3f(1.f, 0.f, 0.f); + glVertex3f(-5.f, 0.f, -4.f); + glColor3f(0.f, 1.f, 0.f); + glVertex3f(5.f, 0.f, -4.f); + glColor3f(0.f, 0.f, 1.f); + glVertex3f(0.f, 0.f, 6.f); glEnd(); // Swap buffers @@ -84,12 +82,12 @@ int main( void ) glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed - while( glfwIsWindow(window) && - glfwGetKey( window, GLFW_KEY_ESC ) != GLFW_PRESS ); + while (glfwIsWindow(window) && + glfwGetKey(window, GLFW_KEY_ESC) != GLFW_PRESS); // Close OpenGL window and terminate GLFW glfwTerminate(); - exit( EXIT_SUCCESS ); + exit(EXIT_SUCCESS); } From 7968b710c355eb5615ad5536455dfb8f360c6085 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:03:29 +0200 Subject: [PATCH 12/22] Formatting. --- examples/triangle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/triangle.c b/examples/triangle.c index ea1fcdd0..fd88d4c6 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -55,7 +55,7 @@ int main(void) // Select and setup the projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(65.0f, (GLfloat)width/(GLfloat)height, 1.f, 100.0f); + gluPerspective(65.f, (GLfloat) width / (GLfloat) height, 1.f, 100.f); // Select and setup the modelview matrix glMatrixMode( GL_MODELVIEW ); From 9c27d52b2e2fd6c1f4ca9657dc3ef90014fb76d6 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:04:17 +0200 Subject: [PATCH 13/22] Formatting. --- examples/triangle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/triangle.c b/examples/triangle.c index fd88d4c6..31438813 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -6,8 +6,8 @@ #include #include -#include +#include int main(void) { From b9f318f0538cf4b44a53e5b5ba33a7df97d35422 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:37:51 +0200 Subject: [PATCH 14/22] Formatting. --- examples/wave.c | 518 +++++++++++++++++++++++------------------------- 1 file changed, 253 insertions(+), 265 deletions(-) diff --git a/examples/wave.c b/examples/wave.c index 2c81abc8..97783d0d 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -22,27 +22,26 @@ /* Animation speed (10.0 looks good) */ #define ANIMATION_SPEED 10.0 +GLfloat alpha = 210.f, beta = -70.f; +GLfloat zoom = 2.f; -GLfloat alpha = 210.0f, beta = -70.0f; -GLfloat zoom = 2.0f; - -int running = 1; +GLboolean running = GL_TRUE; struct Vertex { - GLfloat x,y,z; - GLfloat r,g,b; + GLfloat x, y, z; + GLfloat r, g, b; }; #define GRIDW 50 #define GRIDH 50 #define VERTEXNUM (GRIDW*GRIDH) -#define QUADW (GRIDW-1) -#define QUADH (GRIDH-1) +#define QUADW (GRIDW - 1) +#define QUADH (GRIDH - 1) #define QUADNUM (QUADW*QUADH) -GLuint quad[4*QUADNUM]; +GLuint quad[4 * QUADNUM]; struct Vertex vertex[VERTEXNUM]; /* The grid will look like this: @@ -56,47 +55,47 @@ struct Vertex vertex[VERTEXNUM]; * 0 1 2 */ -void initVertices( void ) +//======================================================================== +// Initialize grid geometry +//======================================================================== + +void init_vertices(void) { - int x,y,p; + int x, y, p; - /* place the vertices in a grid */ - for(y=0;y1) zoom-=1; - break; - case GLFW_KEY_PAGEDOWN: - zoom+=1; - break; - default: - break; - } + switch (key) + { + case GLFW_KEY_ESC: + running = 0; + break; + case GLFW_KEY_SPACE: + init_grid(); + break; + case GLFW_KEY_LEFT: + alpha += 5; + break; + case GLFW_KEY_RIGHT: + alpha -= 5; + break; + case GLFW_KEY_UP: + beta -= 5; + break; + case GLFW_KEY_DOWN: + beta += 5; + break; + case GLFW_KEY_PAGEUP: + if (zoom > 1) + zoom -= 1; + break; + case GLFW_KEY_PAGEDOWN: + zoom+=1; + break; + default: + break; + } } -/* Callback function for window resize events */ -void handle_resize( GLFWwindow window, int width, int height ) +//======================================================================== +// Callback function for window resize events +//======================================================================== + +void handle_resize(GLFWwindow window, int width, int height) { - float ratio = 1.0f; + float ratio = 1.f; - if( height > 0 ) - { - ratio = (float) width / (float) height; - } + if (height > 0) + ratio = (float) width / (float) height; - /* Setup viewport (Place where the stuff will appear in the main window). */ - glViewport(0, 0, width, height); + // Setup viewport + glViewport(0, 0, width, height); - /* - * Change to the projection matrix and set - * our viewing volume. - */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(60.0, ratio, 1.0, 1024.0); + // Change to the projection matrix and set our viewing volume + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, ratio, 1.0, 1024.0); } -/* Program entry point */ +//======================================================================== +// main +//======================================================================== + int main(int argc, char* argv[]) { - /* Dimensions of our window. */ - int width, height; - /* Style of our window. */ - int mode; - /* Frame time */ - double t, t_old, dt_total; - GLFWwindow window; + GLFWwindow window; + double t, dt_total, t_old; - /* Initialize GLFW */ - if(glfwInit() == GL_FALSE) - { - fprintf(stderr, "GLFW initialization failed\n"); - exit(-1); - } - - /* Desired window properties */ - width = 640; - height = 480; - mode = GLFW_WINDOWED; - - glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); - - /* Open window */ - window = glfwOpenWindow(width, height, mode, "Wave Simulation", NULL); - if (!window) - { - fprintf(stderr, "Could not open window\n"); - glfwTerminate(); - exit(-1); - } - - glfwSwapInterval( 1 ); - - /* Keyboard handler */ - glfwSetKeyCallback( window, handle_key_down ); - glfwEnable( window, GLFW_KEY_REPEAT ); - - /* Window resize handler */ - glfwSetWindowSizeCallback( window, handle_resize ); - - /* Initialize OpenGL */ - setup_opengl(); - - /* Initialize simulation */ - initVertices(); - initSurface(); - adjustGrid(); - - /* Initialize timer */ - t_old = glfwGetTime() - 0.01; - - /* Main loop */ - while(running) - { - /* Timing */ - t = glfwGetTime(); - dt_total = t - t_old; - t_old = t; - - /* Safety - iterate if dt_total is too large */ - while( dt_total > 0.0f ) + if (!glfwInit()) { - /* Select iteration time step */ - dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; - dt_total -= dt; - - /* Calculate wave propagation */ - calc(); + fprintf(stderr, "GLFW initialization failed\n"); + exit(EXIT_FAILURE); } - /* Compute height of each vertex */ - adjustGrid(); + window = glfwOpenWindow(640, 480, GLFW_WINDOWED, "Wave Simulation", NULL); + if (!window) + { + fprintf(stderr, "Could not open window\n"); + exit(EXIT_FAILURE); + } - /* Draw wave grid to OpenGL display */ - draw_screen(); + glfwSwapInterval(1); - glfwPollEvents(); + // Keyboard handler + glfwSetKeyCallback(window, handle_key_down); + glfwEnable(window, GLFW_KEY_REPEAT); - /* Still running? */ - running = running && glfwIsWindow( window ); - } + // Window resize handler + glfwSetWindowSizeCallback(window, handle_resize); - glfwTerminate(); + // Initialize OpenGL + init_opengl(); - return 0; + // Initialize simulation + init_vertices(); + init_grid(); + adjust_grid(); + + // Initialize timer + t_old = glfwGetTime() - 0.01; + + while (running) + { + t = glfwGetTime(); + dt_total = t - t_old; + t_old = t; + + // Safety - iterate if dt_total is too large + while (dt_total > 0.f) + { + // Select iteration time step + dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; + dt_total -= dt; + + // Calculate wave propagation + calc_grid(); + } + + // Compute height of each vertex + adjust_grid(); + + // Draw wave grid to OpenGL display + draw_scene(); + + glfwPollEvents(); + + // Still running? + running = running && glfwIsWindow(window); + } + + exit(EXIT_SUCCESS); } + From cb35f0ceda5d60cbdd0ab9aa149c5e2606c23ee3 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:38:59 +0200 Subject: [PATCH 15/22] Added change notice. --- examples/wave.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/wave.c b/examples/wave.c index 97783d0d..f465bc6d 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -5,6 +5,7 @@ * Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com * Modified for variable frame rate by Marcus Geelnard * 2003-Jan-31: Minor cleanups and speedups / MG + * 2010-10-24: Formatting and cleanup - Camilla Berglund *****************************************************************************/ #include From 64abfb5ece45e0b776d024a802332426ca597464 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:40:57 +0200 Subject: [PATCH 16/22] Formatting. --- examples/wave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wave.c b/examples/wave.c index f465bc6d..e0333cd1 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -123,8 +123,8 @@ void init_grid(void) d = sqrt(dx * dx + dy * dy); if (d < 0.1 * (double) (GRIDW / 2)) { - d = d * 10.0; - p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0; + d = d * 10.0; + p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0; } else p[x][y] = 0.0; From 868176721c34eba5d266d3ac1a730a53e0e89a48 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:42:07 +0200 Subject: [PATCH 17/22] Formatting. --- examples/wave.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/wave.c b/examples/wave.c index e0333cd1..f328a59c 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -17,10 +17,10 @@ #define M_PI 3.1415926535897932384626433832795 #endif -/* Maximum delta T to allow for differential calculations */ +// Maximum delta T to allow for differential calculations #define MAX_DELTA_T 0.01 -/* Animation speed (10.0 looks good) */ +// Animation speed (10.0 looks good) #define ANIMATION_SPEED 10.0 GLfloat alpha = 210.f, beta = -70.f; @@ -91,7 +91,6 @@ void init_vertices(void) { p = 4 * (y * QUADW + x); - /* first quad */ quad[p + 0] = y * GRIDW + x; // Some point quad[p + 1] = y * GRIDW + x + 1; // Neighbor at the right side quad[p + 2] = (y + 1) * GRIDW + x + 1; // Upper right neighbor @@ -286,7 +285,7 @@ void handle_key_down(GLFWwindow window, int key, int action) zoom -= 1; break; case GLFW_KEY_PAGEDOWN: - zoom+=1; + zoom += 1; break; default: break; From 1231bf031bb13882db28ed237c24241acfa90d66 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 15:50:39 +0200 Subject: [PATCH 18/22] Formatting. --- examples/wave.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/wave.c b/examples/wave.c index f328a59c..f38a1ee4 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -255,7 +255,7 @@ void calc_grid(void) // Handle key strokes //======================================================================== -void handle_key_down(GLFWwindow window, int key, int action) +void key_callback(GLFWwindow window, int key, int action) { if (action != GLFW_PRESS) return; @@ -297,7 +297,7 @@ void handle_key_down(GLFWwindow window, int key, int action) // Callback function for window resize events //======================================================================== -void handle_resize(GLFWwindow window, int width, int height) +void window_resize_callback(GLFWwindow window, int width, int height) { float ratio = 1.f; @@ -339,11 +339,11 @@ int main(int argc, char* argv[]) glfwSwapInterval(1); // Keyboard handler - glfwSetKeyCallback(window, handle_key_down); + glfwSetKeyCallback(window, key_callback); glfwEnable(window, GLFW_KEY_REPEAT); // Window resize handler - glfwSetWindowSizeCallback(window, handle_resize); + glfwSetWindowSizeCallback(window, window_resize_callback); // Initialize OpenGL init_opengl(); From e0827195a45689509ba8a047b78e93ee29ffa7c8 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 16:07:02 +0200 Subject: [PATCH 19/22] Clarified gamma ramp error message. --- src/x11/x11_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index 62f02eee..8f310e72 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -176,7 +176,7 @@ static void initGammaRamp(void) #endif /*_GLFW_HAS_XF86VIDMODE*/ if (!_glfwLibrary.originalRampSize) - fprintf(stderr, "Gamma ramp setting unsupported\n"); + fprintf(stderr, "No supported gamma ramp API found\n"); // Save the original gamma ramp _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); From dae61bb9180f235a968d99f8a6fd739010b5ae36 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 16:16:21 +0200 Subject: [PATCH 20/22] Added TODO. --- src/x11/x11_gamma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x11/x11_gamma.c b/src/x11/x11_gamma.c index f80fc917..9850acc2 100644 --- a/src/x11/x11_gamma.c +++ b/src/x11/x11_gamma.c @@ -55,6 +55,8 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfwLibrary.X11.display, rr->crtcs[0]); + // TODO: Handle case of original ramp size having a size other than 256 + memcpy(ramp->red, gamma->red, size); memcpy(ramp->green, gamma->green, size); memcpy(ramp->blue, gamma->blue, size); From c5892fee53c05e6df1f91ae66addb7c42a67bb32 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 18:09:05 +0200 Subject: [PATCH 21/22] Formatting. --- src/x11/x11_gamma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/x11/x11_gamma.c b/src/x11/x11_gamma.c index 9850acc2..e4424867 100644 --- a/src/x11/x11_gamma.c +++ b/src/x11/x11_gamma.c @@ -33,9 +33,9 @@ #include -//************************************************************************ -//**** GLFW internal functions **** -//************************************************************************ +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// //======================================================================== // Save the original gamma ramp so that we can restore it later From 4044c2da66c5183e6ef224d5d51610adfeed0a0d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 24 Oct 2010 18:28:55 +0200 Subject: [PATCH 22/22] Made callbacks library global. --- examples/boing.c | 2 +- examples/gears.c | 4 +-- examples/heightmap.c | 4 +-- examples/splitview.c | 8 +++--- examples/wave.c | 4 +-- include/GL/glfw3.h | 20 +++++++-------- src/cocoa/cocoa_window.m | 16 ++++++------ src/enable.c | 8 +++--- src/input.c | 32 +++++++++++------------ src/internal.h | 23 ++++++++--------- src/win32/win32_window.c | 22 ++++++++-------- src/window.c | 55 ++++++++++++++++++++++------------------ src/x11/x11_window.c | 28 ++++++++++---------- tests/accuracy.c | 4 +-- tests/events.c | 20 +++++++-------- tests/fsaa.c | 2 +- tests/fsfocus.c | 6 ++--- tests/gamma.c | 4 +-- tests/iconify.c | 4 +-- tests/peter.c | 6 ++--- tests/reopen.c | 6 ++--- tests/sharing.c | 2 +- tests/tearing.c | 2 +- 23 files changed, 143 insertions(+), 139 deletions(-) diff --git a/examples/boing.c b/examples/boing.c index 007f3f0f..b90f3732 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -585,7 +585,7 @@ int main( void ) exit( EXIT_FAILURE ); } - glfwSetWindowSizeCallback( window, reshape ); + glfwSetWindowSizeCallback( reshape ); glfwEnable( window, GLFW_STICKY_KEYS ); glfwSwapInterval( 1 ); glfwSetTime( 0.0 ); diff --git a/examples/gears.c b/examples/gears.c index 1c2b209c..7271cf64 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -346,8 +346,8 @@ int main(int argc, char *argv[]) init(argc, argv); // Set callback functions - glfwSetWindowSizeCallback( window, reshape ); - glfwSetKeyCallback( window, key ); + glfwSetWindowSizeCallback( reshape ); + glfwSetKeyCallback( key ); // Main loop while( running ) diff --git a/examples/heightmap.c b/examples/heightmap.c index b5f2fdbc..4f8c1c0a 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c @@ -597,8 +597,8 @@ int main(int argc, char** argv) free(fragment_shader_src); exit(EXIT_FAILURE); } - glfwSetWindowCloseCallback(window, window_close_callback); - glfwSetKeyCallback(window, key_callback); + glfwSetWindowCloseCallback(window_close_callback); + glfwSetKeyCallback(key_callback); /* Register events callback */ if (GL_TRUE != init_opengl()) diff --git a/examples/splitview.c b/examples/splitview.c index 42c5ec16..d05b078c 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -468,10 +468,10 @@ int main(void) glfwEnable(window, GLFW_MOUSE_CURSOR); // Set callback functions - glfwSetWindowSizeCallback(window, windowSizeFun); - glfwSetWindowRefreshCallback(window, windowRefreshFun); - glfwSetMousePosCallback(window, mousePosFun); - glfwSetMouseButtonCallback(window, mouseButtonFun); + glfwSetWindowSizeCallback(windowSizeFun); + glfwSetWindowRefreshCallback(windowRefreshFun); + glfwSetMousePosCallback(mousePosFun); + glfwSetMouseButtonCallback(mouseButtonFun); // Main loop do diff --git a/examples/wave.c b/examples/wave.c index f38a1ee4..49bf1a68 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -339,11 +339,11 @@ int main(int argc, char* argv[]) glfwSwapInterval(1); // Keyboard handler - glfwSetKeyCallback(window, key_callback); + glfwSetKeyCallback(key_callback); glfwEnable(window, GLFW_KEY_REPEAT); // Window resize handler - glfwSetWindowSizeCallback(window, window_resize_callback); + glfwSetWindowSizeCallback(window_resize_callback); // Initialize OpenGL init_opengl(); diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 08e0d006..e2316413 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -442,11 +442,11 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow window); GLFWAPI int glfwGetWindowParam(GLFWwindow window, int param); GLFWAPI void glfwSetWindowUserPointer(GLFWwindow window, void* pointer); GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow window); -GLFWAPI void glfwSetWindowSizeCallback(GLFWwindow window, GLFWwindowsizefun cbfun); -GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cbfun); -GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfun cbfun); -GLFWAPI void glfwSetWindowFocusCallback(GLFWwindow window, GLFWwindowfocusfun cbfun); -GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindow window, GLFWwindowiconifyfun cbfun); +GLFWAPI void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun); +GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun); +GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun); +GLFWAPI void glfwSetWindowFocusCallback(GLFWwindowfocusfun cbfun); +GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindowiconifyfun cbfun); /* Event handling */ GLFWAPI void glfwPollEvents(void); @@ -458,11 +458,11 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button); GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos); GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos); GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* x, int* y); -GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun); -GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun); -GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cbfun); -GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun); -GLFWAPI void glfwSetScrollCallback(GLFWwindow window, GLFWscrollfun cbfun); +GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun); +GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun); +GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun); +GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun); +GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun); /* Joystick input */ GLFWAPI int glfwGetJoystickParam(int joy, int param); diff --git a/src/cocoa/cocoa_window.m b/src/cocoa/cocoa_window.m index eeb1a13a..2b389e4d 100644 --- a/src/cocoa/cocoa_window.m +++ b/src/cocoa/cocoa_window.m @@ -70,8 +70,8 @@ window->width = contentRect.size.width; window->height = contentRect.size.height; - if (window->windowSizeCallback) - window->windowSizeCallback(window, window->width, window->height); + if (_glfwLibrary.windowSizeCallback) + _glfwLibrary.windowSizeCallback(window, window->width, window->height); } - (void)windowDidMove:(NSNotification *)notification @@ -95,16 +95,16 @@ { window->iconified = GL_TRUE; - if (window->windowIconifyCallback) - window->windowIconifyCallback(window, window->iconified); + if (_glfwLibrary.windowIconifyCallback) + _glfwLibrary.windowIconifyCallback(window, window->iconified); } - (void)windowDidDeminiaturize:(NSNotification *)notification { window->iconified = GL_FALSE; - if (window->windowIconifyCallback) - window->windowIconifyCallback(window, window->iconified); + if (_glfwLibrary.windowIconifyCallback) + _glfwLibrary.windowIconifyCallback(window, window->iconified); } - (void)windowDidBecomeKey:(NSNotification *)notification @@ -362,8 +362,8 @@ static int convertMacKeyCode(unsigned int macKeyCode) window->mousePosY = [[window->NS.window contentView] bounds].size.height - p.y; } - if (window->mousePosCallback) - window->mousePosCallback(window, window->mousePosX, window->mousePosY); + if (_glfwLibrary.mousePosCallback) + _glfwLibrary.mousePosCallback(window, window->mousePosX, window->mousePosY); } - (void)rightMouseDown:(NSEvent *)event diff --git a/src/enable.c b/src/enable.c index 7a8534a1..60789290 100644 --- a/src/enable.c +++ b/src/enable.c @@ -54,11 +54,11 @@ static void enableMouseCursor(_GLFWwindow* window) window->mousePosX = centerPosX; window->mousePosY = centerPosY; - if (window->mousePosCallback) + if (_glfwLibrary.mousePosCallback) { - window->mousePosCallback(window, - window->mousePosX, - window->mousePosY); + _glfwLibrary.mousePosCallback(window, + window->mousePosX, + window->mousePosY); } } diff --git a/src/input.c b/src/input.c index c5ad0c7b..8a61fbef 100644 --- a/src/input.c +++ b/src/input.c @@ -171,7 +171,7 @@ GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* x, int* y) // Set callback function for keyboard input //======================================================================== -GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun) +GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun) { if (!_glfwInitialized) { @@ -179,7 +179,7 @@ GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun) return; } - window->keyCallback = cbfun; + _glfwLibrary.keyCallback = cbfun; } @@ -187,7 +187,7 @@ GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun) // Set callback function for character input //======================================================================== -GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun) +GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun) { if (!_glfwInitialized) { @@ -195,7 +195,7 @@ GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun) return; } - window->charCallback = cbfun; + _glfwLibrary.charCallback = cbfun; } @@ -203,7 +203,7 @@ GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun) // Set callback function for mouse clicks //======================================================================== -GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cbfun) +GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun) { if (!_glfwInitialized) { @@ -211,7 +211,7 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cb return; } - window->mouseButtonCallback = cbfun; + _glfwLibrary.mouseButtonCallback = cbfun; } @@ -219,7 +219,7 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cb // Set callback function for mouse moves //======================================================================== -GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun) +GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) { if (!_glfwInitialized) { @@ -228,12 +228,17 @@ GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun) } // Set callback function - window->mousePosCallback = cbfun; + _glfwLibrary.mousePosCallback = cbfun; // Call the callback function to let the application know the current // mouse position if (cbfun) - cbfun(window, window->mousePosX, window->mousePosY); + { + _GLFWwindow* window; + + for (window = _glfwLibrary.windowListHead; window; window = window->next) + cbfun(window, window->mousePosX, window->mousePosY); + } } @@ -241,7 +246,7 @@ GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun) // Set callback function for scroll events //======================================================================== -GLFWAPI void glfwSetScrollCallback(GLFWwindow window, GLFWscrollfun cbfun) +GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun) { if (!_glfwInitialized) { @@ -250,11 +255,6 @@ GLFWAPI void glfwSetScrollCallback(GLFWwindow window, GLFWscrollfun cbfun) } // Set callback function - window->scrollCallback = cbfun; - - // Call the callback function to let the application know the current - // scroll offset - if (cbfun) - cbfun(window, window->scrollX, window->scrollY); + _glfwLibrary.scrollCallback = cbfun; } diff --git a/src/internal.h b/src/internal.h index a44ab51a..b064ebb5 100644 --- a/src/internal.h +++ b/src/internal.h @@ -152,18 +152,6 @@ struct _GLFWwindow { struct _GLFWwindow* next; - // User callback functions - GLFWwindowsizefun windowSizeCallback; - GLFWwindowclosefun windowCloseCallback; - GLFWwindowrefreshfun windowRefreshCallback; - GLFWwindowfocusfun windowFocusCallback; - GLFWwindowiconifyfun windowIconifyCallback; - GLFWmousebuttonfun mouseButtonCallback; - GLFWmouseposfun mousePosCallback; - GLFWscrollfun scrollCallback; - GLFWkeyfun keyCallback; - GLFWcharfun charCallback; - // Window settings and state GLboolean iconified; // GL_TRUE if this window is iconified GLboolean closeRequested; // GL_TRUE if this window should be closed @@ -223,6 +211,17 @@ struct _GLFWlibrary _GLFWwindow* activeWindow; _GLFWwindow* cursorLockWindow; + GLFWwindowsizefun windowSizeCallback; + GLFWwindowclosefun windowCloseCallback; + GLFWwindowrefreshfun windowRefreshCallback; + GLFWwindowfocusfun windowFocusCallback; + GLFWwindowiconifyfun windowIconifyCallback; + GLFWmousebuttonfun mouseButtonCallback; + GLFWmouseposfun mousePosCallback; + GLFWscrollfun scrollCallback; + GLFWkeyfun keyCallback; + GLFWcharfun charCallback; + GLFWgammaramp currentRamp; GLFWgammaramp originalRamp; int originalRampSize; diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c index 059faa4b..07ae49d1 100644 --- a/src/win32/win32_window.c +++ b/src/win32/win32_window.c @@ -713,8 +713,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { window->iconified = iconified; - if (window->windowIconifyCallback) - window->windowIconifyCallback(window, window->iconified); + if (_glfwLibrary.windowIconifyCallback) + _glfwLibrary.windowIconifyCallback(window, window->iconified); } return 0; @@ -756,7 +756,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { _glfwInputKey(window, translateKey(wParam, lParam), GLFW_PRESS); - if (window->charCallback) + if (_glfwLibrary.charCallback) translateChar(window, (DWORD) wParam, (DWORD) lParam); return 0; @@ -879,11 +879,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, window->Win32.oldMouseY = newMouseY; window->Win32.mouseMoved = GL_TRUE; - if (window->mousePosCallback) + if (_glfwLibrary.mousePosCallback) { - window->mousePosCallback(window, - window->mousePosX, - window->mousePosY); + _glfwLibrary.mousePosCallback(window, + window->mousePosX, + window->mousePosY); } } @@ -917,8 +917,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, ClipCursor(&ClipWindowRect); } - if (window->windowSizeCallback) - window->windowSizeCallback(window, window->width, window->height); + if (_glfwLibrary.windowSizeCallback) + _glfwLibrary.windowSizeCallback(window, window->width, window->height); return 0; } @@ -941,8 +941,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // Was the window contents damaged? case WM_PAINT: { - if (window->windowRefreshCallback) - window->windowRefreshCallback(window); + if (_glfwLibrary.windowRefreshCallback) + _glfwLibrary.windowRefreshCallback(window); break; } diff --git a/src/window.c b/src/window.c index 14b0c4dc..8b4a7903 100644 --- a/src/window.c +++ b/src/window.c @@ -55,8 +55,8 @@ static void closeFlaggedWindows(void) for (window = _glfwLibrary.windowListHead; window; ) { - if (window->closeRequested && window->windowCloseCallback) - window->closeRequested = window->windowCloseCallback(window); + if (window->closeRequested && _glfwLibrary.windowCloseCallback) + window->closeRequested = _glfwLibrary.windowCloseCallback(window); if (window->closeRequested) { @@ -144,8 +144,8 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) } // Call user callback function - if (window->keyCallback && (window->keyRepeat || !keyrepeat)) - window->keyCallback(window, key, action); + if (_glfwLibrary.keyCallback && (window->keyRepeat || !keyrepeat)) + _glfwLibrary.keyCallback(window, key, action); } @@ -159,8 +159,8 @@ void _glfwInputChar(_GLFWwindow* window, int character) if (!((character >= 32 && character <= 126) || character >= 160)) return; - if (window->charCallback) - window->charCallback(window, character); + if (_glfwLibrary.charCallback) + _glfwLibrary.charCallback(window, character); } @@ -173,8 +173,8 @@ void _glfwInputScroll(_GLFWwindow* window, int x, int y) window->scrollX += x; window->scrollY += y; - if (window->scrollCallback) - window->scrollCallback(window, x, y); + if (_glfwLibrary.scrollCallback) + _glfwLibrary.scrollCallback(window, x, y); } @@ -193,8 +193,8 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action) else window->mouseButton[button] = (char) action; - if (window->mouseButtonCallback) - window->mouseButtonCallback(window, button, action); + if (_glfwLibrary.mouseButtonCallback) + _glfwLibrary.mouseButtonCallback(window, button, action); } @@ -210,8 +210,8 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated) { _glfwLibrary.activeWindow = window; - if (window->windowFocusCallback) - window->windowFocusCallback(window, activated); + if (_glfwLibrary.windowFocusCallback) + _glfwLibrary.windowFocusCallback(window, activated); } } else @@ -236,8 +236,8 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated) _glfwLibrary.activeWindow = NULL; - if (window->windowFocusCallback) - window->windowFocusCallback(window, activated); + if (_glfwLibrary.windowFocusCallback) + _glfwLibrary.windowFocusCallback(window, activated); } } } @@ -1076,7 +1076,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow window) // Set callback function for window size changes //======================================================================== -GLFWAPI void glfwSetWindowSizeCallback(GLFWwindow window, GLFWwindowsizefun cbfun) +GLFWAPI void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun) { if (!_glfwInitialized) { @@ -1084,19 +1084,24 @@ GLFWAPI void glfwSetWindowSizeCallback(GLFWwindow window, GLFWwindowsizefun cbfu return; } - window->windowSizeCallback = cbfun; + _glfwLibrary.windowSizeCallback = cbfun; // Call the callback function to let the application know the current // window size if (cbfun) - cbfun(window, window->width, window->height); + { + _GLFWwindow* window; + + for (window = _glfwLibrary.windowListHead; window; window = window->next) + cbfun(window, window->width, window->height); + } } //======================================================================== // Set callback function for window close events //======================================================================== -GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cbfun) +GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun) { if (!_glfwInitialized) { @@ -1104,7 +1109,7 @@ GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cb return; } - window->windowCloseCallback = cbfun; + _glfwLibrary.windowCloseCallback = cbfun; } @@ -1112,7 +1117,7 @@ GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cb // Set callback function for window refresh events //======================================================================== -GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfun cbfun) +GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun) { if (!_glfwInitialized) { @@ -1120,7 +1125,7 @@ GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfu return; } - window->windowRefreshCallback = cbfun; + _glfwLibrary.windowRefreshCallback = cbfun; } @@ -1128,7 +1133,7 @@ GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfu // Set callback function for window focus events //======================================================================== -GLFWAPI void glfwSetWindowFocusCallback(GLFWwindow window, GLFWwindowfocusfun cbfun) +GLFWAPI void glfwSetWindowFocusCallback(GLFWwindowfocusfun cbfun) { if (!_glfwInitialized) { @@ -1136,7 +1141,7 @@ GLFWAPI void glfwSetWindowFocusCallback(GLFWwindow window, GLFWwindowfocusfun cb return; } - window->windowFocusCallback = cbfun; + _glfwLibrary.windowFocusCallback = cbfun; } @@ -1144,7 +1149,7 @@ GLFWAPI void glfwSetWindowFocusCallback(GLFWwindow window, GLFWwindowfocusfun cb // Set callback function for window iconification events //======================================================================== -GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindow window, GLFWwindowiconifyfun cbfun) +GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindowiconifyfun cbfun) { if (!_glfwInitialized) { @@ -1152,7 +1157,7 @@ GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindow window, GLFWwindowiconifyfu return; } - window->windowIconifyCallback = cbfun; + _glfwLibrary.windowIconifyCallback = cbfun; } diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index e83c8cbc..4b67bb41 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -1197,11 +1197,11 @@ static void processSingleEvent(void) window->X11.cursorPosY = event.xmotion.y; window->X11.mouseMoved = GL_TRUE; - if (window->mousePosCallback) + if (_glfwLibrary.mousePosCallback) { - window->mousePosCallback(window, - window->mousePosX, - window->mousePosY); + _glfwLibrary.mousePosCallback(window, + window->mousePosX, + window->mousePosY); } } break; @@ -1224,11 +1224,11 @@ static void processSingleEvent(void) window->width = event.xconfigure.width; window->height = event.xconfigure.height; - if (window->windowSizeCallback) + if (_glfwLibrary.windowSizeCallback) { - window->windowSizeCallback(window, - window->width, - window->height); + _glfwLibrary.windowSizeCallback(window, + window->width, + window->height); } } @@ -1288,8 +1288,8 @@ static void processSingleEvent(void) window->iconified = GL_FALSE; - if (window->windowIconifyCallback) - window->windowIconifyCallback(window, window->iconified); + if (_glfwLibrary.windowIconifyCallback) + _glfwLibrary.windowIconifyCallback(window, window->iconified); break; } @@ -1306,8 +1306,8 @@ static void processSingleEvent(void) window->iconified = GL_TRUE; - if (window->windowIconifyCallback) - window->windowIconifyCallback(window, window->iconified); + if (_glfwLibrary.windowIconifyCallback) + _glfwLibrary.windowIconifyCallback(window, window->iconified); break; } @@ -1358,8 +1358,8 @@ static void processSingleEvent(void) return; } - if (window->windowRefreshCallback) - window->windowRefreshCallback(window); + if (_glfwLibrary.windowRefreshCallback) + _glfwLibrary.windowRefreshCallback(window); break; } diff --git a/tests/accuracy.c b/tests/accuracy.c index 08fdabe0..c3bebaca 100644 --- a/tests/accuracy.c +++ b/tests/accuracy.c @@ -74,8 +74,8 @@ int main(void) exit(EXIT_FAILURE); } - glfwSetMousePosCallback(window, mouse_position_callback); - glfwSetWindowSizeCallback(window, window_size_callback); + glfwSetMousePosCallback(mouse_position_callback); + glfwSetWindowSizeCallback(window_size_callback); glfwSwapInterval(1); glClearColor(0, 0, 0, 0); diff --git a/tests/events.c b/tests/events.c index 8da2b983..e6fda25e 100644 --- a/tests/events.c +++ b/tests/events.c @@ -303,16 +303,16 @@ int main(void) glfwSwapInterval(1); - glfwSetWindowSizeCallback(window, window_size_callback); - glfwSetWindowCloseCallback(window, window_close_callback); - glfwSetWindowRefreshCallback(window, window_refresh_callback); - glfwSetWindowFocusCallback(window, window_focus_callback); - glfwSetWindowIconifyCallback(window, window_iconify_callback); - glfwSetMouseButtonCallback(window, mouse_button_callback); - glfwSetMousePosCallback(window, mouse_position_callback); - glfwSetScrollCallback(window, scroll_callback); - glfwSetKeyCallback(window, key_callback); - glfwSetCharCallback(window, char_callback); + glfwSetWindowSizeCallback(window_size_callback); + glfwSetWindowCloseCallback(window_close_callback); + glfwSetWindowRefreshCallback(window_refresh_callback); + glfwSetWindowFocusCallback(window_focus_callback); + glfwSetWindowIconifyCallback(window_iconify_callback); + glfwSetMouseButtonCallback(mouse_button_callback); + glfwSetMousePosCallback(mouse_position_callback); + glfwSetScrollCallback(scroll_callback); + glfwSetKeyCallback(key_callback); + glfwSetCharCallback(char_callback); printf("Key repeat should be %s\n", keyrepeat ? "enabled" : "disabled"); printf("System keys should be %s\n", systemkeys ? "enabled" : "disabled"); diff --git a/tests/fsaa.c b/tests/fsaa.c index 4c834aea..e5a187a0 100644 --- a/tests/fsaa.c +++ b/tests/fsaa.c @@ -65,7 +65,7 @@ int main(void) exit(EXIT_FAILURE); } - glfwSetWindowSizeCallback(window, window_size_callback); + glfwSetWindowSizeCallback(window_size_callback); glfwSwapInterval(1); samples = glfwGetWindowParam(window, GLFW_FSAA_SAMPLES); diff --git a/tests/fsfocus.c b/tests/fsfocus.c index a1cefc7d..21631f25 100644 --- a/tests/fsfocus.c +++ b/tests/fsfocus.c @@ -93,9 +93,9 @@ int main(void) glfwSwapInterval(1); glfwEnable(window, GLFW_MOUSE_CURSOR); - glfwSetWindowFocusCallback(window, window_focus_callback); - glfwSetKeyCallback(window, window_key_callback); - glfwSetWindowCloseCallback(window, window_close_callback); + glfwSetWindowFocusCallback(window_focus_callback); + glfwSetKeyCallback(window_key_callback); + glfwSetWindowCloseCallback(window_close_callback); while (running && glfwIsWindow(window) == GL_TRUE) { diff --git a/tests/gamma.c b/tests/gamma.c index e918a156..0d2ff09b 100644 --- a/tests/gamma.c +++ b/tests/gamma.c @@ -149,8 +149,8 @@ int main(int argc, char** argv) ggamma, ggain, gblacklevel); glfwSwapInterval(1); - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, size_callback); + glfwSetKeyCallback(key_callback); + glfwSetWindowSizeCallback(size_callback); glEnable(GL_SCISSOR_TEST); diff --git a/tests/iconify.c b/tests/iconify.c index b870bf95..6868c9ad 100644 --- a/tests/iconify.c +++ b/tests/iconify.c @@ -119,8 +119,8 @@ int main(int argc, char** argv) } glfwSwapInterval(1); - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, size_callback); + glfwSetKeyCallback(key_callback); + glfwSetWindowSizeCallback(size_callback); glEnable(GL_SCISSOR_TEST); diff --git a/tests/peter.c b/tests/peter.c index 95ab744f..e2671248 100644 --- a/tests/peter.c +++ b/tests/peter.c @@ -96,9 +96,9 @@ static GLboolean open_window(void) glfwGetMousePos(window_handle, &x, &y); printf("Mouse position: %i %i\n", x, y); - glfwSetWindowSizeCallback(window_handle, window_size_callback); - glfwSetMousePosCallback(window_handle, mouse_position_callback); - glfwSetKeyCallback(window_handle, key_callback); + glfwSetWindowSizeCallback(window_size_callback); + glfwSetMousePosCallback(mouse_position_callback); + glfwSetKeyCallback(key_callback); glfwSwapInterval(1); return GL_TRUE; diff --git a/tests/reopen.c b/tests/reopen.c index 6f464af2..76f914ae 100644 --- a/tests/reopen.c +++ b/tests/reopen.c @@ -91,9 +91,9 @@ static int open_window(int width, int height, int mode) return 0; } - glfwSetWindowSizeCallback(window_handle, window_size_callback); - glfwSetWindowCloseCallback(window_handle, window_close_callback); - glfwSetKeyCallback(window_handle, key_callback); + glfwSetWindowSizeCallback(window_size_callback); + glfwSetWindowCloseCallback(window_close_callback); + glfwSetKeyCallback(key_callback); glfwSwapInterval(1); printf("Opening %s mode window took %0.3f seconds\n", diff --git a/tests/sharing.c b/tests/sharing.c index 588e5f0b..b1b335c9 100644 --- a/tests/sharing.c +++ b/tests/sharing.c @@ -49,7 +49,7 @@ static GLFWwindow open_window(const char* title, GLFWwindow share) if (!window) return NULL; - glfwSetKeyCallback(window, key_callback); + glfwSetKeyCallback(key_callback); glfwSwapInterval(1); return window; diff --git a/tests/tearing.c b/tests/tearing.c index cd493d53..6e43e88f 100644 --- a/tests/tearing.c +++ b/tests/tearing.c @@ -59,7 +59,7 @@ int main(void) exit(EXIT_FAILURE); } - glfwSetWindowSizeCallback(window, window_size_callback); + glfwSetWindowSizeCallback(window_size_callback); glfwSwapInterval(1); glClearColor(0.f, 0.f, 0.f, 0.f);