Atlas - empty.c

Home / ext / glfw / tests Lines: 3 | Size: 4833 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1//======================================================================== 2// Empty event test 3// Copyright (c) Camilla Löwy <[email protected]> 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 is intended to verify that the posting of empty events works. 27// Background colors are produced on a secondary thread, which then wakes 28// the main thread with glfwPostEmptyEvent when a new one is available. 29// This allows the main thread to wait for events unconditionally. 30// 31//======================================================================== 32 33#include "tinycthread.h" 34 35#define GLAD_GL_IMPLEMENTATION 36#include <glad/gl.h> 37#define GLFW_INCLUDE_NONE 38#include <GLFW/glfw3.h> 39 40#include <math.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <stdbool.h> 44 45struct State 46{ 47 mtx_t lock; 48 bool running; 49 bool needs_update; 50 int width; 51 int height; 52 float r, g, b; 53}; 54 55static void error_callback(int error, const char* description) 56{ 57 fprintf(stderr, "Error: %s\n", description); 58} 59 60static void generate_color(struct State* state) 61{ 62 const float r = (float) rand() / (float) RAND_MAX; 63 const float g = (float) rand() / (float) RAND_MAX; 64 const float b = (float) rand() / (float) RAND_MAX; 65 const float l = sqrtf(r * r + g * g + b * b); 66 67 mtx_lock(&state->lock); 68 state->r = r / l; 69 state->g = g / l; 70 state->b = b / l; 71 state->needs_update = true; 72 mtx_unlock(&state->lock); 73} 74 75static int thread_main(void* data) 76{ 77 struct State* const state = data; 78 79 srand((unsigned int) time(NULL)); 80 81 while (state->running) 82 { 83 generate_color(state); 84 glfwPostEmptyEvent(); 85 86 struct timespec time; 87 clock_gettime(CLOCK_REALTIME, &time); 88 time.tv_sec += 1; 89 thrd_sleep(&time, NULL); 90 } 91 92 return 0; 93} 94 95static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 96{ 97 if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 98 glfwSetWindowShouldClose(window, true); 99} 100 101static void framebuffer_size_callback(GLFWwindow* window, int width, int height) 102{ 103 struct State* const state = glfwGetWindowUserPointer(window); 104 105 mtx_lock(&state->lock); 106 state->width = width; 107 state->height = height; 108 state->needs_update = true; 109 mtx_unlock(&state->lock); 110} 111 112int main(void) 113{ 114 struct State state = { .running = true }; 115 116 if (mtx_init(&state.lock, mtx_plain) != thrd_success) 117 { 118 glfwTerminate(); 119 exit(EXIT_FAILURE); 120 } 121 122 generate_color(&state); 123 124 glfwSetErrorCallback(error_callback); 125 126 if (!glfwInit()) 127 exit(EXIT_FAILURE); 128 129 GLFWwindow* window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); 130 if (!window) 131 { 132 glfwTerminate(); 133 exit(EXIT_FAILURE); 134 } 135 136 glfwMakeContextCurrent(window); 137 gladLoadGL(glfwGetProcAddress); 138 glfwSetKeyCallback(window, key_callback); 139 glfwSetWindowUserPointer(window, &state); 140 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 141 glfwGetFramebufferSize(window, &state.width, &state.height); 142 143 thrd_t color_thread; 144 145 if (thrd_create(&color_thread, thread_main, &state) != thrd_success) 146 { 147 fprintf(stderr, "Failed to create secondary thread\n"); 148 149 glfwTerminate(); 150 exit(EXIT_FAILURE); 151 } 152 153 while (!glfwWindowShouldClose(window)) 154 { 155 if (state.needs_update) 156 { 157 mtx_lock(&state.lock); 158 glViewport(0, 0, state.width, state.height); 159 glClearColor(state.r, state.g, state.b, 1.f); 160 state.needs_update = false; 161 mtx_unlock(&state.lock); 162 163 glClear(GL_COLOR_BUFFER_BIT); 164 glfwSwapBuffers(window); 165 } 166 167 glfwWaitEvents(); 168 } 169 170 glfwHideWindow(window); 171 state.running = false; 172 thrd_join(color_thread, NULL); 173 mtx_destroy(&state.lock); 174 175 glfwTerminate(); 176 exit(EXIT_SUCCESS); 177} 178 179
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.