From 62131fe2954d5e79651f9e47611675ba43da4d31 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 28 Aug 2024 21:46:52 +0200 Subject: [PATCH] Put all pieces together and clean up leftover code --- irr/include/CIndexBuffer.h | 2 +- irr/include/CMeshBuffer.h | 26 +---------- irr/include/IIndexBuffer.h | 26 +++++++++++ irr/include/IMeshBuffer.h | 55 ++--------------------- irr/include/SSkinMeshBuffer.h | 82 +++++++++++++--------------------- irr/src/CMeshManipulator.cpp | 35 +++++++++------ irr/src/COBJMeshFileLoader.cpp | 7 +-- src/client/hud.cpp | 17 +++---- src/client/hud.h | 3 +- src/client/mapblock_mesh.cpp | 14 ++---- src/client/mapblock_mesh.h | 7 ++- 11 files changed, 105 insertions(+), 169 deletions(-) diff --git a/irr/include/CIndexBuffer.h b/irr/include/CIndexBuffer.h index 4701c2e34..676408e65 100644 --- a/irr/include/CIndexBuffer.h +++ b/irr/include/CIndexBuffer.h @@ -24,7 +24,7 @@ public: #endif } - video::E_INDEX_TYPE getType() const + video::E_INDEX_TYPE getType() const override { static_assert(sizeof(T) == 2 || sizeof(T) == 4, "invalid index type"); return sizeof(T) == 2 ? video::EIT_16BIT : video::EIT_32BIT; diff --git a/irr/include/CMeshBuffer.h b/irr/include/CMeshBuffer.h index 6b13a8982..6eb325889 100644 --- a/irr/include/CMeshBuffer.h +++ b/irr/include/CMeshBuffer.h @@ -20,7 +20,7 @@ class CMeshBuffer : public IMeshBuffer public: //! Default constructor for empty meshbuffer CMeshBuffer() : - HWBuffer(NULL), PrimitiveType(EPT_TRIANGLES) + PrimitiveType(EPT_TRIANGLES) { #ifdef _DEBUG setDebugName("CMeshBuffer"); @@ -69,18 +69,6 @@ public: return Indices; } - // TEMPORARY helper for direct buffer acess - inline auto &VertexBuffer() - { - return Vertices->Data; - } - - // TEMPORARY helper for direct buffer acess - inline auto &IndexBuffer() - { - return Indices->Data; - } - //! Get the axis aligned bounding box /** \return Axis aligned bounding box of this buffer. */ const core::aabbox3d &getBoundingBox() const override @@ -142,18 +130,6 @@ public: return PrimitiveType; } - void setHWBuffer(void *ptr) const override - { - HWBuffer = ptr; - } - - void *getHWBuffer() const override - { - return HWBuffer; - } - - mutable void *HWBuffer; - //! Material for this meshbuffer. video::SMaterial Material; //! Vertex buffer diff --git a/irr/include/IIndexBuffer.h b/irr/include/IIndexBuffer.h index bdbbb6dcc..01282f0c8 100644 --- a/irr/include/IIndexBuffer.h +++ b/irr/include/IIndexBuffer.h @@ -7,6 +7,7 @@ #include "IReferenceCounted.h" #include "irrArray.h" #include "EHardwareBufferFlags.h" +#include "EPrimitiveTypes.h" #include "SVertexIndex.h" namespace irr @@ -50,6 +51,31 @@ public: //! Used by the VideoDriver to remember the buffer link. virtual void setHWBuffer(void *ptr) const = 0; virtual void *getHWBuffer() const = 0; + + //! Calculate how many geometric primitives would be drawn + u32 getPrimitiveCount(E_PRIMITIVE_TYPE primitiveType) const + { + const u32 indexCount = getCount(); + switch (primitiveType) { + case scene::EPT_POINTS: + return indexCount; + case scene::EPT_LINE_STRIP: + return indexCount - 1; + case scene::EPT_LINE_LOOP: + return indexCount; + case scene::EPT_LINES: + return indexCount / 2; + case scene::EPT_TRIANGLE_STRIP: + return (indexCount - 2); + case scene::EPT_TRIANGLE_FAN: + return (indexCount - 2); + case scene::EPT_TRIANGLES: + return indexCount / 3; + case scene::EPT_POINT_SPRITES: + return indexCount; + } + return 0; + } }; } // end namespace scene diff --git a/irr/include/IMeshBuffer.h b/irr/include/IMeshBuffer.h index 8a43db87e..55c05211a 100644 --- a/irr/include/IMeshBuffer.h +++ b/irr/include/IMeshBuffer.h @@ -176,18 +176,6 @@ public: return getVertexBuffer()->getTCoords(i); } - //! get the current hardware mapping hint - inline E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const - { - return getVertexBuffer()->getHardwareMappingHint(); - } - - //! get the current hardware mapping hint - inline E_HARDWARE_MAPPING getHardwareMappingHint_Index() const - { - return getIndexBuffer()->getHardwareMappingHint(); - } - //! set the hardware mapping hint, for driver inline void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) { @@ -206,26 +194,8 @@ public: getIndexBuffer()->setDirty(); } - //! Get the currently used ID for identification of changes. - /** This shouldn't be used for anything outside the VideoDriver. */ - inline u32 getChangedID_Vertex() const - { - return getVertexBuffer()->getChangedID(); - } - - //! Get the currently used ID for identification of changes. - /** This shouldn't be used for anything outside the VideoDriver. */ - inline u32 getChangedID_Index() const - { - return getIndexBuffer()->getChangedID(); - } - /* End helpers */ - //! Used by the VideoDriver to remember the buffer link. - virtual void setHWBuffer(void *ptr) const = 0; - virtual void *getHWBuffer() const = 0; - //! Describe what kind of primitive geometry is used by the meshbuffer /** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering. But meshbuffer manipulation functions might expect type EPT_TRIANGLES @@ -237,32 +207,13 @@ public: virtual E_PRIMITIVE_TYPE getPrimitiveType() const = 0; //! Calculate how many geometric primitives are used by this meshbuffer - virtual u32 getPrimitiveCount() const + u32 getPrimitiveCount() const { - const u32 indexCount = getIndexCount(); - switch (getPrimitiveType()) { - case scene::EPT_POINTS: - return indexCount; - case scene::EPT_LINE_STRIP: - return indexCount - 1; - case scene::EPT_LINE_LOOP: - return indexCount; - case scene::EPT_LINES: - return indexCount / 2; - case scene::EPT_TRIANGLE_STRIP: - return (indexCount - 2); - case scene::EPT_TRIANGLE_FAN: - return (indexCount - 2); - case scene::EPT_TRIANGLES: - return indexCount / 3; - case scene::EPT_POINT_SPRITES: - return indexCount; - } - return 0; + return getIndexBuffer()->getPrimitiveCount(getPrimitiveType()); } //! Calculate size of vertices and indices in memory - virtual size_t getSize() const + size_t getSize() const { size_t ret = 0; switch (getVertexType()) { diff --git a/irr/include/SSkinMeshBuffer.h b/irr/include/SSkinMeshBuffer.h index 949551161..fa6eae63a 100644 --- a/irr/include/SSkinMeshBuffer.h +++ b/irr/include/SSkinMeshBuffer.h @@ -21,7 +21,7 @@ struct SSkinMeshBuffer : public IMeshBuffer //! Default constructor SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) : VertexType(vt), PrimitiveType(EPT_TRIANGLES), - HWBuffer(nullptr), BoundingBoxNeedsRecalculated(true) + BoundingBoxNeedsRecalculated(true) { #ifdef _DEBUG setDebugName("SSkinMeshBuffer"); @@ -72,7 +72,7 @@ struct SSkinMeshBuffer : public IMeshBuffer } } - scene::IVertexBuffer *getVertexBuffer() + scene::IVertexBuffer *getVertexBuffer() override { switch (VertexType) { case video::EVT_2TCOORDS: @@ -119,6 +119,28 @@ struct SSkinMeshBuffer : public IMeshBuffer BoundingBox = box; } +private: + template void recalculateBoundingBox(const CVertexBuffer *buf) + { + if (!buf->getCount()) { + BoundingBox.reset(0, 0, 0); + } else { + auto &vertices = buf->Data; + BoundingBox.reset(vertices[0].Pos); + for (size_t i = 1; i < vertices.size(); ++i) + BoundingBox.addInternalPoint(vertices[i].Pos); + } + } + + template static void copyVertex(const T1 &src, T2 &dst) + { + dst.Pos = src.Pos; + dst.Normal = src.Normal; + dst.Color = src.Color; + dst.TCoords = src.TCoords; + } +public: + //! Recalculate bounding box void recalculateBoundingBox() override { @@ -129,36 +151,15 @@ struct SSkinMeshBuffer : public IMeshBuffer switch (VertexType) { case video::EVT_STANDARD: { - if (!Vertices_Standard->getCount()) - BoundingBox.reset(0, 0, 0); - else { - auto &vertices = Vertices_Standard->Data; - BoundingBox.reset(vertices[0].Pos); - for (size_t i = 1; i < vertices.size(); ++i) - BoundingBox.addInternalPoint(vertices[i].Pos); - } + recalculateBoundingBox(Vertices_Standard); break; } case video::EVT_2TCOORDS: { - if (!Vertices_2TCoords->getCount()) - BoundingBox.reset(0, 0, 0); - else { - auto &vertices = Vertices_2TCoords->Data; - BoundingBox.reset(vertices[0].Pos); - for (size_t i = 1; i < vertices.size(); ++i) - BoundingBox.addInternalPoint(vertices[i].Pos); - } + recalculateBoundingBox(Vertices_2TCoords); break; } case video::EVT_TANGENTS: { - if (!Vertices_Tangents->getCount()) - BoundingBox.reset(0, 0, 0); - else { - auto &vertices = Vertices_Tangents->Data; - BoundingBox.reset(vertices[0].Pos); - for (size_t i = 1; i < vertices.size(); ++i) - BoundingBox.addInternalPoint(vertices[i].Pos); - } + recalculateBoundingBox(Vertices_Tangents); break; } } @@ -170,10 +171,7 @@ struct SSkinMeshBuffer : public IMeshBuffer if (VertexType == video::EVT_STANDARD) { video::S3DVertex2TCoords Vertex; for (const auto &Vertex_Standard : Vertices_Standard->Data) { - Vertex.Color = Vertex_Standard.Color; - Vertex.Pos = Vertex_Standard.Pos; - Vertex.Normal = Vertex_Standard.Normal; - Vertex.TCoords = Vertex_Standard.TCoords; + copyVertex(Vertex_Standard, Vertex); Vertices_2TCoords->Data.push_back(Vertex); } Vertices_Standard->Data.clear(); @@ -185,12 +183,9 @@ struct SSkinMeshBuffer : public IMeshBuffer void convertToTangents() { if (VertexType == video::EVT_STANDARD) { - video::S3DVertexTangents Vertex; + video::S3DVertexTangents Vertex; for (const auto &Vertex_Standard : Vertices_Standard->Data) { - Vertex.Color = Vertex_Standard.Color; - Vertex.Pos = Vertex_Standard.Pos; - Vertex.Normal = Vertex_Standard.Normal; - Vertex.TCoords = Vertex_Standard.TCoords; + copyVertex(Vertex_Standard, Vertex); Vertices_Tangents->Data.push_back(Vertex); } Vertices_Standard->Data.clear(); @@ -198,10 +193,7 @@ struct SSkinMeshBuffer : public IMeshBuffer } else if (VertexType == video::EVT_2TCOORDS) { video::S3DVertexTangents Vertex; for (const auto &Vertex_2TCoords : Vertices_2TCoords->Data) { - Vertex.Color = Vertex_2TCoords.Color; - Vertex.Pos = Vertex_2TCoords.Pos; - Vertex.Normal = Vertex_2TCoords.Normal; - Vertex.TCoords = Vertex_2TCoords.TCoords; + copyVertex(Vertex_2TCoords, Vertex); Vertices_Tangents->Data.push_back(Vertex); } Vertices_2TCoords->Data.clear(); @@ -227,16 +219,6 @@ struct SSkinMeshBuffer : public IMeshBuffer return PrimitiveType; } - void setHWBuffer(void *ptr) const override - { - HWBuffer = ptr; - } - - void *getHWBuffer() const override - { - return HWBuffer; - } - //! Call this after changing the positions of any vertex. void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; } @@ -255,8 +237,6 @@ struct SSkinMeshBuffer : public IMeshBuffer //! Primitive type used for rendering (triangles, lines, ...) E_PRIMITIVE_TYPE PrimitiveType; - mutable void *HWBuffer; - bool BoundingBoxNeedsRecalculated; }; diff --git a/irr/src/CMeshManipulator.cpp b/irr/src/CMeshManipulator.cpp index 9b2bd0cde..2c9d05336 100644 --- a/irr/src/CMeshManipulator.cpp +++ b/irr/src/CMeshManipulator.cpp @@ -67,7 +67,7 @@ void recalculateNormalsT(IMeshBuffer *buffer, bool smooth, bool angleWeighted) core::vector3df weight(1.f, 1.f, 1.f); if (angleWeighted) - weight = irr::scene::getAngleWeight(v1, v2, v3); // writing irr::scene:: necessary for borland + weight = getAngleWeight(v1, v2, v3); buffer->getNormal(idx[i + 0]) += weight.X * normal; buffer->getNormal(idx[i + 1]) += weight.Y * normal; @@ -115,6 +115,21 @@ void CMeshManipulator::recalculateNormals(scene::IMesh *mesh, bool smooth, bool } } +template +void copyVertices(const scene::IVertexBuffer *src, scene::CVertexBuffer *dst) +{ + _IRR_DEBUG_BREAK_IF(T::getType() != src->getType()); + auto *data = static_cast(src->getData()); + dst->Data.assign(data, data + src->getCount()); +} + +static void copyIndices(const scene::IIndexBuffer *src, scene::SIndexBuffer *dst) +{ + _IRR_DEBUG_BREAK_IF(src->getType() != video::EIT_16BIT); + auto *data = static_cast(src->getData()); + dst->Data.assign(data, data + src->getCount()); +} + //! Clones a static IMesh into a modifyable SMesh. // not yet 32bit SMesh *CMeshManipulator::createMeshCopy(scene::IMesh *mesh) const @@ -132,30 +147,24 @@ SMesh *CMeshManipulator::createMeshCopy(scene::IMesh *mesh) const case video::EVT_STANDARD: { SMeshBuffer *buffer = new SMeshBuffer(); buffer->Material = mb->getMaterial(); - auto *vt = static_cast(mb->getVertices()); - buffer->VertexBuffer().insert(buffer->VertexBuffer().end(), vt, vt + mb->getVertexCount()); - auto *indices = mb->getIndices(); - buffer->IndexBuffer().insert(buffer->IndexBuffer().end(), indices, indices + mb->getIndexCount()); + copyVertices(mb->getVertexBuffer(), buffer->Vertices); + copyIndices(mb->getIndexBuffer(), buffer->Indices); clone->addMeshBuffer(buffer); buffer->drop(); } break; case video::EVT_2TCOORDS: { SMeshBufferLightMap *buffer = new SMeshBufferLightMap(); buffer->Material = mb->getMaterial(); - auto *vt = static_cast(mb->getVertices()); - buffer->VertexBuffer().insert(buffer->VertexBuffer().end(), vt, vt + mb->getVertexCount()); - auto *indices = mb->getIndices(); - buffer->IndexBuffer().insert(buffer->IndexBuffer().end(), indices, indices + mb->getIndexCount()); + copyVertices(mb->getVertexBuffer(), buffer->Vertices); + copyIndices(mb->getIndexBuffer(), buffer->Indices); clone->addMeshBuffer(buffer); buffer->drop(); } break; case video::EVT_TANGENTS: { SMeshBufferTangents *buffer = new SMeshBufferTangents(); buffer->Material = mb->getMaterial(); - auto *vt = static_cast(mb->getVertices()); - buffer->VertexBuffer().insert(buffer->VertexBuffer().end(), vt, vt + mb->getVertexCount()); - auto *indices = mb->getIndices(); - buffer->IndexBuffer().insert(buffer->IndexBuffer().end(), indices, indices + mb->getIndexCount()); + copyVertices(mb->getVertexBuffer(), buffer->Vertices); + copyIndices(mb->getIndexBuffer(), buffer->Indices); clone->addMeshBuffer(buffer); buffer->drop(); } break; diff --git a/irr/src/COBJMeshFileLoader.cpp b/irr/src/COBJMeshFileLoader.cpp index 064fc4186..bceba6a90 100644 --- a/irr/src/COBJMeshFileLoader.cpp +++ b/irr/src/COBJMeshFileLoader.cpp @@ -192,6 +192,7 @@ IAnimatedMesh *COBJMeshFileLoader::createMesh(io::IReadFile *file) faceCorners.set_used(0); // fast clear // read in all vertices + auto &Vertices = currMtl->Meshbuffer->Vertices->Data; linePtr = goNextWord(linePtr, endPtr); while (0 != linePtr[0]) { // Array to communicate with retrieveVertexIndices() @@ -228,8 +229,8 @@ IAnimatedMesh *COBJMeshFileLoader::createMesh(io::IReadFile *file) if (n != currMtl->VertMap.end()) { vertLocation = n->second; } else { - currMtl->Meshbuffer->VertexBuffer().push_back(v); - vertLocation = currMtl->Meshbuffer->VertexBuffer().size() - 1; + Vertices.push_back(v); + vertLocation = Vertices.size() - 1; currMtl->VertMap.emplace(v, vertLocation); } @@ -247,7 +248,7 @@ IAnimatedMesh *COBJMeshFileLoader::createMesh(io::IReadFile *file) } // triangulate the face - auto &Indices = currMtl->Meshbuffer->IndexBuffer(); + auto &Indices = currMtl->Meshbuffer->Indices->Data; const int c = faceCorners[0]; for (u32 i = 1; i < faceCorners.size() - 1; ++i) { // Add a triangle diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 52fbfb6b4..3ff83bdae 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -133,9 +133,10 @@ Hud::Hud(Client *client, LocalPlayer *player, rangelim(g_settings->getS16("selectionbox_width"), 1, 5); // Prepare mesh for compass drawing - auto &b = m_rotation_mesh_buffer; - auto &vertices = b.Vertices->Data; - auto &indices = b.Indices->Data; + m_rotation_mesh_buffer.reset(new scene::SMeshBuffer()); + auto *b = m_rotation_mesh_buffer.get(); + auto &vertices = b->Vertices->Data; + auto &indices = b->Indices->Data; vertices.resize(4); indices.resize(6); @@ -154,9 +155,9 @@ Hud::Hud(Client *client, LocalPlayer *player, indices[4] = 3; indices[5] = 0; - b.getMaterial().Lighting = false; - b.getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - //b.setHardwareMappingHint(scene::EHM_STATIC); // FIXME: incorrectly stack allocated, not safe! + b->getMaterial().Lighting = false; + b->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + b->setHardwareMappingHint(scene::EHM_STATIC); } void Hud::readScalingSetting() @@ -658,10 +659,10 @@ void Hud::drawCompassRotate(HudElement *e, video::ITexture *texture, driver->setTransform(video::ETS_VIEW, core::matrix4()); driver->setTransform(video::ETS_WORLD, Matrix); - video::SMaterial &material = m_rotation_mesh_buffer.getMaterial(); + auto &material = m_rotation_mesh_buffer->getMaterial(); material.TextureLayers[0].Texture = texture; driver->setMaterial(material); - driver->drawMeshBuffer(&m_rotation_mesh_buffer); + driver->drawMeshBuffer(m_rotation_mesh_buffer.get()); driver->setTransform(video::ETS_WORLD, core::matrix4()); driver->setTransform(video::ETS_VIEW, oldViewMat); diff --git a/src/client/hud.h b/src/client/hud.h index 55b24abd3..120215f45 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include "irr_ptr.h" #include "irr_aabb3d.h" #include "../hud.h" @@ -152,7 +153,7 @@ private: video::SMaterial m_selection_material; video::SMaterial m_block_bounds_material; - scene::SMeshBuffer m_rotation_mesh_buffer; + irr_ptr m_rotation_mesh_buffer; enum { diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 59883d052..5b47a32ff 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -594,12 +594,9 @@ void MapBlockBspTree::traverse(s32 node, v3f viewpoint, std::vector &output void PartialMeshBuffer::draw(video::IVideoDriver *driver) const { - // Swap out the index buffer before drawing the mesh - auto *old = m_buffer->Indices; - m_buffer->Indices = m_indices.get(); - m_buffer->setDirty(scene::EBT_INDEX); // TODO remove - driver->drawMeshBuffer(m_buffer); - m_buffer->Indices = old; + const auto pType = m_buffer->getPrimitiveType(); + driver->drawBuffers(m_buffer->getVertexBuffer(), m_indices.get(), + m_indices->getPrimitiveCount(pType), pType); } /* @@ -785,11 +782,6 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs } } - // Transparent parts have changing indices - // TODO: remove - for (auto &it : m_transparent_triangles) - it.buffer->setHardwareMappingHint(scene::EHM_STREAM, scene::EBT_INDEX); - m_bsp_tree.buildTree(&m_transparent_triangles, data->side_length); // Check if animation is required for this mesh diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index e958814f3..d2c651525 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -145,19 +145,18 @@ private: * * Attach alternate `Indices` to an existing mesh buffer, to make it possible to use different * indices with the same vertex buffer. - * */ class PartialMeshBuffer { public: PartialMeshBuffer(scene::SMeshBuffer *buffer, std::vector &&vertex_indices) : - m_buffer(buffer) + m_buffer(buffer), m_indices(make_irr()) { - m_indices.reset(new scene::SIndexBuffer()); m_indices->Data = std::move(vertex_indices); + m_indices->setHardwareMappingHint(scene::EHM_STATIC); } - scene::IMeshBuffer *getBuffer() const { return m_buffer; } + auto *getBuffer() const { return m_buffer; } void draw(video::IVideoDriver *driver) const;