vectozavr-shooter/engine/io/Screen.cpp

210 lines
6.6 KiB
C++
Raw Normal View History

2021-09-13 15:53:43 +03:00
//
// Created by Иван Ильин on 14.01.2021.
//
2021-10-31 11:39:08 +03:00
#include <utility>
#include <cmath>
#include <SFML/OpenGL.hpp>
2021-09-13 15:53:43 +03:00
#include "Screen.h"
2022-07-11 16:58:05 +03:00
#include "../utils/Time.h"
#include "../utils/Log.h"
#include "../utils/ResourceManager.h"
2021-09-13 15:53:43 +03:00
2021-10-31 11:39:08 +03:00
void Screen::open(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background,
sf::Uint32 style) {
_title = name;
_background = background;
2021-09-13 15:53:43 +03:00
sf::ContextSettings settings;
settings.depthBits = 12;
settings.antialiasingLevel = 1;
2021-09-13 15:53:43 +03:00
2021-10-31 19:01:06 +03:00
_window->create(sf::VideoMode(screenWidth, screenHeight), name, style, settings);
_window->setVerticalSyncEnabled(verticalSync);
2021-09-13 15:53:43 +03:00
}
void Screen::display() {
sf::Event event{};
while (_window->pollEvent(event)) {
2021-09-13 15:53:43 +03:00
if (event.type == sf::Event::Closed) {
_window->close();
2021-09-13 15:53:43 +03:00
}
}
std::string title = _title + " (" + std::to_string(Time::fps()) + " fps)";
_window->setTitle(title);
2021-09-13 15:53:43 +03:00
2021-11-11 22:47:00 +03:00
if(_renderVideo) {
sf::Texture copyTexture;
copyTexture.create(_window->getSize().x, _window->getSize().y);
copyTexture.update(*_window);
2021-11-11 23:03:21 +03:00
// most of the time of video rendering is wasting on saving .png sequence
2021-11-11 22:47:00 +03:00
// that's why we will save all images in the end
// TODO: sometimes we have a huge time delay here for no obvious reason
_renderSequence.push_back(copyTexture);
}
_window->display();
2021-09-13 15:53:43 +03:00
}
2021-11-11 22:47:00 +03:00
void Screen::startRender() {
stopRender();
2021-11-12 11:41:26 +03:00
Log::log("Screen::startRender(): start recording the screen");
2021-11-11 22:47:00 +03:00
_renderVideo = true;
}
void Screen::stopRender() {
if(_renderVideo) {
2021-11-12 11:41:26 +03:00
Log::log("Screen::stopRender(): stop recording the screen");
Log::log("Screen::stopRender(): start saving .png sequence");
std::string c = "rm film/png/*.png";
popen(c.c_str(), "w");
2021-11-11 22:47:00 +03:00
int i = 0;
for(; i < _renderSequence.size(); i++) {
_renderSequence[i].copyToImage().saveToFile("film/png/" + std::to_string(i) + ".png");
2021-11-12 11:41:26 +03:00
Log::log("Screen::stopRender(): saving .png sequence (" + std::to_string(static_cast<int>(100*i/_renderSequence.size())) + "%)");
2021-11-11 22:47:00 +03:00
}
_renderSequence.clear();
2021-11-12 11:41:26 +03:00
Log::log("Screen::stopRender(): start rendering final video");
2021-11-11 23:03:21 +03:00
// TODO: .png sequence looks better than a final video (poor clarity and desaturated colors)
2021-11-12 11:41:26 +03:00
c = "ffmpeg -stats -r 60 -i film/png/%d.png -vcodec libx264 -crf 1 -pix_fmt yuv420p -frames " + std::to_string(i) + " film/mp4/" + std::to_string(_scene) + "_" + _title + "_" + std::to_string(rand()) + ".mp4";
2021-11-11 22:47:00 +03:00
popen(c.c_str(), "w");
_scene++;
_renderVideo = false;
2021-11-12 11:41:26 +03:00
Log::log("Screen::stopRender(): finish rendering final video");
2021-11-11 22:47:00 +03:00
}
}
2021-09-13 15:53:43 +03:00
void Screen::clear() {
2021-10-22 19:42:32 +03:00
// Clear the depth buffer
2022-07-11 16:58:05 +03:00
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2021-10-22 19:42:32 +03:00
_window->clear(_background);
2021-09-13 15:53:43 +03:00
}
2021-10-31 11:39:08 +03:00
void Screen::drawTriangle(const Triangle &triangle) {
2021-09-13 15:53:43 +03:00
sf::Vertex tris[3] =
{
2021-10-31 12:01:31 +03:00
sf::Vertex(sf::Vector2f(static_cast<float>(triangle[0].x()), static_cast<float>(triangle[0].y())),
triangle.color()),
sf::Vertex(sf::Vector2f(static_cast<float>(triangle[1].x()), static_cast<float>(triangle[1].y())),
triangle.color()),
sf::Vertex(sf::Vector2f(static_cast<float>(triangle[2].x()), static_cast<float>(triangle[2].y())),
triangle.color())
2021-09-13 15:53:43 +03:00
};
2021-10-22 19:42:32 +03:00
_window->draw(tris, 3, sf::Triangles);
2021-09-13 15:53:43 +03:00
}
2021-10-31 11:39:08 +03:00
void Screen::setTitle(const std::string &title) {
_title = title;
2021-09-13 15:53:43 +03:00
}
bool Screen::isOpen() {
return _window->isOpen();
2021-09-13 15:53:43 +03:00
}
void Screen::close() {
_window->close();
2021-09-13 15:53:43 +03:00
}
2021-10-28 16:58:02 +03:00
void Screen::setMouseCursorVisible(bool visible) {
_window->setMouseCursorVisible(visible);
}
void Screen::drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, const Vec2D &p4, sf::Color color) {
sf::ConvexShape polygon;
polygon.setPointCount(4);
2021-10-31 12:01:31 +03:00
polygon.setPoint(0, sf::Vector2f(static_cast<float>(p1.x()), static_cast<float>(p1.y())));
polygon.setPoint(1, sf::Vector2f(static_cast<float>(p2.x()), static_cast<float>(p2.y())));
polygon.setPoint(2, sf::Vector2f(static_cast<float>(p3.x()), static_cast<float>(p3.y())));
polygon.setPoint(3, sf::Vector2f(static_cast<float>(p4.x()), static_cast<float>(p4.y())));
polygon.setFillColor(color);
2021-10-22 19:42:32 +03:00
_window->draw(polygon);
2021-09-13 15:53:43 +03:00
}
2021-10-31 11:39:08 +03:00
void Screen::drawText(const std::string &string, const Vec2D &position, int size, sf::Color color) {
sf::Text text;
2021-09-13 15:53:43 +03:00
2021-10-16 20:22:55 +03:00
text.setFont(*ResourceManager::loadFont(Consts::MEDIUM_FONT));
2021-09-13 15:53:43 +03:00
text.setCharacterSize(size);
text.setFillColor(color);
text.setStyle(sf::Text::Italic);
2021-10-31 12:01:31 +03:00
text.setPosition(static_cast<float>(position.x()), static_cast<float>(position.y()));
2021-09-13 15:53:43 +03:00
text.setString(string);
2021-10-22 19:42:32 +03:00
_window->draw(text);
2021-09-13 15:53:43 +03:00
}
void Screen::drawSprite(const sf::Sprite &sprite) {
_window->draw(sprite);
}
2021-09-13 15:53:43 +03:00
void Screen::drawText(const sf::Text &text) {
_window->draw(text);
}
2021-09-13 15:53:43 +03:00
2021-10-22 19:42:32 +03:00
// OpenGL functions
void Screen::prepareToGlDrawMesh() {
2021-10-22 19:42:32 +03:00
glEnable(GL_CULL_FACE); // enable culling face
glCullFace(GL_BACK); // cull faces from back
glFrontFace(GL_CCW); // vertex order (counter clock wise)
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.f);
2022-07-11 16:58:05 +03:00
glDepthFunc(GL_LESS);
2021-10-22 19:42:32 +03:00
// Disable lighting
glDisable(GL_LIGHTING);
// enable alpha channel:
2022-07-11 16:58:05 +03:00
//glEnable( GL_ALPHA_TEST );
//glAlphaFunc(GL_NOTEQUAL, 0.0);
//
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2021-10-22 19:42:32 +03:00
// Configure the viewport (the same size as the window)
glViewport(0, 0, _window->getSize().x, _window->getSize().y);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat ratio = static_cast<float>(_window->getSize().x) / _window->getSize().y;
glFrustum(-ratio, ratio, -1.f, 1.f, 1.0f, 500.f);
// Enable position and texture coordinates vertex components
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Disable normal and color vertex components
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// Prepare to apply some transformations
2021-10-22 19:42:32 +03:00
glMatrixMode(GL_MODELVIEW);
}
// OpenGL functions
void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, GLfloat* model, size_t count) {
glVertexPointer(3, GL_FLOAT, 7 * sizeof(GLfloat), geometry);
glColorPointer(4, GL_FLOAT, 7 * sizeof(GLfloat), geometry + 3);
2021-10-22 19:42:32 +03:00
glLoadIdentity();
glLoadMatrixf(view);
glMultMatrixf(model);
2021-10-22 19:42:32 +03:00
// Draw the mesh
glDrawArrays(GL_TRIANGLES, 0, count);
}