2021-09-13 15:53:43 +03:00
|
|
|
//
|
|
|
|
// Created by Иван Ильин on 14.01.2021.
|
|
|
|
//
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
#include <iostream>
|
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
#include "Engine.h"
|
|
|
|
#include "utils/Time.h"
|
|
|
|
#include "ResourceManager.h"
|
2021-10-02 21:17:03 +03:00
|
|
|
#include "animation/Timeline.h"
|
2021-10-17 19:38:16 +03:00
|
|
|
#include "SoundController.h"
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
Engine::Engine() {
|
2021-10-17 19:38:16 +03:00
|
|
|
Time::init();
|
|
|
|
Timeline::init();
|
|
|
|
ResourceManager::init();
|
|
|
|
SoundController::init();
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
void Engine::create(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background,
|
|
|
|
sf::Uint32 style) {
|
2021-09-19 11:25:10 +03:00
|
|
|
_name = name;
|
2021-09-13 15:53:43 +03:00
|
|
|
screen->open(screenWidth, screenHeight, name, verticalSync, background, style);
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
Log::log("Engine::create(): started engine (" + std::to_string(screenWidth) + "x" + std::to_string(screenHeight) +
|
|
|
|
") with title '" + name + "'.");
|
2021-09-13 15:53:43 +03:00
|
|
|
Time::update();
|
|
|
|
|
|
|
|
start();
|
|
|
|
camera->init(screenWidth, screenHeight);
|
|
|
|
|
|
|
|
while (screen->isOpen()) {
|
2021-11-03 11:19:01 +03:00
|
|
|
// 'd' in the beginning of the name means debug.
|
|
|
|
// While printing debug info we will take into account only timer names witch start with 'd '
|
|
|
|
Time::startTimer("d all");
|
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
screen->clear();
|
|
|
|
|
|
|
|
Time::update();
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
Time::startTimer("d game update");
|
2021-09-19 11:25:10 +03:00
|
|
|
update();
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::stopTimer("d game update");
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
// sometimes we dont need to update physics world
|
|
|
|
// (for example in menu or while pause)
|
2021-09-19 11:25:10 +03:00
|
|
|
// hence we can set '_updateWorld' equal to false in setUpdateWorld(bool):
|
2021-10-31 11:39:08 +03:00
|
|
|
if (_updateWorld) {
|
2021-09-13 15:53:43 +03:00
|
|
|
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::startTimer("d animations");
|
2021-10-02 21:17:03 +03:00
|
|
|
Timeline::update();
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::stopTimer("d animations");
|
2021-09-19 11:25:10 +03:00
|
|
|
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::startTimer("d collisions");
|
2021-09-19 11:25:10 +03:00
|
|
|
world->update();
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::stopTimer("d collisions");
|
2021-09-13 15:53:43 +03:00
|
|
|
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::startTimer("d projections");
|
2021-10-31 11:39:08 +03:00
|
|
|
if (_useOpenGL) {
|
|
|
|
GLfloat *view = camera->glView();
|
|
|
|
for (auto &it : *world) {
|
2021-10-22 19:42:32 +03:00
|
|
|
if (it.second->isVisible()) {
|
2021-10-31 11:39:08 +03:00
|
|
|
GLfloat *model = it.second->glModel();
|
2021-11-05 00:05:06 +03:00
|
|
|
GLfloat *geometry = Screen::glMeshToGLfloatArray(it.second);
|
2021-10-29 23:44:37 +03:00
|
|
|
screen->glDrawMesh(geometry, view, model, 3 * it.second->triangles().size());
|
2021-11-04 04:32:15 +03:00
|
|
|
delete[] geometry;
|
|
|
|
delete[] model;
|
2021-10-22 19:42:32 +03:00
|
|
|
}
|
|
|
|
}
|
2021-11-04 04:32:15 +03:00
|
|
|
delete[] view;
|
2021-10-22 19:42:32 +03:00
|
|
|
} else {
|
|
|
|
// clear triangles from previous frame
|
|
|
|
camera->clear();
|
|
|
|
// project triangles to the camera plane
|
2021-10-31 11:39:08 +03:00
|
|
|
for (auto &it : *world) {
|
2021-10-22 19:42:32 +03:00
|
|
|
camera->project(it.second);
|
2021-10-28 16:58:02 +03:00
|
|
|
}
|
2021-10-22 19:42:32 +03:00
|
|
|
// draw triangles on the screen
|
2021-10-28 16:58:02 +03:00
|
|
|
for (auto &t : camera->sorted()) {
|
2021-10-22 19:42:32 +03:00
|
|
|
screen->drawTriangle(*t);
|
2021-10-28 16:58:02 +03:00
|
|
|
}
|
2021-10-22 19:42:32 +03:00
|
|
|
|
|
|
|
_triPerSec = camera->buffSize() * Time::fps();
|
|
|
|
}
|
2021-11-03 11:19:01 +03:00
|
|
|
Time::stopTimer("d projections");
|
2021-09-19 11:25:10 +03:00
|
|
|
|
2021-11-05 21:28:04 +03:00
|
|
|
screen->pushGLStates();
|
2021-10-30 12:39:44 +03:00
|
|
|
if (Consts::SHOW_FPS_COUNTER) {
|
2021-11-03 11:19:01 +03:00
|
|
|
screen->drawText(std::to_string(Time::fps()) + " fps",
|
|
|
|
Vec2D(static_cast<double>(screen->width()) - 100.0, 10.0), 25,
|
2021-10-31 11:39:08 +03:00
|
|
|
sf::Color(100, 100, 100));
|
2021-10-30 12:39:44 +03:00
|
|
|
}
|
2021-11-03 11:19:01 +03:00
|
|
|
printDebugInfo();
|
2021-09-19 11:25:10 +03:00
|
|
|
gui();
|
2021-11-05 21:28:04 +03:00
|
|
|
screen->popGLStates();
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
screen->display();
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
Time::stopTimer("d all");
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Engine::exit() {
|
2021-10-31 11:39:08 +03:00
|
|
|
if (screen->isOpen()) {
|
2021-09-13 15:53:43 +03:00
|
|
|
screen->close();
|
|
|
|
}
|
2021-10-17 19:38:16 +03:00
|
|
|
SoundController::free();
|
|
|
|
ResourceManager::free();
|
|
|
|
Timeline::free();
|
|
|
|
Time::free();
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + "x" +
|
2021-10-31 13:00:38 +03:00
|
|
|
std::to_string(screen->height()) + ") with title '" + screen->title() + "'.");
|
2021-09-19 11:25:10 +03:00
|
|
|
}
|
|
|
|
|
2021-11-03 11:19:01 +03:00
|
|
|
void Engine::printDebugInfo() const {
|
2021-10-30 12:39:44 +03:00
|
|
|
|
2021-11-03 11:19:01 +03:00
|
|
|
if (_showDebugInfo) {
|
|
|
|
// coordinates & fps:
|
2021-10-30 12:39:44 +03:00
|
|
|
std::string text = _name + "\n\n X: " +
|
2021-10-31 11:39:08 +03:00
|
|
|
std::to_string((camera->position().x())) + "\n Y: " +
|
|
|
|
std::to_string((camera->position().y())) + "\n Z: " +
|
|
|
|
std::to_string((camera->position().z())) + "\n\n" +
|
|
|
|
std::to_string(screen->width()) + "x" +
|
|
|
|
std::to_string(screen->height()) + "\t" +
|
|
|
|
std::to_string(Time::fps()) + " fps";
|
|
|
|
if (_useOpenGL) {
|
2021-10-30 12:39:44 +03:00
|
|
|
text += "\n Using OpenGL acceleration";
|
2021-10-22 19:42:32 +03:00
|
|
|
} else {
|
2021-11-03 11:19:01 +03:00
|
|
|
text += "\n" + std::to_string(_triPerSec) + " tris/s";
|
2021-10-22 19:42:32 +03:00
|
|
|
}
|
2021-10-30 12:39:44 +03:00
|
|
|
|
|
|
|
sf::Text t;
|
|
|
|
|
|
|
|
t.setFont(*ResourceManager::loadFont(Consts::THIN_FONT));
|
|
|
|
t.setString(text);
|
|
|
|
t.setCharacterSize(30);
|
|
|
|
t.setFillColor(sf::Color::Black);
|
2021-10-31 13:00:38 +03:00
|
|
|
t.setPosition(static_cast<float>(screen->width()) - 400.0f, 10.0f);
|
2021-10-30 12:39:44 +03:00
|
|
|
|
|
|
|
screen->drawText(t);
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
// timers:
|
|
|
|
int timerWidth = screen->width() - 100;
|
|
|
|
float xPos = 50;
|
|
|
|
float yPos = 300;
|
|
|
|
int height = 50;
|
|
|
|
|
|
|
|
double totalTime = Time::elapsedTimerMilliseconds("d all");
|
|
|
|
double timeSum = 0;
|
|
|
|
int i = 0;
|
|
|
|
for (auto &[timerName, timer] : Time::timers()) {
|
|
|
|
int width = timerWidth * timer.elapsedMilliseconds() / totalTime;
|
|
|
|
|
|
|
|
if (timerName == "d all" || timerName[0] != 'd') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
screen->drawTetragon(Vec2D{xPos, yPos + height * i},
|
|
|
|
Vec2D{xPos + width, yPos + height * i},
|
|
|
|
Vec2D{xPos + width, yPos + height + height * i},
|
|
|
|
Vec2D{xPos, yPos + height + height * i},
|
2021-11-05 13:16:00 +03:00
|
|
|
{static_cast<sf::Uint8>(255.0 * static_cast<double>(width) / timerWidth),
|
|
|
|
static_cast<sf::Uint8>(255.0 * (1.0 - static_cast<double>(width) / timerWidth)),
|
2021-11-05 21:28:04 +03:00
|
|
|
0, 100});
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
|
|
|
|
screen->drawText(
|
2021-11-03 12:25:09 +03:00
|
|
|
timerName.substr(2, timerName.size()) + ":\t" +
|
|
|
|
std::to_string((int) (1.0 / timer.elapsedMilliseconds())) + " / s \t (" +
|
|
|
|
std::to_string((int) (100 * timer.elapsedMilliseconds() / totalTime)) + "%)",
|
2021-11-03 11:19:01 +03:00
|
|
|
Vec2D{xPos + 10, yPos + height * i + 5}, 30,
|
2021-11-05 21:28:04 +03:00
|
|
|
sf::Color(0, 0, 0, 150));
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
i++;
|
|
|
|
timeSum += timer.elapsedMilliseconds();
|
|
|
|
}
|
|
|
|
|
|
|
|
int width = timerWidth * (totalTime - timeSum) / totalTime;
|
|
|
|
screen->drawTetragon(Vec2D{xPos, yPos + height * i},
|
|
|
|
Vec2D{xPos + width, yPos + height * i},
|
|
|
|
Vec2D{xPos + width, yPos + height + height * i},
|
|
|
|
Vec2D{xPos, yPos + height + height * i},
|
2021-11-05 13:16:00 +03:00
|
|
|
{static_cast<sf::Uint8>(255.0 * static_cast<double>(width) / timerWidth),
|
|
|
|
static_cast<sf::Uint8>(255.0 * (1.0 - static_cast<double>(width) / timerWidth)),
|
2021-11-05 21:28:04 +03:00
|
|
|
0, 100});
|
2021-11-03 11:19:01 +03:00
|
|
|
|
|
|
|
|
2021-11-03 12:25:09 +03:00
|
|
|
screen->drawText("other:\t" + std::to_string((int) (1.0 / (totalTime - timeSum))) + " / s \t (" +
|
|
|
|
std::to_string((int) (100 * (totalTime - timeSum) / totalTime)) + "%)",
|
2021-11-03 11:19:01 +03:00
|
|
|
Vec2D{xPos + 10, yPos + height * i + 5}, 30,
|
2021-11-05 21:28:04 +03:00
|
|
|
sf::Color(0, 0, 0, 150));
|
2021-11-03 11:19:01 +03:00
|
|
|
|
2021-09-19 11:25:10 +03:00
|
|
|
}
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|