The color of the window blinks repeatedly

Started by
18 comments, last by test opty 6 years, 4 months ago

Hello all,

 

On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.


#include <glad/glad.h> 
#include <GLFW/glfw3.h>
#include <std_lib_facilities_4.h>
using namespace std;

void framebuffer_size_callback(GLFWwindow* window , int width, int height)
{
    glViewport(0, 0, width, height);
}

//******************************

void processInput(GLFWwindow* window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

//*********************************

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr)
    {
        cout << "Failed to create GLFW window" << endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        cout << "Failed to initialize GLAD" << endl;
        return -1;
    }

    glViewport(0, 0, 600, 480);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

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

    glfwTerminate();
    return 0;
}

 

The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.

What is the problem and how to solve it please?

Advertisement

Looks like you only call glClear once during startup. You need to call it every frame (so it probably needs to be inside your while loop, at the top; I'm not overly familiar with GLFW).

It got solved! Thanks.

But what do you mean by "every frame"? Would you explain it a little?  

Every iteration of your rendering loop is called a "frame."

Every frame you draw the complete scene from scratch, starting by clearing the old frame by using glClear. You need to do this because

  • normally you'll have drawn a bunch of other stuff -- sprites, meshes, text, etc -- to the screen during the last frame. You want to draw those things in their new positions this frame, and you'll want to clear the drawing you did of them in their old positions last frame. Also
  • under the hood, most of the time, the actual method of presenting your back buffer to the screen involves swapping it with another one or otherwise moving the memory around or discarding it so you're not actually drawing into the same region of memory between two successful frames. You may have two buffers - a front and a back buffer - that are swapped between, for example.  Which is probably what caused the artifacting you saw: you only cleared one buffer, the second had garbage in it.

 

Thank you very much. It was useful. 

I have new questions on the case now! :)

Here we have a simple window. It has nothing. So how many frames are needed to complete that window?

If one frame is to draw, say, a corner of the window, why do we need to replace it with a new one in the next frame?!

 

1 hour ago, test opty said:

Here we have a simple window. It has nothing. So how many frames are needed to complete that window?

Instead you should ask how long does it take to render one frame.

Games normally run in 60 frames per second. So every second you should render 60 frames. If a frame takes too long to render it reduces the amount of frames you can render that second.

24 Frames per second is needed for smooth animations and 12 is the lowest that it could go and still look like it is moving.

Think of it as a fast moving slide show. Because the images are rendered so fast it looks like things are moving, it works the same as a movie or a flip book.

1 hour ago, test opty said:

If one frame is to draw, say, a corner of the window, why do we need to replace it with a new one in the next frame?!

Because not everything remains in the same place. If the character moves then the objects in the game will move and need to be rendered at a new point.

Thanks for the reply.

Please have a look at the code above. It's a simple rectangle or window. So nothing is moving/animating. 

How many frames are needed for that (apparently) fixed picture? I guess less than 10 per second. Once again, what does each frame do in that window? If I'm frank, I think only one frame is sufficient and no frame replacing is needed. 

2 hours ago, test opty said:

I think only one frame is sufficient and no frame replacing is needed. 

Yes you are correct. Lots of turn based games only update the image when needed. Only one is needed for your window.

However when was the last time you have seen a game where there wasn't any movement? Even the mouse pointer inside the window needs the buffer to update.

 

You are updating the buffer with: glfwSwapBuffers(window);  If you moved this out of the loop it should stop updating your render. You could also use some kind of bool to check if a update is needed.

 

To explain how the buffer works: The image is the buffer. There should be 2 buffers one for showing the player and a other one that is drawn on. When the glfwSwapBuffers() is called it checks if the image is done and swaps them when ready.

The glfwSwapBuffers() is a very advanced little piece of code it even has Vsync in it. It was designed to be easy to use.


//This is your game
while (!glfwWindowShouldClose(window))//If the window is open, the loop runs.
    {
        processInput(window);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

The reason GLFW works like this is to keep things easy for users, as your game now progresses you will need to update each time something happens.

Some libraries do allow you more control however they are much harder to use because you need to run everything yourself.

 

 

10 hours ago, Scouting Ninja said:

However when was the last time you have seen a game where there wasn't any movement?

I'm at the beginning of learning OpenGL, so it's not a game I think.

By the way, does this convey that OpenGL is mostly for developing games?

10 hours ago, Scouting Ninja said:

You are updating the buffer with: glfwSwapBuffers(window);  If you moved this out of the loop it should stop updating your render. You could also use some kind of bool to check if a update is needed.

I used the statements without the loop (removed the loop) but the resulting window is shown and immediately vanishing! I even can't see it!  :( I think the loop is also for keeping the output (window) so that we are able to see the result. 

As an another attempt to figure the issue out completely, I reused the loop and put a counter into it. Now I can see the resulting window. Then I couted that counter (I use C++). It showed different values, say, from 75, 97 to 137 or over!

That is, we have many iterations, just for a simple window! It's also strange for me.

This topic is closed to new replies.

Advertisement