I want to make render from a “main” thread, and have another thread call glfwSwapBuffers at regular intervals (or on demand from the “main” thread).
I have a MWE based on the example at https://www.glfw.org/documentation.html#example-code . Modification:
- Add rendering of a color changing rectangle
- Put glfwSwpBuffers in a seperate thread
- Register a callback function for window resize events
Unfortunately, it looks like something strange is happening to the “context”. When glfwSwapBuffers is called from a separate thread the rectangle does not stay centeret, and parts of the window are not updated (when enlarging the window).
Here is my program
// File: main.c
// Compile: cc -o main main.c -lglfw -lOpenGL
// Run: ./main
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
// Define a value for 'test'
// 1: Swap buffers in a different thread
// 2: Single-threaded program
#define test 1
float red = 0.5;
float rincr = 0.01;
uint8_t more = 1;
int width;
int height;
GLFWwindow* window;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
printf( "Update %i x %i\n", width, height );
}
void* cyclic(void* )
{
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 50000000;
while(more)
{
/* Swap front and back buffers */
// glfwMakeContextCurrent(window); // Don't uncomment, causes crash
glfwSwapBuffers(window);
/* Sleep a while */
nanosleep( &ts, NULL);
}
}
int main(void)
{
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Set callback function for window resize */
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Start another thread */
#if test == 1
pthread_t thread1; // Swapping buffers in a another thread
pthread_create( &thread1, NULL, cyclic, NULL); // has a strange effect on context (?)
#endif
/* Loop until the user closes the window */
while( more )
{
more = !glfwWindowShouldClose(window);
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
red += rincr;
if( red < 0.05 || 0.95 < red ) rincr = -rincr;
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3f(red, 0.2, 0.1);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
#if test == 2
glfwSwapBuffers(window); // Works nicely
#endif
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Am I doing something wrong, or is my design not possible with GLFW?