SFML - Рисуем в 2D
Рисуем в 2D
Введение ===
Как было сказано в предыдущих статьях, модуль SFML, отвечающий за окна, предоставляет простой способ создания окна с OpenGL-контекстом и управления его событиями, но не помогает нам что-либо нарисовать. Он дает единственную возможность, но довольно-таки мощную - рисование с помощью OpenGL API напрямую.
К счастью, SFML предоставляет графический модуль, который вам поможет нарисовать различные 2D объекты более простым способом, чем если бы вы использовали OpenGL.
Окно рисования ===
Для рисования разных вещей нам предоставляется графический модуль, вместе с которым вам нужно использовать специальный класс окна sf::RenderWindow. Этот класс получен от класса sf::Window и содержит все его функции. Все, что вы уже знаете об sf::Window (создание, управление событиями, управление частотой кадров, использование OpenGL), также применимо и к sf::RenderWindow.
В добавок к этому, sf::RenderWindow дает высоко-уровневые функции, которые помогут вам очень просто рисовать разные вещи. В этой статье мы остановимся на двух из этих функций : очищении и рисовании. Они напрямую соответствуют своим названиям : функция очистки экрана очищает всё окно и заливает заданным цветом, а функция рисования рисует любой переданный ей объект.
Ниже представлен типичный главный цикл с окном рисования:
#include <SFML/Graphics.hpp>
int main()
{
// создаем окно
sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
// приложение будет работать, пока окно открыто
while (window.isOpen())
{
// проверяем все события окна, которые были запущены с предыдущей итерации цикла
sf::Event event;
while (window.pollEvent(event))
{
// сработало событие закрытия окна - закроем его
if (event.type == sf::Event::Closed)
window.close();
}
// очищаем окно и заливаем черным цветом
window.clear(sf::Color::Black);
// рисуем что-нибудь здесь
// window.draw(...);
// конец текущего кадра - отображаем
window.display();
}
return 0;
}Вызов очистки перед рисование чего-либо является обязательным, иначе то, что было отображено предыдущим кадром будет нарисовано позади нового кадра и смешается. Исключением является, если вы перерисовываете окно полностью так, что ни один пиксель из предыдущего кадра не будет показан. В этом случае вы можете не вызывать функцию очистки (хотя это и не будет иметь большого влияния на производительность).
Вызов функции рисования также обязателен, он принимает то, что нужно рисовать и отображает это в окне. На самом деле оно не отображается напрямую сразу в окно, а сохраняется в скрытом буфере. Затем этот буфер отображается на экран, когда вы вызываете функцию отображения окна - это называется Двойной буферизацией.
Этот цикл очистки\рисования\отображения - единственный хороший способ рисования различных вещей. Не используйте другую стратегию отрисовки, такие, как сохранение пикселей из предыдущего кадра, перебора пикселей, или одиночного вызова рисования и множественного вызова отображения. Вы получите странные результаты, благодаря двойной буферизации.
Современное графическое оборудование и API создано для постоянных циклов очистки\рисования\отображения, в которых всё полностью очищается на каждой итерации главного цикла. Не бойтесь рисовать 1000 спрайтов 60 раз в секунду, это все равно намного меньше рисования миллионов треугольников, которые ваш компьютер может обработать.
Что мы теперь можем нарисовать? ===
Сейчас, когда главный цикл готов для рисования, давайте посмотрим что и как мы можем в нем нарисовать.
SFML дает возможность рисования 4 разных объектов : 3 из них готовы для рисования (спрайты, текст и фигуры), последний - это всего-лишь блок для строительства ваших собственных объектов (буфер вершин).
Хотя они имеют некоторые общие свойства, каждый из этих объектов поставляются с собственными нюансами, которые описаны в специальных учебных пособиях, которые постепенно будут мной переводиться и ссылки буду даны ниже.
Рисование вне окна ===
SFML также предоставляет способ рисования в текстуру или в окно. Для этого используйте класс sf::RenderTexture, вместо sf::RenderWindow. Он имеет такие же функции для рисования, наследованные от общего класса sf::RenderTarget.
// создаем render-texture размерами 500х500 пикселей
sf::RenderTexture renderTexture;
if (!renderTexture.create(500, 500))
{
// ошибка при создании
}
// все тот же цикл рисования
renderTexture.clear();
renderTexture.draw(sprite); // or any other drawable
renderTexture.display();
// получаем текстуру, в которую все было отрисовано
const sf::Texture& texture = renderTexture.getTexture();
// и рисуем её в окне
sf::Sprite sprite(texture);
window.draw(sprite);Функция getTexture возвращает текстуру "только для чтения", это значит, что вы можете только использовать её, не изменяя. Если вы хотите её изменить, перед использованием, вы можете скопировать её в собственную sf::Texture и изменять её.
Класс sf::RenderTexture также имеет такие же функции, как и sf::RenderWindow для управления видом и OpenGL. Если вы используете OpenGL для рисования в render-texture, вы можете запросить создания буфера глубины с помощью передачи третьего параметра в функцию создания текстуры.
renderTexture.create(500, 500, true); // включаем буфер глубины
Рисуем из потоков ===
SFML поддерживает рисование из нескольких потоков, и вам не потребуется никаких дополнительных усилий, чтобы это работало. Единственная вещь, которую вам следует запомнить - это необходимость деактивировать окно перед использованием в другом потоке. Причиной этой необходимости является то, что окно (благодаря контексту OpenGL) не может быть активно в более, чем одном потоке, в один момент времени.
void renderingThread(sf::RenderWindow* window)
{
// цикл отрисовки
while (window->isOpen())
{
// рисуем
// конец текущего кадра
window->display();
}
}
int main()
{
// создаем окно
sf::RenderWindow window(sf::VideoMode(800, 600), "OpenGL");
// деактивируем контекст OpenGL
window.setActive(false);
// запускаем поток
sf::Thread thread(&renderingThread, &window);
thread.launch();
// обрабатываем события,логику и всё, что угодно, в этом цикле
while (window.isOpen())
{
...
}
return 0;
}Как вы можете видеть, вам не требуется возиться с активацией окна в потоке рисования, SFML делает это за вас автоматически, когда это требуется.
Смотрите также:
Комментарии
а вы можете показать что из этого получится ?
а вы можете показать что из этого получится ?
Из чего именно? Просто цикла рисования? Или рисования в текстуру, с последующим натягиванием на спрайт?
А что с полноэкранным режимом и ресайзом окна?
специальный класс окна sf::RenderWindow. Этот класс получен от класса sf::Window и содержит все его функции. Все, что вы уже знаете об sf::Window (создание, управление событиями, управление частотой кадров, использование OpenGL), также применимо и к sf::RenderWindow.
Kozinaka,
http://devtribe.ru/p/programming/sfml-window
Вот отрисовка обычная

И рендер в текстуру 250х250,затем в спрайт,а спрайт красим в зеленый и рисуем




<a href= http://mosros.flybb.ru/viewtopic.php?f=2&t=635>Процесс получения диплома стоматолога: реально ли это сделать быстро?</a>