Merge pull request #4 from Neirokan/optimize

Fix animation erase, optimize hitbox and glState push/pop
master
Vectozavr 2021-11-06 14:46:07 +07:00 committed by GitHub
commit 33fee79c74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 38 deletions

View File

@ -58,6 +58,8 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
Time::startTimer("d projections"); Time::startTimer("d projections");
if (_useOpenGL) { if (_useOpenGL) {
GLfloat *view = camera->glInvModel(); GLfloat *view = camera->glInvModel();
screen->pushGLStates();
screen->prepareToGlDrawMesh();
for (auto &it : *world) { for (auto &it : *world) {
if (it.second->isVisible()) { if (it.second->isVisible()) {
GLfloat *model = it.second->glModel(); GLfloat *model = it.second->glModel();
@ -66,9 +68,9 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
delete[] model; delete[] model;
} }
} }
screen->popGLStates();
delete[] view; delete[] view;
} else { } else {
screen->pushGLStates();
// clear triangles from previous frame // clear triangles from previous frame
camera->clear(); camera->clear();
// project triangles to the camera plane // project triangles to the camera plane
@ -81,11 +83,9 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
} }
_triPerSec = camera->buffSize() * Time::fps(); _triPerSec = camera->buffSize() * Time::fps();
screen->popGLStates();
} }
Time::stopTimer("d projections"); Time::stopTimer("d projections");
screen->pushGLStates();
if (Consts::SHOW_FPS_COUNTER) { if (Consts::SHOW_FPS_COUNTER) {
screen->drawText(std::to_string(Time::fps()) + " fps", screen->drawText(std::to_string(Time::fps()) + " fps",
Vec2D(static_cast<double>(screen->width()) - 100.0, 10.0), 25, Vec2D(static_cast<double>(screen->width()) - 100.0, 10.0), 25,
@ -93,7 +93,6 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
} }
printDebugInfo(); printDebugInfo();
gui(); gui();
screen->popGLStates();
} }
screen->display(); screen->display();

View File

@ -112,13 +112,14 @@ void Screen::drawText(const sf::Text &text) {
} }
// OpenGL functions // OpenGL functions
void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count) { void Screen::prepareToGlDrawMesh() {
if (!sf::Shader::isAvailable()) if (!sf::Shader::isAvailable())
{ {
Log::log("Shaders are not available!"); Log::log("Shaders are not available!");
} }
sf::Shader::bind(NULL);
glEnable(GL_CULL_FACE); // enable culling face glEnable(GL_CULL_FACE); // enable culling face
glCullFace(GL_BACK); // cull faces from back glCullFace(GL_BACK); // cull faces from back
glFrontFace(GL_CCW); // vertex order (counter clock wise) glFrontFace(GL_CCW); // vertex order (counter clock wise)
@ -147,15 +148,20 @@ void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t
// Enable position and texture coordinates vertex components // Enable position and texture coordinates vertex components
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 7 * sizeof(GLfloat), geometry);
glColorPointer(4, GL_FLOAT, 7 * sizeof(GLfloat), geometry + 3);
// Disable normal and color vertex components // Disable normal and color vertex components
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// Apply some transformations // Prepare to apply some transformations
glMatrixMode(GL_MODELVIEW); 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);
glLoadIdentity(); glLoadIdentity();
glLoadMatrixf(view); glLoadMatrixf(view);
@ -163,6 +169,4 @@ void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t
// Draw the mesh // Draw the mesh
glDrawArrays(GL_TRIANGLES, 0, count); glDrawArrays(GL_TRIANGLES, 0, count);
sf::Shader::bind(NULL);
} }

View File

@ -60,6 +60,8 @@ public:
void setMouseCursorVisible(bool visible); void setMouseCursorVisible(bool visible);
// OpenGL functions // OpenGL functions
void prepareToGlDrawMesh();
void glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count); void glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count);
[[nodiscard]] std::shared_ptr<sf::RenderWindow> renderWindow() { return _window; } [[nodiscard]] std::shared_ptr<sf::RenderWindow> renderWindow() { return _window; }

