Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: back buffering problem?  (Read 5512 times)

0 Members and 1 Guest are viewing this topic.

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
back buffering problem?
« on: September 29, 2012, 04:12:43 am »
Hey guys.

I'm re-sharpening my OpenGL stone, and I've hit a problem that has stumped both myself and my internet researching skills. It's probably very simple.

The problem is once I run my application, the application's viewport flashes between two renders in a flickering pattern. I'm supposing the front and back buffers are swapping.

How can I prevent this? I want all the triangles to stay on screen at all times. I'm certain it has to do with my if/else statment followed by window.display(), which is from SFML 2.0rc.

I'm working on a Sierpinski Gasket (I'm close but not done yet. Don't tell me I want to figure it out!). I am interested in general code clean up though. I'm open for any suggestions!

Thanks!


#include <SFML/Graphics.hpp>
#include <GL/glew.h>

using namespace sf;

struct point
{
        float x, y; // z is always 0 ... for now. MWUAHAHAA
};

point points[3] = {{0.f, 1.f},     // top
                                   {-1.f, -1.f},   // left
                                   { 1.f, -1.f}};  // right

point temp = {points[0].x, points[0].y};

void renderFirstTriangle()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glBegin(GL_TRIANGLES);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[0].x, points[0].y, 0.f);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[1].x, points[1].y, 0.f);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[2].x, points[2].y, 0.f);

                glEnd();
}

int main()
{
    Window window(VideoMode(800, 600), "Fractal", Style::Default, ContextSettings(32));
    window.setVerticalSyncEnabled(true);
       
        renderFirstTriangle();

        while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
                        if (event.type == Event::Resized)
                glViewport(0, 0, event.size.width, event.size.height);

                        else if (event.type == Event::Closed)
                                window.close();
        }

                for (int i = 0; i < 3; i++)
                {
                        // calculate new vertex positions

                        temp.x = points[0].x;
                        temp.y = points[0].y;

                        glBegin(GL_TRIANGLES);
                       
                        if( i % 2 )
                                glColor3f(0.1f, 0.1f, 0.1f);

                        glVertex3f((points[0].x + points[1].x) / 2, (points[0].y + points[1].y) / 2, 0.0f);
                        glVertex3f((points[1].x + points[2].x) / 2, (points[1].y + points[2].y) / 2, 0.0f);
                        glVertex3f((points[2].x + temp.x) / 2, (points[2].y + temp.y) / 2, 0.0f);
                       
                        glEnd();
                }
                window.display();
        }
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: back buffering problem?
« Reply #1 on: September 29, 2012, 09:38:46 am »
You should always clear the window, draw your stuff and then display it.
Keep in mind that drawing it once and hoping it will always stay there is a bad idea, because as soon as you drag some window in front of yours the information will get overwritten.

#include <SFML/Graphics.hpp>
#include <GL/glew.h>

using namespace sf;

struct point
{
        float x, y; // z is always 0 ... for now. MWUAHAHAA
};

point points[3] = {{0.f, 1.f},     // top
                                   {-1.f, -1.f},   // left
                                   { 1.f, -1.f}};  // right

point temp = {points[0].x, points[0].y};

void renderFirstTriangle()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glBegin(GL_TRIANGLES);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[0].x, points[0].y, 0.f);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[1].x, points[1].y, 0.f);

                glColor3f(1.f, 1.f, 1.f);
                glVertex3f(points[2].x, points[2].y, 0.f);

                glEnd();
}

int main()
{
    Window window(VideoMode(800, 600), "Fractal", Style::Default, ContextSettings(32));
    window.setVerticalSyncEnabled(true);

        while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
                        if (event.type == Event::Resized)
                glViewport(0, 0, event.size.width, event.size.height);

                        else if (event.type == Event::Closed)
                                window.close();
        }

                window.clear();
                renderFirstTriangle();

                for (int i = 0; i < 3; i++)
                {
                        // calculate new vertex positions

                        temp.x = points[0].x;
                        temp.y = points[0].y;

                        glBegin(GL_TRIANGLES);
                       
                        if( i % 2 )
                                glColor3f(0.1f, 0.1f, 0.1f);

                        glVertex3f((points[0].x + points[1].x) / 2, (points[0].y + points[1].y) / 2, 0.0f);
                        glVertex3f((points[1].x + points[2].x) / 2, (points[1].y + points[2].y) / 2, 0.0f);
                        glVertex3f((points[2].x + temp.x) / 2, (points[2].y + temp.y) / 2, 0.0f);
                       
                        glEnd();
                }
                window.display();
        }
}
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #2 on: September 30, 2012, 06:08:54 am »
Thanks for the response.

I am using SFML 2.0 and window.clear does not exist in 2.0. I have added window.setActive(); though which doesn't seem to help but seems appropiate.

