Put all pieces together and clean up leftover code

This commit is contained in:
sfan5 2024-08-28 21:46:52 +02:00
parent 6b7fc1e9fe
commit 62131fe295
11 changed files with 105 additions and 169 deletions

@ -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;

@ -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<f32> &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

@ -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

@ -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()) {

@ -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 <typename T> void recalculateBoundingBox(const CVertexBuffer<T> *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 <typename T1, typename T2> 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;
};

@ -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 <typename T>
void copyVertices(const scene::IVertexBuffer *src, scene::CVertexBuffer<T> *dst)
{
_IRR_DEBUG_BREAK_IF(T::getType() != src->getType());
auto *data = static_cast<const T*>(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<const u16*>(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<const video::S3DVertex*>(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<const video::S3DVertex2TCoords*>(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<const video::S3DVertexTangents*>(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;

@ -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

@ -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);

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIFont.h>
#include <SMaterial.h>
#include <SMeshBuffer.h>
#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<scene::SMeshBuffer> m_rotation_mesh_buffer;
enum
{

@ -594,12 +594,9 @@ void MapBlockBspTree::traverse(s32 node, v3f viewpoint, std::vector<s32> &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

@ -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<u16> &&vertex_indices) :
m_buffer(buffer)
m_buffer(buffer), m_indices(make_irr<scene::SIndexBuffer>())
{
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;