RenderWindow不断更新display()导致闪烁

时间:2016-04-30 16:36:01

标签: c++ sfml display

我正在尝试编写一个程序,允许用户使用鼠标进行绘制。我一直在尝试使用sf::RenderWindow对象来适当更新显示的许多不同方法来调用display()但没有取得多大成功。我正在进行绘图的循环是调用显示速度太快,导致大量闪烁(通过测试确认)。如果我添加一种方法来减慢对display()的调用速度,例如使用sf::Clock,那么绘图只会在与display()相同的延迟时更新,从而导致口吃效果。我需要的是一种经常更新显示器以显示绘图更新而不会导致屏幕闪烁的方法。

目前,我已经延迟显示(在事件轮询开关语句的底部),因此不会发生闪烁,但会向mainWindow.display();添加void MainWindow::draw()函数导致闪烁,因为它更新太快。我在sf::Event::MouseMoved上进行了绘图,但我尝试更改它以查看是否有帮助,但事实并非如此。

这里发生了所有绘图和事件检测:

MainWindow.h

#pragma once
#include "GraphPaper.h"
#include "stdafx.h"

class MainWindow
{
    public:
        MainWindow(short, short);
        void close();
        void start();
        void moveCamera(sf::Keyboard::Key);
        void draw(sf::Event);
        void displayWindow(sf::Vector2i&);

    private:
        bool leftMousePressed, rightMousePressed, isExiting;
        int r, g, b, mouseX, mouseY;
        short height, width;

        const short DRAWING_CRICLE_RADIUS = 10;

        GraphPaper paper;
        //DrawingBrush brush;

        const sf::Color WHITE = sf::Color(255, 255, 255);
        const sf::Color BLACK = sf::Color(0, 0, 0);

        sf::CircleShape circle;
        sf::Mouse cursor;
        sf::Vector2i windowCenter;
        sf::RenderWindow mainWindow;
        sf::View view;
};

MainWindow.cpp:

#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"

MainWindow::MainWindow(short height, short width)
{
    this->height = height;
    this->width = width;
    circle.setRadius(DRAWING_CRICLE_RADIUS);
    circle.setFillColor(BLACK);
}

void MainWindow::start()
{
    sf::Clock clock;
    mainWindow.create(sf::VideoMode(height, width, 32), "Test");

    sf::View view(sf::FloatRect(0,0,height,width));
    mainWindow.setView(view);

    leftMousePressed, rightMousePressed, isExiting = false;

    sf::Event currentEvent;
    sf::Vector2i windowCenter(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));

    displayWindow(windowCenter);

    while (!isExiting)
    {
        sf::Clock clock;
        while (mainWindow.pollEvent(currentEvent))
        {
            switch (currentEvent.type)
            {
            case sf::Event::MouseMoved:
            {
                if (rightMousePressed == true)
                {
                    std::cout << "Mouse Panned\n";
                }
                if (leftMousePressed == true)
                {
                    draw(currentEvent);
                }
                break;
            }
            case sf::Event::MouseButtonPressed:
            {
                std::cout << "Mouse Pressed\n";

                mouseX = currentEvent.mouseButton.x;
                mouseY = currentEvent.mouseButton.y;

                if (currentEvent.mouseButton.button == sf::Mouse::Left)
                {
                    while (currentEvent.type != sf::Event::MouseButtonReleased)
                    {
                        std::cout << "Mouse is Drawing\n";
                        draw(currentEvent);
                        mainWindow.pollEvent(currentEvent);
                    }
                }
                else if (currentEvent.mouseButton.button == sf::Mouse::Right)
                {
                    rightMousePressed = true;
                }
                break;
            }
            case sf::Event::MouseButtonReleased:
            {
                std::cout << "Mouse Released\n";
                if (currentEvent.mouseButton.button == sf::Mouse::Left)
                {
                    leftMousePressed = false;
                }
                else if(currentEvent.mouseButton.button == sf::Mouse::Right)
                {
                    rightMousePressed = false;
                }
                break;
            }
            case sf::Event::KeyPressed:
            {
                sf::Keyboard::Key keyPressed = currentEvent.key.code;
                if(keyPressed == sf::Keyboard::Escape)
                {
                    close();
                }
                else if(keyPressed == sf::Keyboard::Left || sf::Keyboard::Right ||
                                       sf::Keyboard::Down || sf::Keyboard::Up ||
                                       sf::Keyboard::A || sf::Keyboard::S ||
                                       sf::Keyboard::D || sf::Keyboard::W)
                {
                    moveCamera(keyPressed);
                    displayWindow(windowCenter);
                }
                break;
            }
            case sf::Event::Closed:
            {
                close();
                break;
            }
            case sf::Event::Resized:
            {
                windowCenter = sf::Vector2i(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
                displayWindow(windowCenter);
                break;
            }
            }
            if (clock.getElapsedTime().asMilliseconds() >= 500)
            {
                clock.restart();
                mainWindow.display();
            }
        }
    }
}
void MainWindow::moveCamera(sf::Keyboard::Key keyPressed)
{
    view = mainWindow.getView();
    switch (keyPressed)
    {
    case sf::Keyboard::A:
    case sf::Keyboard::Left:
    {
        view.move(-50, 0);
        break;
    }
    case sf::Keyboard::D:
    case sf::Keyboard::Right:
    {
        view.move(50, 0);
        break;
    }
    case sf::Keyboard::W:
    case sf::Keyboard::Up:
    {
        view.move(0, 50);
        break;
    }
    case sf::Keyboard::S:
    case sf::Keyboard::Down:
    {
        view.move(0, -50);
        break;
    }
    }
    mainWindow.setView(view);
}
void MainWindow::draw(sf::Event mouse)
{
    circle.setPosition(mainWindow.mapPixelToCoords(sf::Vector2i(mouse.mouseMove.x, mouse.mouseMove.y)));
    mainWindow.draw(circle);
}
void MainWindow::close()
{
    std::cout << "Closing...\n";
    mainWindow.close();
    isExiting = true;
}
void MainWindow::displayWindow(sf::Vector2i& windowCenter)
{
    mainWindow.clear(WHITE);
    mainWindow.draw(paper.getSprite());
    mainWindow.display();
    cursor.setPosition(windowCenter);
}

1 个答案:

答案 0 :(得分:1)

您缺少渲染循环的重要部分。您应该在每次循环迭代时绘制所有部分。现在你只是在你的圈子被改变时画画。

您的代码应如下所示:

  1. 根据输入更改圆圈位置
  2. 清除窗口
  3. 画圆圈
  4. 显示