I'm beginning to presume this is a problem with 2.0 itself. Thoughts anyone?

I will also note that moving a window infront of my application in windows 7 does not clear the screen. So, the data is being stored and re-rendered it seems.
« Last Edit: September 30, 2012, 06:12:10 am by Jesse Meyer »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: back buffering problem?
« Reply #3 on: September 30, 2012, 09:48:05 am »
You must call glClear to clear the back buffer. You must do it every frame.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: back buffering problem?
« Reply #4 on: September 30, 2012, 07:26:18 pm »
I am using SFML 2.0 and window.clear does not exist in 2.0. I have added window.setActive(); though which doesn't seem to help but seems appropiate.
Oh well my bad then, didn't notice that you were using the plain sf::Window class and not the sf::RenderWindow. ;)
Yes in this case you'll have to call the OpenGL equivalent glClear.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #5 on: October 01, 2012, 07:03:39 am »
Thanks everyone.

So, I'm using RenderWindow now, along with window.clear() and I am in need of some advice.

As expected, the back buffer clears but with that so do all the points that have been rendered thus far. What is the best design to ensure the dots remain on screen? Do I have to re-render them each frame, implying that the longer my application runs, the longer each frame will take to render? I don't forsee that being an issue but it does complicate the code.

My code now is as follows :

#include <SFML/Graphics.hpp>
#include <GL/glew.h>
#include <time.h>
#include <iostream>

using namespace sf;

struct point
{
        float x, y; // z is always 0 ... for now. MWUAHAHAA
};
                   //  x  ,  y
point triangle[3] = {{-1.f, -1.f},      // left
                                    { 1.f, -1.f},      // right
                                    { 0.f, 1.f}};     // top

int main()
{
    RenderWindow window(VideoMode(800, 600), "Fractal", Style::Default, ContextSettings(32));
    window.setVerticalSyncEnabled(true);

        srand((unsigned)time(0));

        float oldX = (float)rand()/((float)RAND_MAX / 2 );
        float oldY = (float)rand()/((float)RAND_MAX / 2 );

        // normalize the result
        if((oldX + oldY) > 2)
        {
                oldX -= 1.f;
                oldY -= 1.f;
        }

        int randomVertex;
        float newX;
        float newY;

        while(window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
                        if (event.type == Event::Resized)
                glViewport(0, 0, event.size.width, event.size.height);

                        else if (event.type == Event::Closed)
                                window.close();
        }

                window.clear();

                // calculate new vertex positions

                randomVertex = rand() % 3;

                newX = (oldX + triangle[randomVertex].x) / 2;
                newY = (oldY + triangle[randomVertex].y) / 2;

                glBegin(GL_POINTS);

                glVertex3f(newX, newY, 0.0f);

                glEnd();

                oldX = newX;
                oldY = newY;
               
                window.display();
        }
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: back buffering problem?
« Reply #6 on: October 01, 2012, 08:07:04 am »
You don't need the graphics module and sf::RenderWindow just to clear your window, glClear does the job if you're using OpenGL.

And yes, you need to clear/draw/display everything every frame, the back buffer is not a persistent object where you can accumulate rendered objects.
Laurent Gomila - SFML developer

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #7 on: October 01, 2012, 10:24:22 pm »
Thanks Laurent. I'm still figuring out SFML (and it's bloody fantastic thus far, great job!), which leads to another question : is there a persistent object within SFML that I can use for storing these points, or is something as generic as <vector> good enough?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: back buffering problem?
« Reply #8 on: October 01, 2012, 10:45:21 pm »
You should start by the beginning: what do you want to do? ;)
Laurent Gomila - SFML developer

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #9 on: October 01, 2012, 11:08:34 pm »
Ha. Well as it stands, it works, but with a huge caveat that the screen blinks sometimes between two different sets of points (flipping buffers). To address this, I'd have to store each new point generated per frame into a container (a persistent object) and iterate through it each frame. The obvious downside is that as the object grows so does the time it takes to render. The longer the application runs the slower it becomes.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: back buffering problem?
« Reply #10 on: October 01, 2012, 11:43:44 pm »
Do you realize that you're talking about technical details but we don't even know what your application does? That's what I'm trying to know :P
Laurent Gomila - SFML developer

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #11 on: October 01, 2012, 11:57:11 pm »
It's a Sierpinski Gasket fractal generator.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: back buffering problem?
« Reply #12 on: October 02, 2012, 08:03:24 am »
If you really want to accumulate individual pixels and have a constant drawing time, you should work on an array of pixels (std::vector<sf::Uint8> for example), and update a sf::Texture (see its update function) from it whenever you want to refresh the screen.
Laurent Gomila - SFML developer

Jesse Meyer

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: back buffering problem?
« Reply #13 on: October 02, 2012, 08:34:16 am »
Thanks! (Btw, what would be the next popular alternative to what I'm doing?)