View File

@ -70,16 +70,12 @@ void Timeline::update() {
return; return;
} }
// TODO: sometimes I catch an exception here: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) for (auto iter = _instance->_animations.begin(); iter != _instance->_animations.end(); ) {
for (auto&[listName, animationList] : _instance->_animations) { if (iter->second.empty()) {
if (animationList.empty()) { _instance->_animations.erase(iter++);
/*
* TODO If you delete this line you will not catch an exception.
* Maybe something wrong with std::map::erase()
*/
_instance->_animations.erase(listName);
continue; continue;
} }
auto& animationList = iter->second;
auto it = animationList.begin(); auto it = animationList.begin();
// If it the front animation is 'a_wait()' we should wait until waiting time is over // If it the front animation is 'a_wait()' we should wait until waiting time is over
@ -98,6 +94,7 @@ void Timeline::update() {
it++; it++;
} }
} }
iter++;
} }
} }

View File

@ -18,7 +18,6 @@ void Window::addButton(int x, int y, int w, int h, std::function<void()> click,
void Window::update() { void Window::update() {
_screen->pushGLStates();
_screen->setTitle(_name); _screen->setTitle(_name);
_screen->drawSprite(_back); _screen->drawSprite(_back);
@ -46,7 +45,6 @@ void Window::update() {
_screen->drawText(button.text()); _screen->drawText(button.text());
} }
} }
_screen->popGLStates();
} }
void Window::setBackgroundTexture(const std::string &texture, double sx, double sy, int w, int h) { void Window::setBackgroundTexture(const std::string &texture, double sx, double sy, int w, int h) {

View File

@ -2,30 +2,36 @@
// Created by Иван Ильин on 04.11.2021. // Created by Иван Ильин on 04.11.2021.
// //
#include <algorithm> #include <set>
#include "HitBox.h" #include "HitBox.h"
#include "../Consts.h"
bool HitBox::Vec3DLess::operator()(const Vec3D& lhs, const Vec3D& rhs) const noexcept {
if (fabs(lhs.x() - rhs.x()) >= Consts::EPS)
return lhs.x() < rhs.x();
else if (fabs(lhs.y() - rhs.y()) >= Consts::EPS)
return lhs.y() < rhs.y();
else if (fabs(lhs.z() - rhs.z()) >= Consts::EPS)
return lhs.z() < rhs.z();
else
return false;
}
HitBox::HitBox(const Mesh& mesh) { HitBox::HitBox(const Mesh& mesh) {
_hitBox.reserve(mesh.triangles().size() * 3);
for(const auto& t : mesh.triangles()) {
for(int i = 0; i < 3; i++) {
// we dont need to add the same points in hit box // we dont need to add the same points in hit box
_addIfUnique(Vec3D(t[i])); std::set<Vec3D, HitBox::Vec3DLess> points;
}
} for (const auto& t : mesh.triangles())
for (int i = 0; i < 3; i++)
points.insert(Vec3D(t[i]));
_hitBox.reserve(points.size());
for (const auto& it : points)
_hitBox.push_back(it);
_hitBox.shrink_to_fit(); _hitBox.shrink_to_fit();
} }
void HitBox::_addIfUnique(Vec3D &&point) {
auto check = [&point](const auto& p) { return p == point; };
if (std::find_if(_hitBox.rbegin(), _hitBox.rend(), check) == _hitBox.rend()) {
_hitBox.push_back(point);
}
}
HitBox HitBox::Box(const Mesh &mesh) { HitBox HitBox::Box(const Mesh &mesh) {
HitBox result; HitBox result;

View File

@ -9,9 +9,11 @@
class HitBox final { class HitBox final {
private: private:
std::vector<Vec3D> _hitBox; struct Vec3DLess {
bool operator()(const Vec3D& lhs, const Vec3D& rhs) const noexcept;
};
void _addIfUnique(Vec3D &&point); std::vector<Vec3D> _hitBox;
public: public:
HitBox() = default; HitBox() = default;