Search code examples
c++openglglfwglewopengl-4

glpointsize() Fails to Shrink a Point


I'm trying to write a simple opengl program that cyclically grows and shrinks a single point at the center of the screen using glPointSize() and a variable pointSize. Printing the value of pointSize and stepping through the code with a debugger appears to show that pointSize updates correctly on each iteration. The rendering of the point also appears to be correct when pointSize is increasing, but when pointSize is decreasing the point is still rendered at its maximum size on the screen, and keeps rendering that way no matter how much pointSize grows or shrinks in value - and I cannot figure out why.

#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <iostream>

#define numVAOs 1
GLuint renderingProgram;
GLuint vao[numVAOs];

GLuint createShaderProgram() {
    const char *vshaderSource =
        "#version 430    \n"
        "void main(void) \n"
        "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";

    const char *fshaderSource =
        "#version 430    \n"
        "out vec4 color; \n"
        "void main(void) \n"
        "{ color = vec4(0.0, 0.0, 1.0, 1.0); }";

    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    GLuint vfprogram = glCreateProgram();

    glShaderSource(vShader, 1, &vshaderSource, NULL);
    glShaderSource(fShader, 1, &fshaderSource, NULL);

    glCompileShader(vShader);
    glCompileShader(fShader);

    glAttachShader(vfprogram, vShader);
    glAttachShader(vfprogram, fShader);

    glLinkProgram(vfprogram);

    return vfprogram;
}

void init() {
    renderingProgram = createShaderProgram();
    glGenVertexArrays(numVAOs, vao);
    glBindVertexArray(vao[0]);
}

GLfloat pointSize = 100.0f;
GLfloat increment = 1.0f;

void display() {
    glUseProgram(renderingProgram);

    if (pointSize > 200 || pointSize < 2) increment *= -1.0f;
    pointSize += increment;

    glPointSize(pointSize);
    glDrawArrays(GL_POINTS, 0, 1);
}

int main(void) {
    if (!glfwInit()) exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    GLFWwindow* window = glfwCreateWindow(600, 600, "Test", nullptr, nullptr);

    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK) exit(EXIT_FAILURE);

    glfwSwapInterval(1);

    init();

    while (!glfwWindowShouldClose(window)) {
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

Solution

  • Your code does not clear the screen with glClear. Therefore, when the point grows, you can see it. When it shrinks, it's simply drawn 'inside' the bigger dot, without you noticing it. You could catch that if you changed the color of the dot as it changes the size.

    Simply clear the color buffer at the beginning of the frame:

    void display() {
        // default clear color is black, but you can change it:
        //glClearColor(1,0,0,1);
        glClear(GL_COLOR_BUFFER_BIT);
    
        glUseProgram(renderingProgram);
        ...