From daf1294e6fe46c6570662d2614dd5b244b0b9837 Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 26 Dec 2017 14:34:34 +0800 Subject: [PATCH] Add minimap and adjust unlit shader for it --- data/shaders/sp_unlit.frag | 16 +-- src/graphics/lighting_passes.cpp | 2 +- src/graphics/material_manager.cpp | 29 +---- src/graphics/material_manager.hpp | 3 +- src/graphics/sp/sp_mesh.hpp | 2 + src/graphics/sp/sp_mesh_buffer.hpp | 10 ++ src/tracks/graph.cpp | 182 +++++++++++++++++++++++++---- src/tracks/graph.hpp | 4 + src/tracks/quad.cpp | 29 +++++ src/tracks/quad.hpp | 5 +- 10 files changed, 213 insertions(+), 69 deletions(-) diff --git a/data/shaders/sp_unlit.frag b/data/shaders/sp_unlit.frag index 8b92d6bc3..386c48d18 100644 --- a/data/shaders/sp_unlit.frag +++ b/data/shaders/sp_unlit.frag @@ -1,11 +1,8 @@ #ifdef Use_Bindless_Texture flat in sampler2D tex_layer_0; -flat in sampler2D tex_layer_2; #else // spm layer 1 texture uniform sampler2D tex_layer_0; -// gloss map -uniform sampler2D tex_layer_2; #endif #ifdef Use_Array_Texture @@ -50,17 +47,8 @@ void main(void) o_diffuse_color = vec4(final_color, 1.0); #if defined(Advanced_Lighting_Enabled) - -#ifdef Use_Array_Texture - vec4 layer_2 = texture(tex_array, vec3(uv, array_2)); -#else - vec4 layer_2 = texture(tex_layer_2, uv); -#endif - o_normal_depth.xy = 0.5 * EncodeNormal(normalize(normal)) + 0.5; - o_normal_depth.z = layer_2.x; - o_gloss_map = vec2(0.0); - + o_normal_depth.z = 0.0; + o_gloss_map = vec2(0.0, 0.1); #endif } - diff --git a/src/graphics/lighting_passes.cpp b/src/graphics/lighting_passes.cpp index 74af42d59..8bb51a9f5 100644 --- a/src/graphics/lighting_passes.cpp +++ b/src/graphics/lighting_passes.cpp @@ -412,7 +412,7 @@ void LightingPasses::renderEnvMap(GLuint normal_depth_texture, glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); - if (UserConfigParams::m_degraded_IBL) + if (specular_probe == 0 || UserConfigParams::m_degraded_IBL) { DegradedIBLShader::getInstance()->use(); glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO()); diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index a3a12393b..70ac9f54e 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -144,8 +144,7 @@ Material* MaterialManager::getMaterialSPM(std::string lay_one_tex_lc, } //----------------------------------------------------------------------------- -Material* MaterialManager::getMaterialFor(video::ITexture* t, - const std::string& lay_two_tex_lc) +Material* MaterialManager::getMaterialFor(video::ITexture* t) { const io::path& img_path = t->getName().getInternalName(); @@ -156,18 +155,7 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, { if (m_materials[i]->getTexFullPath() == img_path.c_str()) { - const std::string& mat_lay_two = m_materials[i]->getUVTwoTexture(); - if (mat_lay_two.empty() && lay_two_tex_lc.empty()) - { - return m_materials[i]; - } - else if (!mat_lay_two.empty() && !lay_two_tex_lc.empty()) - { - if (mat_lay_two == lay_two_tex_lc) - { - return m_materials[i]; - } - } + return m_materials[i]; } } } @@ -180,18 +168,7 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, { if (m_materials[i]->getTexFname() == image.c_str()) { - const std::string& mat_lay_two = m_materials[i]->getUVTwoTexture(); - if (mat_lay_two.empty() && lay_two_tex_lc.empty()) - { - return m_materials[i]; - } - else if (!mat_lay_two.empty() && !lay_two_tex_lc.empty()) - { - if (mat_lay_two == lay_two_tex_lc) - { - return m_materials[i]; - } - } + return m_materials[i]; } } // for i } diff --git a/src/graphics/material_manager.hpp b/src/graphics/material_manager.hpp index e899acaa4..b3c91256f 100644 --- a/src/graphics/material_manager.hpp +++ b/src/graphics/material_manager.hpp @@ -62,8 +62,7 @@ public: scene::IMeshBuffer *mb); Material* getMaterialFor(video::ITexture* t, video::E_MATERIAL_TYPE material_type); - Material* getMaterialFor(video::ITexture* t, - const std::string& lay_two_tex_lc = ""); + Material* getMaterialFor(video::ITexture* t); Material* getMaterialSPM(std::string lay_one_tex_lc, std::string lay_two_tex_lc); void setAllMaterialFlags(video::ITexture* t, diff --git a/src/graphics/sp/sp_mesh.hpp b/src/graphics/sp/sp_mesh.hpp index faea06a83..ac7e7ebdd 100644 --- a/src/graphics/sp/sp_mesh.hpp +++ b/src/graphics/sp/sp_mesh.hpp @@ -157,6 +157,8 @@ public: // ------------------------------------------------------------------------ s32 getJointIDWithArm(const c8* name, unsigned* arm_id) const; // ------------------------------------------------------------------------ + void addSPMeshBuffer(SPMeshBuffer* spmb) { m_buffer.push_back(spmb); } + // ------------------------------------------------------------------------ SPMeshBuffer* getSPMeshBuffer(u32 nr) const; }; diff --git a/src/graphics/sp/sp_mesh_buffer.hpp b/src/graphics/sp/sp_mesh_buffer.hpp index dfd9e44c3..3e9323329 100644 --- a/src/graphics/sp/sp_mesh_buffer.hpp +++ b/src/graphics/sp/sp_mesh_buffer.hpp @@ -264,6 +264,16 @@ public: m_vertices.push_back(v); } // ------------------------------------------------------------------------ + void addIndex(uint16_t idx) + { + m_indices.push_back(idx); + } + // ------------------------------------------------------------------------ + void setSPMVertices(std::vector& vertices) + { + m_vertices = std::move(vertices); + } + // ------------------------------------------------------------------------ void setIndices(std::vector& indices) { m_indices = std::move(indices); diff --git a/src/tracks/graph.cpp b/src/tracks/graph.cpp index ab6bb6420..35e77a003 100644 --- a/src/tracks/graph.cpp +++ b/src/tracks/graph.cpp @@ -19,9 +19,12 @@ #include "tracks/graph.hpp" #include "config/user_config.hpp" +#include "graphics/central_settings.hpp" #include "graphics/irr_driver.hpp" #include "graphics/render_target.hpp" -#include "graphics/stk_tex_manager.hpp" +#include "graphics/material_manager.hpp" +#include "graphics/sp/sp_mesh.hpp" +#include "graphics/sp/sp_mesh_buffer.hpp" #include "modes/profile_world.hpp" #include "tracks/arena_node_3d.hpp" #include "tracks/drive_node_2d.hpp" @@ -66,15 +69,32 @@ void Graph::createDebugMesh() { if (getNumNodes() <= 0) return; // no debug output if not graph - createMesh(/*show_invisible*/true, - /*enable_transparency*/true); - - video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices(); - for (unsigned int i = 0; i < m_mesh_buffer->getVertexCount(); i++) +#ifndef SERVER_ONY + if (CVS->isGLSL()) { - // Swap the alpha and back - v[i].Color.setAlpha((i%2) ? 64 : 255); + createMeshSP(/*show_invisible*/true, + /*enable_transparency*/true); + video::S3DVertexSkinnedMesh *v = + (video::S3DVertexSkinnedMesh*)m_mesh_buffer->getVertices(); + for (unsigned int i = 0; i < m_mesh_buffer->getVertexCount(); i++) + { + // Swap the alpha and back + v[i].m_color.setAlpha((i%2) ? 64 : 255); + } } + else + { + createMesh(/*show_invisible*/true, + /*enable_transparency*/true); + video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices(); + for (unsigned int i = 0; i < m_mesh_buffer->getVertexCount(); i++) + { + // Swap the alpha and back + v[i].Color.setAlpha((i%2) ? 64 : 255); + } + } +#endif + m_node = irr_driver->addMesh(m_mesh, "track-debug-mesh"); #ifdef DEBUG m_node->setName("track-debug-mesh"); @@ -109,9 +129,6 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency, m.Lighting = false; if (enable_transparency) m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - m.setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 255, 255))); - m.setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0))); - m.setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0))); m_mesh = irr_driver->createQuadMesh(&m); m_mesh_buffer = m_mesh->getMeshBuffer(0); assert(m_mesh_buffer->getVertexType()==video::EVT_STANDARD); @@ -206,18 +223,7 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency, // i.e. part of the lap line might not be visible. for (unsigned int i = 0; i < 4; i++) lap_v[i].Pos.Y += 0.1f; -#ifndef USE_TEXTURED_LINE m_mesh_buffer->append(lap_v, 4, lap_ind, 6); -#else - lap_v[0].TCoords = core::vector2df(0,0); - lap_v[1].TCoords = core::vector2df(3,0); - lap_v[2].TCoords = core::vector2df(3,1); - lap_v[3].TCoords = core::vector2df(0,1); - m_mesh_buffer->append(lap_v, 4, lap_ind, 6); - video::SMaterial &m = m_mesh_buffer->getMaterial(); - video::ITexture *t = irr_driver->getTexture("chess.png"); - m.setTexture(0, t); -#endif } // Instead of setting the bounding boxes, we could just disable culling, @@ -234,6 +240,121 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency, #endif } // createMesh +// ----------------------------------------------------------------------------- +/** Creates the actual mesh that is used by createDebugMesh() or makeMiniMap() + */ +void Graph::createMeshSP(bool show_invisible, bool enable_transparency, + const video::SColor *track_color) +{ +#ifndef SERVER_ONLY + + SP::SPMesh* spm = new SP::SPMesh(); + SP::SPMeshBuffer* spmb = new SP::SPMeshBuffer(true/*vertex_color*/); + m_mesh = spm; + m_mesh_buffer = spmb; + + unsigned int n = 0; + const unsigned int total_nodes = getNumNodes(); + + // Count the number of quads to display (some quads might be invisible) + for (unsigned int i = 0; i < total_nodes; i++) + { + if (show_invisible || !m_all_nodes[i]->isInvisible()) + n++; + } + + // Four vertices for each of the n-1 remaining quads + std::vector vertices; + vertices.resize(4 * n); + // Each quad consists of 2 triangles with 3 elements, so + // we need 2*3 indices for each quad. + std::vector indices; + indices.resize(6 * n); + video::SColor c(255, 255, 0, 0); + + if (track_color) + c = *track_color; + + // Now add all quads + int i = 0; + for (unsigned int count = 0; count < total_nodes; count++) + { + // Ignore invisible quads + if (!show_invisible && m_all_nodes[count]->isInvisible()) + continue; + + // Swap the colours from red to blue and back + if (!track_color) + { + c.setRed ((i % 2) ? 255 : 0); + c.setBlue((i % 2) ? 0 : 255); + } + + video::SColor this_color = c; + differentNodeColor(count, &this_color); + // Transfer the 4 points of the current quad to the list of vertices + m_all_nodes[count]->getSPMVertices(vertices.data() + (4 * i), this_color); + + // Set up the indices for the triangles + indices[6 * i] = 4 * i + 2; // First triangle: vertex 0, 1, 2 + indices[6 * i + 1] = 4 * i + 1; + indices[6 * i + 2] = 4 * i; + indices[6 * i + 3] = 4 * i + 3; // second triangle: vertex 0, 1, 3 + indices[6 * i + 4] = 4 * i + 2; + indices[6 * i + 5] = 4 * i; + i++; + } + + if (hasLapLine()) + { + video::S3DVertexSkinnedMesh lap_v[4]; + uint16_t lap_ind[6]; + video::SColor lap_color(128, 255, 0, 0); + m_all_nodes[0]->getSPMVertices(lap_v, lap_color); + + // Now scale the length (distance between vertix 0 and 3 + // and between 1 and 2) to be 'length': + // Length of the lap line about 3% of the 'height' + // of the track. + const float length = (m_bb_max.getZ() - m_bb_min.getZ()) * 0.03f; + + core::vector3df dl = lap_v[3].m_position-lap_v[0].m_position; + float ll2 = dl.getLengthSQ(); + if (ll2 < 0.001) + lap_v[3].m_position = lap_v[0].m_position + core::vector3df(0, 0, 1); + else + lap_v[3].m_position = lap_v[0].m_position + dl * length / sqrt(ll2); + + core::vector3df dr = lap_v[2].m_position - lap_v[1].m_position; + float lr2 = dr.getLengthSQ(); + if (lr2 < 0.001) + lap_v[2].m_position = lap_v[1].m_position + core::vector3df(0, 0, 1); + else + lap_v[2].m_position = lap_v[1].m_position + dr * length / sqrt(lr2); + lap_ind[0] = 4 * n + 2; + lap_ind[1] = 4 * n + 1; + lap_ind[2] = 4 * n; + lap_ind[3] = 4 * n + 3; + lap_ind[4] = 4 * n + 2; + lap_ind[5] = 4 * n; + // Set it a bit higher to avoid issued with z fighting, + // i.e. part of the lap line might not be visible. + for (unsigned int i = 0; i < 4; i++) + lap_v[i].m_position.Y += 0.1f; + std::copy(lap_v, lap_v + 4, std::back_inserter(vertices)); + std::copy(lap_ind, lap_ind +6, std::back_inserter(indices)); + } + + spmb->setSPMVertices(vertices); + spmb->setIndices(indices); + spmb->recalculateBoundingBox(); + spmb->setSTKMaterial(material_manager->getSPMaterial( + enable_transparency ? "alphablend" : "unlit")); + spm->addSPMeshBuffer(spmb); + spm->setBoundingBox(spmb->getBoundingBox()); +#endif +} // createMeshSP + // ----------------------------------------------------------------------------- /** Takes a snapshot of the graph so they can be used as minimap. */ @@ -253,9 +374,20 @@ RenderTarget* Graph::makeMiniMap(const core::dimension2du &dimension, irr_driver->getSceneManager() ->setAmbientLight(video::SColor(255, 255, 255, 255)); - createMesh(/*show_invisible part of the track*/ false, - /*enable_transparency*/ false, - /*track_color*/ &fill_color); +#ifndef SERVER_ONY + if (CVS->isGLSL()) + { + createMeshSP(/*show_invisible part of the track*/ false, + /*enable_transparency*/ false, + /*track_color*/ &fill_color); + } + else + { + createMesh(/*show_invisible part of the track*/ false, + /*enable_transparency*/ false, + /*track_color*/ &fill_color); + } +#endif m_node = irr_driver->addMesh(m_mesh, "mini_map"); #ifdef DEBUG diff --git a/src/tracks/graph.hpp b/src/tracks/graph.hpp index 41a0bac7f..b1079354a 100644 --- a/src/tracks/graph.hpp +++ b/src/tracks/graph.hpp @@ -95,6 +95,10 @@ private: bool enable_transparency=false, const video::SColor *track_color=NULL); // ------------------------------------------------------------------------ + void createMeshSP(bool show_invisible=true, + bool enable_transparency=false, + const video::SColor *track_color=NULL); + // ------------------------------------------------------------------------ void cleanupDebugMesh(); // ------------------------------------------------------------------------ virtual bool hasLapLine() const = 0; diff --git a/src/tracks/quad.cpp b/src/tracks/quad.cpp index a8c4c9f30..e0dc115e4 100644 --- a/src/tracks/quad.cpp +++ b/src/tracks/quad.cpp @@ -18,6 +18,7 @@ #include "tracks/quad.hpp" #include "tracks/graph.hpp" +#include "utils/mini_glm.hpp" #include "utils/log.hpp" #include @@ -68,6 +69,34 @@ void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const v[3].Color = color; } // setVertices +// ---------------------------------------------------------------------------- +/** Sets the vertices in an spm vertex array to the 4 points of this quad. + * \param v The vertex array in which to set the vertices. + * \param color The color to use for this quad. + */ +void Quad::getSPMVertices(video::S3DVertexSkinnedMesh *v, + const video::SColor &color) const +{ + // Eps is used to raise the track debug quads a little bit higher than + // the ground, so that they are actually visible. + core::vector3df normal = getNormal().toIrrVector(); + core::vector3df eps = normal * 0.1f; + v[0].m_position = m_p[0].toIrrVector()+eps; + v[1].m_position = m_p[1].toIrrVector()+eps; + v[2].m_position = m_p[2].toIrrVector()+eps; + v[3].m_position = m_p[3].toIrrVector()+eps; + + v[0].m_normal = MiniGLM::compressVector3(normal); + v[1].m_normal = MiniGLM::compressVector3(normal); + v[2].m_normal = MiniGLM::compressVector3(normal); + v[3].m_normal = MiniGLM::compressVector3(normal); + + v[0].m_color = color; + v[1].m_color = color; + v[2].m_color = color; + v[3].m_color = color; +} // setVertices + // ---------------------------------------------------------------------------- bool Quad::pointInside(const Vec3& p, bool ignore_vertical) const { diff --git a/src/tracks/quad.hpp b/src/tracks/quad.hpp index 396f618cf..b33d637f9 100644 --- a/src/tracks/quad.hpp +++ b/src/tracks/quad.hpp @@ -27,7 +27,7 @@ namespace irr { - namespace video { struct S3DVertex; } + namespace video { struct S3DVertex; struct S3DVertexSkinnedMesh; } } using namespace irr; @@ -75,6 +75,9 @@ public: // ------------------------------------------------------------------------ void getVertices(video::S3DVertex *v, const video::SColor &color) const; // ------------------------------------------------------------------------ + void getSPMVertices(video::S3DVertexSkinnedMesh *v, + const video::SColor &color) const; + // ------------------------------------------------------------------------ /** Returns the i-th. point of a quad. */ const Vec3& operator[](int i) const { return m_p[i]; } // ------------------------------------------------------------------------