如何为生成艺术目的在单个缓冲区上绘制
How to draw on a single buffer for generative art purposes
实际上我遇到了一个我自己无法解决的问题,使用 SFML 我只有一个形状,我将它移动到 每帧,然后我画它。问题是,SFML 使用两个缓冲区,每个缓冲区(帧)上的轨迹都不相同,并且会产生奇怪的闪烁效果。
我需要你的知识,我是否应该找到另一种方法来做到这一点,比如我将扩展的形状数组。或者有没有办法跳过第二个缓冲区?把这个缓冲区做成一张纸,我的形状是画笔。
sf::CircleShape circle;
//Init the circle (radius etc)
sf::Vector2f pos(0, 500);
while(!done)
{
pos.x += 1;
circle.setPosition(pos);
window.draw(circle);
window.display();
}
祝你度过愉快的一天。
双缓冲的目的是避免在 帧渲染期间显示部分未完全渲染的场景 。所以你的问题与双缓冲本身无关。基本上,您每次都需要生成渲染特定帧所需的所有基元。在您的具体情况下,您可以这样实现:
sf::CircleShape circle;
//Init the circle (radius etc)
sf::Vector2f pos(0, 500);
int frameCount = 0;
while(!done)
{
++frameCount;
for (int i = 0; i < frameCount; ++i) {
circle.setPosition(pos + sf::Vector2f(i, 0));
window.draw(circle);
}
window.display();
}
您可以使用 sf::RenderTexture
作为后台缓冲区(单缓冲区)来实现这一点,然后通过 sf::RenderWindow` 在屏幕上绘制
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML art");
window.setVerticalSyncEnabled(true);
sf::RenderTexture target;
if (!target.create(window.getSize().x, window.getSize().y))
return -1;
target.clear(sf::Color::White);
target.display();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::CircleShape circle(5.f, 32u);
circle.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
circle.setFillColor(sf::Color::Red);
target.draw(circle, sf::BlendNone);
target.display();
}
window.clear();
window.draw(sf::Sprite(target.getTexture()));
window.display();
}
}
实际上我遇到了一个我自己无法解决的问题,使用 SFML 我只有一个形状,我将它移动到 每帧,然后我画它。问题是,SFML 使用两个缓冲区,每个缓冲区(帧)上的轨迹都不相同,并且会产生奇怪的闪烁效果。
我需要你的知识,我是否应该找到另一种方法来做到这一点,比如我将扩展的形状数组。或者有没有办法跳过第二个缓冲区?把这个缓冲区做成一张纸,我的形状是画笔。
sf::CircleShape circle;
//Init the circle (radius etc)
sf::Vector2f pos(0, 500);
while(!done)
{
pos.x += 1;
circle.setPosition(pos);
window.draw(circle);
window.display();
}
祝你度过愉快的一天。
双缓冲的目的是避免在 帧渲染期间显示部分未完全渲染的场景 。所以你的问题与双缓冲本身无关。基本上,您每次都需要生成渲染特定帧所需的所有基元。在您的具体情况下,您可以这样实现:
sf::CircleShape circle;
//Init the circle (radius etc)
sf::Vector2f pos(0, 500);
int frameCount = 0;
while(!done)
{
++frameCount;
for (int i = 0; i < frameCount; ++i) {
circle.setPosition(pos + sf::Vector2f(i, 0));
window.draw(circle);
}
window.display();
}
您可以使用 sf::RenderTexture
作为后台缓冲区(单缓冲区)来实现这一点,然后通过 sf::RenderWindow` 在屏幕上绘制
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML art");
window.setVerticalSyncEnabled(true);
sf::RenderTexture target;
if (!target.create(window.getSize().x, window.getSize().y))
return -1;
target.clear(sf::Color::White);
target.display();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::CircleShape circle(5.f, 32u);
circle.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
circle.setFillColor(sf::Color::Red);
target.draw(circle, sf::BlendNone);
target.display();
}
window.clear();
window.draw(sf::Sprite(target.getTexture()));
window.display();
}
}