From ea1a18004f9265cbb75ff082fc73cfe35103bbb9 Mon Sep 17 00:00:00 2001 From: Skarn Date: Wed, 14 Oct 2020 03:29:03 +0300 Subject: [PATCH] who the fuck decided to recompile bounding box shader on every tick??? --- src/noggit/ModelInstance.cpp | 56 ++++++------ src/noggit/ModelInstance.h | 1 + src/noggit/WMO.cpp | 27 +++--- src/noggit/WMO.h | 1 + src/noggit/WMOInstance.cpp | 3 +- src/opengl/primitives.cpp | 166 +++++++++++++++++++++-------------- src/opengl/primitives.hpp | 23 +++-- src/opengl/shader.cpp | 4 + src/opengl/shader.hpp | 1 + 9 files changed, 166 insertions(+), 116 deletions(-) diff --git a/src/noggit/ModelInstance.cpp b/src/noggit/ModelInstance.cpp index da8a8bbd..6196ccc1 100644 --- a/src/noggit/ModelInstance.cpp +++ b/src/noggit/ModelInstance.cpp @@ -53,39 +53,39 @@ void ModelInstance::draw_box ( math::matrix_4x4 const& model_view if (is_current_selection) { - opengl::primitives::wire_box ( misc::transform_model_box_coords(model->header.collision_box_min) - , misc::transform_model_box_coords(model->header.collision_box_max) - ).draw ( model_view - , projection - , transform_matrix_transposed() - , { 1.0f, 1.0f, 0.0f, 1.0f } - ); + opengl::primitives::wire_box::getInstance().draw ( model_view + , projection + , transform_matrix_transposed() + , { 1.0f, 1.0f, 0.0f, 1.0f } + , misc::transform_model_box_coords(model->header.collision_box_min) + , misc::transform_model_box_coords(model->header.collision_box_max) + ); - opengl::primitives::wire_box ( misc::transform_model_box_coords(model->header.bounding_box_min) - , misc::transform_model_box_coords(model->header.bounding_box_max) - ).draw ( model_view - , projection - , transform_matrix_transposed() - , {1.0f, 1.0f, 1.0f, 1.0f} - ); + opengl::primitives::wire_box::getInstance().draw ( model_view + , projection + , transform_matrix_transposed() + , {1.0f, 1.0f, 1.0f, 1.0f} + , misc::transform_model_box_coords(model->header.bounding_box_min) + , misc::transform_model_box_coords(model->header.bounding_box_max) + ); - opengl::primitives::wire_box ( _extents[0] - , _extents[1] - ).draw ( model_view - , projection - , math::matrix_4x4(math::matrix_4x4::unit) - , {0.0f, 1.0f, 0.0f, 1.0f} - ); + opengl::primitives::wire_box::getInstance().draw ( model_view + , projection + , math::matrix_4x4(math::matrix_4x4::unit) + , {0.0f, 1.0f, 0.0f, 1.0f} + , _extents[0] + , _extents[1] + ); } else { - opengl::primitives::wire_box ( misc::transform_model_box_coords(model->header.bounding_box_min) - , misc::transform_model_box_coords(model->header.bounding_box_max) - ).draw ( model_view - , projection - , transform_matrix_transposed() - , {0.5f, 0.5f, 0.5f, 1.0f} - ); + opengl::primitives::wire_box::getInstance().draw ( model_view + , projection + , transform_matrix_transposed() + , {0.5f, 0.5f, 0.5f, 1.0f} + , misc::transform_model_box_coords(model->header.bounding_box_min) + , misc::transform_model_box_coords(model->header.bounding_box_max) + ); } } diff --git a/src/noggit/ModelInstance.h b/src/noggit/ModelInstance.h index 66593bd4..76db8f41 100644 --- a/src/noggit/ModelInstance.h +++ b/src/noggit/ModelInstance.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace math { class frustum; } class Model; diff --git a/src/noggit/WMO.cpp b/src/noggit/WMO.cpp index 055decb1..f1844608 100644 --- a/src/noggit/WMO.cpp +++ b/src/noggit/WMO.cpp @@ -368,21 +368,22 @@ void WMO::draw ( opengl::scoped::use_program& wmo_shader for (auto& group : groups) { - opengl::primitives::wire_box(group.BoundingBoxMin, group.BoundingBoxMax) - .draw( model_view - , projection - , transform_matrix_transposed - , {1.0f, 1.0f, 1.0f, 1.0f} - ); + opengl::primitives::wire_box::getInstance().draw( model_view + , projection + , transform_matrix_transposed + , {1.0f, 1.0f, 1.0f, 1.0f} + , group.BoundingBoxMin + , group.BoundingBoxMax + ); } - opengl::primitives::wire_box ( math::vector_3d(extents[0].x, extents[0].z, -extents[0].y) - , math::vector_3d(extents[1].x, extents[1].z, -extents[1].y) - ).draw ( model_view - , projection - , transform_matrix_transposed - , {1.0f, 0.0f, 0.0f, 1.0f} - ); + opengl::primitives::wire_box::getInstance().draw ( model_view + , projection + , transform_matrix_transposed + , {1.0f, 0.0f, 0.0f, 1.0f} + , math::vector_3d(extents[0].x, extents[0].z, -extents[0].y) + , math::vector_3d(extents[1].x, extents[1].z, -extents[1].y) + ); } } diff --git a/src/noggit/WMO.h b/src/noggit/WMO.h index 49c28d83..3f18dfbc 100644 --- a/src/noggit/WMO.h +++ b/src/noggit/WMO.h @@ -12,6 +12,7 @@ #include #include #include +#include #include diff --git a/src/noggit/WMOInstance.cpp b/src/noggit/WMOInstance.cpp index 14fde802..b0b4868b 100644 --- a/src/noggit/WMOInstance.cpp +++ b/src/noggit/WMOInstance.cpp @@ -97,7 +97,8 @@ void WMOInstance::draw ( opengl::scoped::use_program& wmo_shader gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); math::vector_4d color = force_box ? math::vector_4d(0.0f, 0.0f, 1.0f, 1.0f) : math::vector_4d(0.0f, 1.0f, 0.0f, 1.0f); - opengl::primitives::wire_box (extents[0], extents[1]).draw (model_view, projection, math::matrix_4x4(math::matrix_4x4::unit), color); + opengl::primitives::wire_box::getInstance().draw(model_view, projection, math::matrix_4x4(math::matrix_4x4::unit), + color, extents[0], extents[1]); } } diff --git a/src/opengl/primitives.cpp b/src/opengl/primitives.cpp index a0ed5c24..94edb318 100644 --- a/src/opengl/primitives.cpp +++ b/src/opengl/primitives.cpp @@ -15,92 +15,122 @@ namespace opengl { namespace primitives { - wire_box::wire_box ( math::vector_3d const& min_point - , math::vector_3d const& max_point - ) - : _program { { GL_VERTEX_SHADER - , R"code( -#version 330 core - -in vec4 position; - -uniform mat4 model_view; -uniform mat4 projection; -uniform mat4 transform; - -void main() -{ - gl_Position = projection * model_view * transform * position; -} -)code" - } - , { GL_FRAGMENT_SHADER - , R"code( -#version 330 core - -uniform vec4 color; - -out vec4 out_color; - -void main() -{ - out_color = color; -} -)code" - } - } - { - std::vector positions (math::box_points (min_point, max_point)); - - static std::array const indices - {{5, 7, 3, 2, 0, 1, 3, 1, 5, 4, 0, 4, 6, 2, 6, 7}}; - - _vao.upload(); - - { - scoped::buffer_binder const buffer (_positions); - gl.bufferData ( GL_ARRAY_BUFFER - , positions.size() * sizeof (*positions.data()) - , positions.data() - , GL_STATIC_DRAW - ); - } - - { - scoped::buffer_binder const buffer (_indices); - gl.bufferData ( GL_ELEMENT_ARRAY_BUFFER - , indices.size() * sizeof (*indices.data()) - , indices.data() - , GL_STATIC_DRAW - ); - } - } - void wire_box::draw ( math::matrix_4x4 const& model_view , math::matrix_4x4 const& projection , math::matrix_4x4 const& transform , math::vector_4d const& color - ) const + , math::vector_3d const& min_point + , math::vector_3d const& max_point + ) { - opengl::scoped::use_program wire_box_shader {_program}; + + if (!_buffers_are_setup) + { + setup_buffers(); + } + + opengl::scoped::use_program wire_box_shader {*_program.get()}; wire_box_shader.uniform("model_view", model_view); wire_box_shader.uniform("projection", projection); wire_box_shader.uniform("transform", transform); wire_box_shader.uniform("color", color); + wire_box_shader.uniform("pointPositions", math::box_points (min_point, max_point)); opengl::scoped::bool_setter const line_smooth; gl.hint(GL_LINE_SMOOTH_HINT, GL_NICEST); opengl::scoped::vao_binder const _(_vao[0]); - scoped::buffer_binder const vertices (_positions); - wire_box_shader.attrib("position", 3, GL_FLOAT, GL_FALSE, 0, 0); - - scoped::buffer_binder const indices (_indices); gl.drawElements (GL_LINE_STRIP, _indices, 16, GL_UNSIGNED_BYTE, nullptr); } - + + void wire_box::setup_buffers() + { + _program.reset(new opengl::program( {{ GL_VERTEX_SHADER + , R"code( + #version 330 core + + in vec4 position; + + uniform vec3 pointPositions[8]; + uniform mat4 model_view; + uniform mat4 projection; + uniform mat4 transform; + + void main() + { + vec4 pos = position; // hack to get rid of compiler optimizations, else Noggit crashes + gl_Position = projection * model_view * transform * vec4(pointPositions[gl_VertexID], 1.0); + } + )code"} + , { GL_FRAGMENT_SHADER + , R"code( + #version 330 core + + uniform vec4 color; + + out vec4 out_color; + + void main() + { + out_color = color; + } + )code" + } + })); + + _vao.upload(); + _buffers.upload(); + + //std::vector positions (math::box_points (min_point, max_point)); + + std::vector positions = { + {-0.5f, -0.5f, -0.5f}, + {0.5f, -0.5f, -0.5f}, + {0.5f, 0.5f, -0.5f}, + {-0.5f, 0.5f, -0.5f}, + {-0.5f, -0.5f, 0.5f}, + {0.5f, -0.5f, 0.5f}, + {0.5f, 0.5f, 0.5f}, + {-0.5f, 0.5f, 0.5f}, + }; + + static std::array const indices + {{5, 7, 3, 2, 0, 1, 3, 1, 5, 4, 0, 4, 6, 2, 6, 7}}; + + scoped::buffer_binder const pos_buffer (_positions); + gl.bufferData ( GL_ARRAY_BUFFER + , positions.size() * sizeof (*positions.data()) + , positions.data() + , GL_STATIC_DRAW + ); + + scoped::buffer_binder const index_buffer (_indices); + gl.bufferData ( GL_ELEMENT_ARRAY_BUFFER + , indices.size() * sizeof (*indices.data()) + , indices.data() + , GL_STATIC_DRAW + ); + + auto test = glGetError(); + + opengl::scoped::use_program shader (*_program.get()); + + test = glGetError(); + + opengl::scoped::vao_binder const _ (_vao[0]); + + test = glGetError(); + + shader.attrib("position", 3, GL_FLOAT, GL_FALSE, 0, 0); + + test = glGetError(); + + _buffers_are_setup = true; + + } + void sphere::draw( math::matrix_4x4 const& mvp , math::vector_3d const& pos diff --git a/src/opengl/primitives.hpp b/src/opengl/primitives.hpp index 19d274dd..203a7e39 100644 --- a/src/opengl/primitives.hpp +++ b/src/opengl/primitives.hpp @@ -19,23 +19,34 @@ namespace opengl { class wire_box { + private: + wire_box() {} + wire_box( const wire_box&); + wire_box& operator=( wire_box& ); public: - wire_box ( math::vector_3d const& min_point - , math::vector_3d const& max_point - ); + static wire_box& getInstance() { + static wire_box instance; + return instance; + } void draw ( math::matrix_4x4 const& model_view , math::matrix_4x4 const& projection , math::matrix_4x4 const& transform , math::vector_4d const& color - ) const; + , math::vector_3d const& min_point + , math::vector_3d const& max_point + ); private: + bool _buffers_are_setup = false; + + void setup_buffers(); + scoped::deferred_upload_vertex_arrays<1> _vao; - scoped::buffers<2> _buffers; + scoped::deferred_upload_buffers<2> _buffers; GLuint const& _positions = _buffers[0]; GLuint const& _indices = _buffers[1]; - opengl::program _program; + std::unique_ptr _program; }; class sphere diff --git a/src/opengl/shader.cpp b/src/opengl/shader.cpp index ccb45196..35c5299d 100644 --- a/src/opengl/shader.cpp +++ b/src/opengl/shader.cpp @@ -172,6 +172,10 @@ namespace opengl { gl.uniform1iv (uniform_location(name), value.size(), value.data()); } + void use_program::uniform (std::string const& name, std::vector const& value) + { + gl.uniform3fv (uniform_location(name), value.size(), reinterpret_cast(value.data())); + } void use_program::uniform (std::string const& name, math::vector_2d const& value) { gl.uniform2fv (uniform_location (name), 1, value); diff --git a/src/opengl/shader.hpp b/src/opengl/shader.hpp index 72dfcdcb..e12af290 100644 --- a/src/opengl/shader.hpp +++ b/src/opengl/shader.hpp @@ -77,6 +77,7 @@ namespace opengl void uniform (std::string const& name, std::vector const&); void uniform (std::string const& name, GLint); void uniform (std::string const& name, GLfloat); + void uniform (std::string const& name, std::vector const& value); void uniform (std::string const& name, math::vector_2d const&); void uniform (std::string const& name, math::vector_3d const&); void uniform (std::string const& name, math::vector_4d const&);