1 //========================================================================
2 // Vsync enabling test
3 // Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
4 //
5 // This software is provided 'as-is', without any express or implied
6 // warranty. In no event will the authors be held liable for any damages
7 // arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it
11 // freely, subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented; you must not
14 // claim that you wrote the original software. If you use this software
15 // in a product, an acknowledgment in the product documentation would
16 // be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such, and must not
19 // be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source
22 // distribution.
23 //
24 //========================================================================
25 //
26 // This test renders a high contrast, horizontally moving bar, allowing for
27 // visual verification of whether the set swap interval is indeed obeyed
28 //
29 //========================================================================
30
31 #include <GLFW/glfw3.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <math.h>
36
37 static int swap_interval;
38 static double frame_rate;
39
update_window_title(GLFWwindow * window)40 static void update_window_title(GLFWwindow* window)
41 {
42 char title[256];
43
44 sprintf(title, "Tearing detector (interval %i, %0.1f Hz)",
45 swap_interval, frame_rate);
46
47 glfwSetWindowTitle(window, title);
48 }
49
set_swap_interval(GLFWwindow * window,int interval)50 static void set_swap_interval(GLFWwindow* window, int interval)
51 {
52 swap_interval = interval;
53 glfwSwapInterval(swap_interval);
54 update_window_title(window);
55 }
56
error_callback(int error,const char * description)57 static void error_callback(int error, const char* description)
58 {
59 fprintf(stderr, "Error: %s\n", description);
60 }
61
framebuffer_size_callback(GLFWwindow * window,int width,int height)62 static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
63 {
64 glViewport(0, 0, width, height);
65 }
66
key_callback(GLFWwindow * window,int key,int scancode,int action,int mods)67 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
68 {
69 if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
70 set_swap_interval(window, 1 - swap_interval);
71 }
72
main(void)73 int main(void)
74 {
75 float position;
76 unsigned long frame_count = 0;
77 double last_time, current_time;
78 GLFWwindow* window;
79
80 glfwSetErrorCallback(error_callback);
81
82 if (!glfwInit())
83 exit(EXIT_FAILURE);
84
85 window = glfwCreateWindow(640, 480, "", NULL, NULL);
86 if (!window)
87 {
88 glfwTerminate();
89 exit(EXIT_FAILURE);
90 }
91
92 glfwMakeContextCurrent(window);
93 set_swap_interval(window, 0);
94
95 last_time = glfwGetTime();
96 frame_rate = 0.0;
97
98 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
99 glfwSetKeyCallback(window, key_callback);
100
101 glMatrixMode(GL_PROJECTION);
102 glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f);
103 glMatrixMode(GL_MODELVIEW);
104
105 while (!glfwWindowShouldClose(window))
106 {
107 glClear(GL_COLOR_BUFFER_BIT);
108
109 position = cosf((float) glfwGetTime() * 4.f) * 0.75f;
110 glRectf(position - 0.25f, -1.f, position + 0.25f, 1.f);
111
112 glfwSwapBuffers(window);
113 glfwPollEvents();
114
115 frame_count++;
116
117 current_time = glfwGetTime();
118 if (current_time - last_time > 1.0)
119 {
120 frame_rate = frame_count / (current_time - last_time);
121 frame_count = 0;
122 last_time = current_time;
123 update_window_title(window);
124 }
125 }
126
127 glfwTerminate();
128 exit(EXIT_SUCCESS);
129 }
130
131