From f07f9a663895f59edb13ed15213c9c8090f0cb7b Mon Sep 17 00:00:00 2001 From: Neirokan Date: Sat, 6 Nov 2021 00:28:55 +0300 Subject: [PATCH 1/3] Hitbox creation through set --- engine/physics/HitBox.cpp | 36 +++++++++++++++++++++--------------- engine/physics/HitBox.h | 6 ++++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/engine/physics/HitBox.cpp b/engine/physics/HitBox.cpp index 8bdfa4d..64564c1 100644 --- a/engine/physics/HitBox.cpp +++ b/engine/physics/HitBox.cpp @@ -2,28 +2,34 @@ // Created by Иван Ильин on 04.11.2021. // -#include +#include #include "HitBox.h" +#include "../Consts.h" -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 - _addIfUnique(Vec3D(t[i])); - } - } - _hitBox.shrink_to_fit(); +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; } -void HitBox::_addIfUnique(Vec3D &&point) { +HitBox::HitBox(const Mesh& mesh) { + // we dont need to add the same points in hit box + std::set points; - auto check = [&point](const auto& p) { return p == point; }; + for (const auto& t : mesh.triangles()) + for (int i = 0; i < 3; i++) + points.insert(Vec3D(t[i])); - if (std::find_if(_hitBox.rbegin(), _hitBox.rend(), check) == _hitBox.rend()) { - _hitBox.push_back(point); - } + _hitBox.reserve(points.size()); + for (const auto& it : points) + _hitBox.push_back(it); + _hitBox.shrink_to_fit(); } HitBox HitBox::Box(const Mesh &mesh) { diff --git a/engine/physics/HitBox.h b/engine/physics/HitBox.h index eda1e6e..c48fdcf 100644 --- a/engine/physics/HitBox.h +++ b/engine/physics/HitBox.h @@ -9,9 +9,11 @@ class HitBox final { private: - std::vector _hitBox; + struct Vec3DLess { + bool operator()(const Vec3D& lhs, const Vec3D& rhs) const noexcept; + }; - void _addIfUnique(Vec3D &&point); + std::vector _hitBox; public: HitBox() = default; From dd307749bea649c355ecf66ab7c879ab4dfcc769 Mon Sep 17 00:00:00 2001 From: Neirokan Date: Sat, 6 Nov 2021 00:31:41 +0300 Subject: [PATCH 2/3] Animation timeline erase fix --- engine/animation/Timeline.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/engine/animation/Timeline.cpp b/engine/animation/Timeline.cpp index 7109559..947b0e6 100644 --- a/engine/animation/Timeline.cpp +++ b/engine/animation/Timeline.cpp @@ -70,16 +70,12 @@ void Timeline::update() { return; } - // TODO: sometimes I catch an exception here: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) - for (auto&[listName, animationList] : _instance->_animations) { - if (animationList.empty()) { - /* - * TODO If you delete this line you will not catch an exception. - * Maybe something wrong with std::map::erase() - */ - _instance->_animations.erase(listName); + for (auto iter = _instance->_animations.begin(); iter != _instance->_animations.end(); ) { + if (iter->second.empty()) { + _instance->_animations.erase(iter++); continue; } + auto& animationList = iter->second; auto it = animationList.begin(); // If it the front animation is 'a_wait()' we should wait until waiting time is over @@ -98,6 +94,7 @@ void Timeline::update() { it++; } } + iter++; } } From 57203991beef548ae42a54e320296149b22836d8 Mon Sep 17 00:00:00 2001 From: Neirokan Date: Sat, 6 Nov 2021 00:34:13 +0300 Subject: [PATCH 3/3] Move push/pop GL state calls You can place it around your OpenGL code too. --- engine/Engine.cpp | 7 +++---- engine/Screen.cpp | 18 +++++++++++------- engine/Screen.h | 2 ++ engine/gui/Window.cpp | 2 -- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/engine/Engine.cpp b/engine/Engine.cpp index 52de232..4a089ba 100644 --- a/engine/Engine.cpp +++ b/engine/Engine.cpp @@ -58,6 +58,8 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name, Time::startTimer("d projections"); if (_useOpenGL) { GLfloat *view = camera->glInvModel(); + screen->pushGLStates(); + screen->prepareToGlDrawMesh(); for (auto &it : *world) { if (it.second->isVisible()) { GLfloat *model = it.second->glModel(); @@ -66,9 +68,9 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name, delete[] model; } } + screen->popGLStates(); delete[] view; } else { - screen->pushGLStates(); // clear triangles from previous frame camera->clear(); // 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(); - screen->popGLStates(); } Time::stopTimer("d projections"); - screen->pushGLStates(); if (Consts::SHOW_FPS_COUNTER) { screen->drawText(std::to_string(Time::fps()) + " fps", Vec2D(static_cast(screen->width()) - 100.0, 10.0), 25, @@ -93,7 +93,6 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name, } printDebugInfo(); gui(); - screen->popGLStates(); } screen->display(); diff --git a/engine/Screen.cpp b/engine/Screen.cpp index b0818b2..27192fb 100644 --- a/engine/Screen.cpp +++ b/engine/Screen.cpp @@ -112,13 +112,14 @@ void Screen::drawText(const sf::Text &text) { } // OpenGL functions -void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count) { - +void Screen::prepareToGlDrawMesh() { if (!sf::Shader::isAvailable()) { Log::log("Shaders are not available!"); } + sf::Shader::bind(NULL); + glEnable(GL_CULL_FACE); // enable culling face glCullFace(GL_BACK); // cull faces from back 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 glEnableClientState(GL_VERTEX_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 glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); - // Apply some transformations + // Prepare to apply some transformations 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(); glLoadMatrixf(view); @@ -163,6 +169,4 @@ void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t // Draw the mesh glDrawArrays(GL_TRIANGLES, 0, count); - - sf::Shader::bind(NULL); } diff --git a/engine/Screen.h b/engine/Screen.h index 6bfd820..ad5fb69 100644 --- a/engine/Screen.h +++ b/engine/Screen.h @@ -60,6 +60,8 @@ public: void setMouseCursorVisible(bool visible); // OpenGL functions + void prepareToGlDrawMesh(); + void glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count); [[nodiscard]] std::shared_ptr renderWindow() { return _window; } diff --git a/engine/gui/Window.cpp b/engine/gui/Window.cpp index f6251ae..9a09282 100644 --- a/engine/gui/Window.cpp +++ b/engine/gui/Window.cpp @@ -18,7 +18,6 @@ void Window::addButton(int x, int y, int w, int h, std::function click, void Window::update() { - _screen->pushGLStates(); _screen->setTitle(_name); _screen->drawSprite(_back); @@ -46,7 +45,6 @@ void Window::update() { _screen->drawText(button.text()); } } - _screen->popGLStates(); } void Window::setBackgroundTexture(const std::string &texture, double sx, double sy, int w, int h) {