This is supposed to animate half of a clockwise circle, as though a particle was moving in a circle at constant speed:
// gcc simple6.c -o simple6 -lglfw -lGL -lm
// Fedora Linux 42 (Workstation Edition), graphics NV137, Wayland
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
float t=0, h = .05, ratio;
int width, height;
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit()) exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window) { glfwTerminate(); exit(EXIT_FAILURE); }
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glLineWidth(1);
glfwSwapInterval(2);
while (!glfwWindowShouldClose(window)) {
if (t < 6.28/2) {
glBegin(GL_LINES);
glVertex3f(sin(t), cos(t), .0);
glVertex3f(sin(t+h), cos(t+h), .0);
glEnd();
glFlush();
glfwSwapBuffers(window);
glBegin(GL_LINES);
glVertex3f(sin(t), cos(t), .0);
glVertex3f(sin(t+h), cos(t+h), .0);
glEnd();
glFlush();
t += h;
}
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
The program fails: it usually ends showing a circle with gaps:
...and I have seen it flicker and mess up the whole window. If I change the program to grow the half circle in a single window and then exchange the frame buffers, then it draws the half circle just fine.The program iteratively addends a line segment, swaps the buffer, and then addends an identical line segment.
What am I doing wrong?
I'm assuming your assumption is that the "other buffer" remains as you left it, hence why you're trying to draw the same thing in "each" and then increment your little angle thing and then not clear between frames?
That is not how OpenGL works, and in fact it's not how any graphics API works. OpenGL is under no obligation to return the "previous" buffer after you call *SwapBuffers()
, which lets it apply a whole myriad of optimizations:
If you want to retain images between frames, use a framebuffer backed by a texture, then every frame you render your additional line to the framebuffer, then render the image to your front buffer like usual, clearing it every time. (note that this needs a better round-robin implementation or it will serialize frames)