diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bfd01559..998c9fda9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,6 +329,7 @@ set(MAIN_SOURCES src/components/radar.h src/components/hull.h src/components/rendering.h + src/components/rendering.cpp src/components/docking.h src/components/coolant.h src/components/shipsystem.h diff --git a/src/components/rendering.cpp b/src/components/rendering.cpp new file mode 100644 index 000000000..9d78151aa --- /dev/null +++ b/src/components/rendering.cpp @@ -0,0 +1,32 @@ +#include "mesh.h" +#include "textureManager.h" +#include "rendering.h" + +Mesh* MeshRenderComponent::getMesh() +{ + if (!mesh.ptr && !mesh.name.empty()) + mesh.ptr = Mesh::getMesh(mesh.name); + return mesh.ptr; +} + +sp::Texture* MeshRenderComponent::getTexture() +{ + if (!texture.ptr && !texture.name.empty()) + texture.ptr = textureManager.getTexture(texture.name); + return texture.ptr; +} + +sp::Texture* MeshRenderComponent::getSpecularTexture() +{ + if (!specular_texture.ptr && !specular_texture.name.empty()) + specular_texture.ptr = textureManager.getTexture(specular_texture.name); + return specular_texture.ptr; +} + +sp::Texture* MeshRenderComponent::getIlluminationTexture() +{ + if (!illumination_texture.ptr && !illumination_texture.name.empty()) + illumination_texture.ptr = textureManager.getTexture(illumination_texture.name); + return illumination_texture.ptr; +} + diff --git a/src/components/rendering.h b/src/components/rendering.h index 9b5f91fb0..3582fdf23 100644 --- a/src/components/rendering.h +++ b/src/components/rendering.h @@ -1,7 +1,7 @@ #pragma once +#include #include "io/dataBuffer.h" - #include "graphics/texture.h" #include "mesh.h" #include "shaderRegistry.h" @@ -26,6 +26,11 @@ class MeshRenderComponent TextureRef illumination_texture; glm::vec3 mesh_offset{}; float scale = 1.0; + + Mesh* getMesh(); + sp::Texture* getTexture(); + sp::Texture* getSpecularTexture(); + sp::Texture* getIlluminationTexture(); }; class EngineEmitter diff --git a/src/mesh.cpp b/src/mesh.cpp index ced90b2a8..e8d95c15d 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -56,13 +56,15 @@ Mesh::Mesh(std::vector&& unindexed_vertices) glBindBuffer(GL_ARRAY_BUFFER, vbo_ibo[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(MeshVertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); - + if (!indices.empty()) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_ibo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_NONE); } + + greatest_distance_from_center = greatestDistanceFromCenter(vertices); } } @@ -75,10 +77,10 @@ void Mesh::render(int32_t position_attrib, int32_t texcoords_attrib, int32_t nor if (position_attrib != -1) glVertexAttribPointer(position_attrib, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, position)); - + if (normal_attrib != -1) glVertexAttribPointer(normal_attrib, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, normal)); - + if (texcoords_attrib != -1) glVertexAttribPointer(texcoords_attrib, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, uv)); @@ -89,12 +91,12 @@ void Mesh::render(int32_t position_attrib, int32_t texcoords_attrib, int32_t nor glDrawElements(GL_TRIANGLES, face_count * 3, GL_UNSIGNED_SHORT, nullptr); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_NONE); } - + else { glDrawArrays(GL_TRIANGLES, 0, static_cast(vertices.size())); } - + glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); } @@ -114,7 +116,7 @@ glm::vec3 Mesh::randomPoint() } else { - + v0_index = static_cast(irandom(0, static_cast(vertices.size()) / 3 - 1)) * 3; v1_index = v0_index + 1; v2_index = v0_index + 2; @@ -136,6 +138,27 @@ glm::vec3 Mesh::randomPoint() return ret; } +uint32_t Mesh::greatestDistanceFromCenter(std::vector& vertices) +{ + if (vertices.empty()) { + return 0; + } + + glm::vec3 sum{}; + for(auto vertex : vertices) sum += glm::vec3{vertex.position[0], vertex.position[1], vertex.position[2]}; + auto average = sum / float(vertices.size()); + + auto greatest_distance = 0.f; + for(auto vertex : vertices) + { + float distance = glm::distance(average, glm::vec3{vertex.position[0], vertex.position[1], vertex.position[2]}); + if(distance > greatest_distance) { + greatest_distance = distance; + } + } + return greatest_distance; +} + struct IndexInfo { int v; @@ -193,7 +216,7 @@ Mesh* Mesh::getMesh(const string& filename) LOG(ERROR, "Bad normal line: ", line); parsing_ok = false; } - + }else if (parts[0] == "vt") { if (parts.size() >= 3) @@ -205,7 +228,7 @@ Mesh* Mesh::getMesh(const string& filename) LOG(ERROR, "Bad vertex texcoord line: ", line); parsing_ok = false; } - + }else if (parts[0] == "f") { if (parts.size() >= 4) @@ -269,8 +292,8 @@ Mesh* Mesh::getMesh(const string& filename) { LOG(ERROR, "Failed to parse ", filename); } - - + + }else if (filename.endswith(".model")) { mesh_vertices.resize(readInt(stream)); @@ -285,6 +308,6 @@ Mesh* Mesh::getMesh(const string& filename) meshMap[filename] = ret; } - + return ret; } diff --git a/src/mesh.h b/src/mesh.h index fad612d6f..96688d2dc 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -21,11 +21,16 @@ class Mesh : sp::NonCopyable gl::Buffers<2> vbo_ibo{ gl::Unitialized{} }; uint32_t face_count{}; public: + float greatest_distance_from_center{}; explicit Mesh(std::vector&& vertices); void render(int32_t position_attrib, int32_t texcoords_attrib, int32_t normal_attrib); glm::vec3 randomPoint(); + // Calculate the center all vertices in this mesh, and return the distance + // of the point farthest from that center. + uint32_t greatestDistanceFromCenter(std::vector& vertices); + static Mesh* getMesh(const string& filename); }; diff --git a/src/screenComponents/databaseView.cpp b/src/screenComponents/databaseView.cpp index 7738411f1..be52dee40 100644 --- a/src/screenComponents/databaseView.cpp +++ b/src/screenComponents/databaseView.cpp @@ -126,7 +126,8 @@ void DatabaseViewComponent::display() if (mrc) { - //TODO: (new GuiRotatingModelView(visual, "DATABASE_MODEL_VIEW", selected_entry))->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); + (new GuiRotatingModelView(visual, "DATABASE_MODEL_VIEW", selected_entry)) + ->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax); if(database->image != "") { (new GuiImage(visual, "DATABASE_IMAGE", database->image))->setMargins(0)->setSize(32, 32); diff --git a/src/screenComponents/rotatingModelView.cpp b/src/screenComponents/rotatingModelView.cpp index 4a876eae9..b0f9d44cb 100644 --- a/src/screenComponents/rotatingModelView.cpp +++ b/src/screenComponents/rotatingModelView.cpp @@ -4,8 +4,11 @@ #include "featureDefs.h" #include "rotatingModelView.h" +#include "textureManager.h" + #include "glObjects.h" #include "shaderRegistry.h" +#include "systems/rendering.h" #include @@ -14,17 +17,21 @@ #include #include -GuiRotatingModelView::GuiRotatingModelView(GuiContainer* owner, string id/*TODO, P model*/) -: GuiElement(owner, id)//, model(model) +GuiRotatingModelView::GuiRotatingModelView(GuiContainer* owner, string id, sp::ecs::Entity& entity) + +: GuiElement(owner, id), entity(entity) { } void GuiRotatingModelView::onDraw(sp::RenderTarget& renderer) { - /*TODO + if (rect.size.x <= 0) return; if (rect.size.y <= 0) return; - if (!model) return; + + auto mrc = entity.getComponent(); + if (!mrc) return; + renderer.finish(); float camera_fov = 60.0f; @@ -38,97 +45,122 @@ void GuiRotatingModelView::onDraw(sp::RenderTarget& renderer) glClearDepth(1.f); glClear(GL_DEPTH_BUFFER_BIT); - glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); - auto projection = glm::perspective(glm::radians(camera_fov), rect.size.x / rect.size.y, 1.f, 25000.f); - auto view_matrix = glm::rotate(glm::identity(), glm::radians(90.f), glm::vec3(1.f, 0.f, 0.f)); - view_matrix = glm::scale(view_matrix, glm::vec3(1.f, 1.f, -1.f)); - view_matrix = glm::translate(view_matrix, glm::vec3(0.f, -200.f, 0.f)); + + auto mesh_radius = mrc->getMesh()->greatest_distance_from_center; + float mesh_diameter = mesh_radius * 2.f; + float near_clip_boundary = 1.f; + + auto projection_matrix = glm::perspective(glm::radians(camera_fov), rect.size.x / rect.size.y, near_clip_boundary, 25000.f); + float max_size = mesh_diameter * glm::tan(glm::radians(camera_fov / 2.f)); + float scale = max_size / mesh_diameter; + + // OpenGL standard: X across (left-to-right), Y up, Z "towards". + auto view_matrix = glm::rotate(glm::identity(), glm::radians(90.f), glm::vec3(1.f, 0.f, 0.f)); // -> X across (l-t-r), Y "towards", Z down + view_matrix = glm::scale(view_matrix, glm::vec3(1.f, 1.f, -1.f)); // -> X across (l-t-r), Y "towards", Z up + view_matrix = glm::translate(view_matrix, glm::vec3(0.f, -1.f * max_size - near_clip_boundary, 0.f)); view_matrix = glm::rotate(view_matrix, glm::radians(-30.f), glm::vec3(1.f, 0.f, 0.f)); view_matrix = glm::rotate(view_matrix, glm::radians(engine->getElapsedTime() * 360.0f / 10.0f), glm::vec3(0.f, 0.f, 1.f)); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, 0); - glDepthMask(true); glEnable(GL_DEPTH_TEST); + ShaderRegistry::updateProjectionView(projection_matrix, view_matrix); + + auto model_matrix = calculateModelMatrix(glm::vec2{}, 0.f, mrc->mesh_offset, scale); + + auto shader = lookUpShader(*mrc); + glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Model), 1, GL_FALSE, glm::value_ptr(model_matrix)); + + auto modeldata_matrix = glm::rotate(model_matrix, glm::radians(180.f), {0.f, 0.f, 1.f}); + modeldata_matrix = glm::scale(modeldata_matrix, glm::vec3{scale}); + + // Lights setup. + ShaderRegistry::setupLights(shader.get(), modeldata_matrix); + + // Textures + activateAndBindMeshTextures(*mrc); + + // Draw + +// { +// #ifdef DEBUG +// ShaderRegistry::ScopedShader shader(ShaderRegistry::Shaders::BasicColor); +// { +// // Common state - matrices. +// glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Projection), 1, GL_FALSE, glm::value_ptr(projection_matrix)); +// glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::View), 1, GL_FALSE, glm::value_ptr(view_matrix)); +// glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Model), 1, GL_FALSE, glm::value_ptr(model_matrix)); +// +// // Vertex attrib +// gl::ScopedVertexAttribArray positions(shader.get().attribute(ShaderRegistry::Attributes::Position)); +// +// // for (const EngineEmitterData& ee : model->engine_emitters) +// // { +// // glm::vec3 offset = ee.position * model->scale; +// // float r = model->scale * ee.scale * 0.5f; +// // +// // glUniform4f(shader.get().uniform(ShaderRegistry::Uniforms::Color), ee.color.x, ee.color.y, ee.color.z, 1.f); +// // auto vertices = { +// // glm::vec3{offset.x + r, offset.y, offset.z}, +// // glm::vec3{offset.x - r, offset.y, offset.z}, +// // glm::vec3{offset.x, offset.y + r, offset.z}, +// // glm::vec3{offset.x, offset.y - r, offset.z}, +// // glm::vec3{offset.x, offset.y, offset.z + r}, +// // glm::vec3{offset.x, offset.y, offset.z - r} +// // }; +// // glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); +// // glDrawArrays(GL_LINES, 0, vertices.size()); +// // } +// auto r = mesh_radius * 0.1f; +// // float r = model->getRadius() * 0.1f; +// +// glUniform4f(shader.get().uniform(ShaderRegistry::Uniforms::Color), 1.f, 1.f, 1.f, 1.f); +// +// // for (const glm::vec3& position : model->beam_position) +// // { +// // glm::vec3 offset = position * model->scale; +// // +// // auto vertices = { +// // glm::vec3{offset.x + r, offset.y, offset.z}, +// // glm::vec3{offset.x - r, offset.y, offset.z}, +// // glm::vec3{offset.x, offset.y + r, offset.z}, +// // glm::vec3{offset.x, offset.y - r, offset.z}, +// // glm::vec3{offset.x, offset.y, offset.z + r}, +// // glm::vec3{offset.x, offset.y, offset.z - r} +// // }; +// // glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); +// // glDrawArrays(GL_LINES, 0, vertices.size()); +// // } +// +// // for (const glm::vec3& position : model->tube_position) +// // { +// // glm::vec3 offset = position * model->scale; +// // +// // auto vertices = { +// // glm::vec3{offset.x + r * 3, offset.y, offset.z}, +// // glm::vec3{offset.x - r, offset.y, offset.z}, +// // glm::vec3{offset.x, offset.y + r, offset.z}, +// // glm::vec3{offset.x, offset.y - r, offset.z}, +// // glm::vec3{offset.x, offset.y, offset.z + r}, +// // glm::vec3{offset.x, offset.y, offset.z - r} +// // }; +// // glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); +// // glDrawArrays(GL_LINES, 0, vertices.size()); +// // } +// } +// #endif +// } + drawMesh(*mrc, shader); - ShaderRegistry::updateProjectionView(projection, view_matrix); - - { - float scale = 100.0f / model->getRadius(); - auto model_matrix = glm::scale(glm::identity(), glm::vec3(scale)); - model->render(model_matrix); -#ifdef DEBUG - ShaderRegistry::ScopedShader shader(ShaderRegistry::Shaders::BasicColor); - { - // Common state - matrices. - glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Projection), 1, GL_FALSE, glm::value_ptr(projection)); - glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::View), 1, GL_FALSE, glm::value_ptr(view_matrix)); - glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Model), 1, GL_FALSE, glm::value_ptr(model_matrix)); - - // Vertex attrib - gl::ScopedVertexAttribArray positions(shader.get().attribute(ShaderRegistry::Attributes::Position)); - - for (const EngineEmitterData& ee : model->engine_emitters) - { - glm::vec3 offset = ee.position * model->scale; - float r = model->scale * ee.scale * 0.5f; - - glUniform4f(shader.get().uniform(ShaderRegistry::Uniforms::Color), ee.color.x, ee.color.y, ee.color.z, 1.f); - auto vertices = { - glm::vec3{offset.x + r, offset.y, offset.z}, - glm::vec3{offset.x - r, offset.y, offset.z}, - glm::vec3{offset.x, offset.y + r, offset.z}, - glm::vec3{offset.x, offset.y - r, offset.z}, - glm::vec3{offset.x, offset.y, offset.z + r}, - glm::vec3{offset.x, offset.y, offset.z - r} - }; - glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); - glDrawArrays(GL_LINES, 0, vertices.size()); - } - float r = model->getRadius() * 0.1f; - - glUniform4f(shader.get().uniform(ShaderRegistry::Uniforms::Color), 1.f, 1.f, 1.f, 1.f); - - for (const glm::vec3& position : model->beam_position) - { - glm::vec3 offset = position * model->scale; - - auto vertices = { - glm::vec3{offset.x + r, offset.y, offset.z}, - glm::vec3{offset.x - r, offset.y, offset.z}, - glm::vec3{offset.x, offset.y + r, offset.z}, - glm::vec3{offset.x, offset.y - r, offset.z}, - glm::vec3{offset.x, offset.y, offset.z + r}, - glm::vec3{offset.x, offset.y, offset.z - r} - }; - glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); - glDrawArrays(GL_LINES, 0, vertices.size()); - } - - for (const glm::vec3& position : model->tube_position) - { - glm::vec3 offset = position * model->scale; - - auto vertices = { - glm::vec3{offset.x + r * 3, offset.y, offset.z}, - glm::vec3{offset.x - r, offset.y, offset.z}, - glm::vec3{offset.x, offset.y + r, offset.z}, - glm::vec3{offset.x, offset.y - r, offset.z}, - glm::vec3{offset.x, offset.y, offset.z + r}, - glm::vec3{offset.x, offset.y, offset.z - r} - }; - glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), std::begin(vertices)); - glDrawArrays(GL_LINES, 0, vertices.size()); - } - } -#endif - } glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glViewport(0, 0, renderer.getPhysicalSize().x, renderer.getPhysicalSize().y); - */ } diff --git a/src/screenComponents/rotatingModelView.h b/src/screenComponents/rotatingModelView.h index 297330e01..456a9c45c 100644 --- a/src/screenComponents/rotatingModelView.h +++ b/src/screenComponents/rotatingModelView.h @@ -2,13 +2,14 @@ #define ROTATING_MODEL_VIEW_H #include "gui/gui2_element.h" +#include "components/rendering.h" class GuiRotatingModelView : public GuiElement { private: - //TODO: P model; + sp::ecs::Entity &entity; public: - GuiRotatingModelView(GuiContainer* owner, string id /*TODO, P model*/); + GuiRotatingModelView(GuiContainer* owner, string id, sp::ecs::Entity& entity); virtual void onDraw(sp::RenderTarget& target) override; }; diff --git a/src/systems/rendering.cpp b/src/systems/rendering.cpp index 2ab03f88b..c071a56b3 100644 --- a/src/systems/rendering.cpp +++ b/src/systems/rendering.cpp @@ -22,7 +22,7 @@ void RenderSystem::render3D(float aspect, float camera_fov) depth_cutoff_back = -std::numeric_limits::infinity(); for(auto& handler : render_handlers) (this->*(handler.func))(handler.rif); - + for(int n=render_lists.size() - 1; n >= 0; n--) { auto& render_list = render_lists[n]; @@ -33,7 +33,6 @@ void RenderSystem::render3D(float aspect, float camera_fov) ShaderRegistry::updateProjectionView(projection, {}); glDepthMask(true); - glDisable(GL_BLEND); for(auto info : render_list) if (!info.transparent) @@ -47,76 +46,88 @@ void RenderSystem::render3D(float aspect, float camera_fov) } } -void MeshRenderSystem::update(float delta) -{ -} - -void MeshRenderSystem::render3D(sp::ecs::Entity e, sp::Transform& transform, MeshRenderComponent& mrc) -{ - if (!mrc.mesh.ptr && !mrc.mesh.name.empty()) - mrc.mesh.ptr = Mesh::getMesh(mrc.mesh.name); - if (!mrc.mesh.ptr) - return; - if (!mrc.texture.ptr && !mrc.texture.name.empty()) - mrc.texture.ptr = textureManager.getTexture(mrc.texture.name); - if (!mrc.specular_texture.ptr && !mrc.specular_texture.name.empty()) - mrc.specular_texture.ptr = textureManager.getTexture(mrc.specular_texture.name); - if (!mrc.illumination_texture.ptr && !mrc.illumination_texture.name.empty()) - mrc.illumination_texture.ptr = textureManager.getTexture(mrc.illumination_texture.name); - - auto position = transform.getPosition(); - auto rotation = transform.getRotation(); +glm::mat4 calculateModelMatrix(glm::vec2 position, float rotation, glm::vec3 mesh_offset, float scale) { auto model_matrix = glm::translate(glm::identity(), glm::vec3{ position.x, position.y, 0.f }); model_matrix = glm::rotate(model_matrix, glm::radians(rotation), glm::vec3{ 0.f, 0.f, 1.f }); - model_matrix = glm::translate(model_matrix, mrc.mesh_offset); + model_matrix = glm::translate(model_matrix, mesh_offset); + model_matrix = glm::scale(model_matrix, glm::vec3{scale}); - // EE's coordinate flips to a Z-up left hand. - // To account for that, flip the model around 180deg. - auto modeldata_matrix = glm::rotate(model_matrix, glm::radians(180.f), {0.f, 0.f, 1.f}); - modeldata_matrix = glm::scale(modeldata_matrix, glm::vec3{mrc.scale}); - //modeldata_matrix = glm::translate(modeldata_matrix, mrc.mesh_offset); // Old mesh offset + return model_matrix; +} +ShaderRegistry::ScopedShader lookUpShader(MeshRenderComponent& mrc) +{ auto shader_id = ShaderRegistry::Shaders::Object; - if (mrc.texture.ptr && mrc.specular_texture.ptr && mrc.illumination_texture.ptr) + if (mrc.getTexture() && mrc.getSpecularTexture() && mrc.getIlluminationTexture()) shader_id = ShaderRegistry::Shaders::ObjectSpecularIllumination; - else if (mrc.texture.ptr && mrc.specular_texture.ptr) + else if (mrc.getTexture() && mrc.getSpecularTexture()) shader_id = ShaderRegistry::Shaders::ObjectSpecular; - else if (mrc.texture.ptr && mrc.illumination_texture.ptr) + else if (mrc.getTexture() && mrc.getIlluminationTexture()) shader_id = ShaderRegistry::Shaders::ObjectIllumination; - ShaderRegistry::ScopedShader shader(shader_id); - glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Model), 1, GL_FALSE, glm::value_ptr(modeldata_matrix)); - - // Lights setup. - ShaderRegistry::setupLights(shader.get(), model_matrix); + return ShaderRegistry::ScopedShader(shader_id); +} - // Textures - if (mrc.texture.ptr) - mrc.texture.ptr->bind(); +void activateAndBindMeshTextures(MeshRenderComponent& mrc) +{ + if (mrc.getTexture()) + mrc.getTexture()->bind(); - if (mrc.specular_texture.ptr) + if (mrc.getSpecularTexture()) { glActiveTexture(GL_TEXTURE0 + ShaderRegistry::textureIndex(ShaderRegistry::Textures::SpecularMap)); - mrc.specular_texture.ptr->bind(); + mrc.getSpecularTexture()->bind(); } - if (mrc.illumination_texture.ptr) + if (mrc.getIlluminationTexture()) { glActiveTexture(GL_TEXTURE0 + ShaderRegistry::textureIndex(ShaderRegistry::Textures::IlluminationMap)); - mrc.illumination_texture.ptr->bind(); + mrc.getIlluminationTexture()->bind(); } +} - // Draw +void drawMesh(MeshRenderComponent& mrc, ShaderRegistry::ScopedShader& shader) +{ gl::ScopedVertexAttribArray positions(shader.get().attribute(ShaderRegistry::Attributes::Position)); gl::ScopedVertexAttribArray texcoords(shader.get().attribute(ShaderRegistry::Attributes::Texcoords)); gl::ScopedVertexAttribArray normals(shader.get().attribute(ShaderRegistry::Attributes::Normal)); - mrc.mesh.ptr->render(positions.get(), texcoords.get(), normals.get()); + mrc.getMesh()->render(positions.get(), texcoords.get(), normals.get()); - if (mrc.specular_texture.ptr || mrc.illumination_texture.ptr) + // wut iz? + if (mrc.getSpecularTexture() || mrc.getIlluminationTexture()) glActiveTexture(GL_TEXTURE0); } +void MeshRenderSystem::update(float delta) +{ +} + +void MeshRenderSystem::render3D(sp::ecs::Entity e, sp::Transform& transform, MeshRenderComponent& mrc) +{ + auto model_matrix = calculateModelMatrix( + transform.getPosition(), + transform.getRotation(), + mrc.mesh_offset, + mrc.scale); + + auto shader = lookUpShader(mrc); + glUniformMatrix4fv(shader.get().uniform(ShaderRegistry::Uniforms::Model), 1, GL_FALSE, glm::value_ptr(model_matrix)); + + auto modeldata_matrix = glm::rotate(model_matrix, glm::radians(180.f), {0.f, 0.f, 1.f}); + modeldata_matrix = glm::scale(modeldata_matrix, glm::vec3{mrc.scale}); + + // Lights setup. + ShaderRegistry::setupLights(shader.get(), modeldata_matrix); + + // Textures + activateAndBindMeshTextures(mrc); + + // Draw + drawMesh(mrc, shader); + +} + void NebulaRenderSystem::update(float delta) { } @@ -333,7 +344,7 @@ void ExplosionRenderSystem::render3D(sp::ecs::Entity e, sp::Transform& transform } // upload glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(glm::vec3), vertices.data()); - + glDrawElements(GL_TRIANGLES, static_cast(6 * active_quads), GL_UNSIGNED_SHORT, nullptr); n += active_quads; } diff --git a/src/systems/rendering.h b/src/systems/rendering.h index 21b9fef8c..71d20df1a 100644 --- a/src/systems/rendering.h +++ b/src/systems/rendering.h @@ -67,8 +67,15 @@ class RenderSystem }; static std::vector render_handlers; }; + template Render3DInterface::Render3DInterface() { RenderSystem::add3DHandler(this); } +// FIX: This is obviously not the right place to define these utility functions +glm::mat4 calculateModelMatrix(glm::vec2 position, float rotation, glm::vec3 mesh_offset, float scale); +ShaderRegistry::ScopedShader lookUpShader(MeshRenderComponent& mrc); +void activateAndBindMeshTextures(MeshRenderComponent& mrc); +void drawMesh(MeshRenderComponent& mrc, ShaderRegistry::ScopedShader& shader); + class MeshRenderSystem : public sp::ecs::System, public Render3DInterface { public: