Fixes needed to use irrArray backed by std::vector (#12263)

This commit is contained in:
paradust7 2022-05-21 15:11:49 -07:00 committed by GitHub
parent bc59fcf5c5
commit 2742fef458
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 55 deletions

@ -449,15 +449,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
drawcall_count += draw_order.size(); drawcall_count += draw_order.size();
for (auto &descriptor : draw_order) { for (auto &descriptor : draw_order) {
scene::IMeshBuffer *buf; scene::IMeshBuffer *buf = descriptor.getBuffer();
if (descriptor.m_use_partial_buffer) {
descriptor.m_partial_buffer->beforeDraw();
buf = descriptor.m_partial_buffer->getBuffer();
}
else {
buf = descriptor.m_buffer;
}
// Check and abort if the machine is swapping a lot // Check and abort if the machine is swapping a lot
if (draw.getTimerTime() > 2000) { if (draw.getTimerTime() > 2000) {
@ -501,7 +493,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
m.setTranslation(block_wpos - offset); m.setTranslation(block_wpos - offset);
driver->setTransform(video::ETS_WORLD, m); driver->setTransform(video::ETS_WORLD, m);
driver->drawMeshBuffer(buf); descriptor.draw(driver);
vertex_count += buf->getIndexCount(); vertex_count += buf->getIndexCount();
} }
@ -812,15 +804,7 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
drawcall_count += draw_order.size(); drawcall_count += draw_order.size();
for (auto &descriptor : draw_order) { for (auto &descriptor : draw_order) {
scene::IMeshBuffer *buf; scene::IMeshBuffer *buf = descriptor.getBuffer();
if (descriptor.m_use_partial_buffer) {
descriptor.m_partial_buffer->beforeDraw();
buf = descriptor.m_partial_buffer->getBuffer();
}
else {
buf = descriptor.m_buffer;
}
// Check and abort if the machine is swapping a lot // Check and abort if the machine is swapping a lot
if (draw.getTimerTime() > 1000) { if (draw.getTimerTime() > 1000) {
@ -845,7 +829,7 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
m.setTranslation(block_wpos - offset); m.setTranslation(block_wpos - offset);
driver->setTransform(video::ETS_WORLD, m); driver->setTransform(video::ETS_WORLD, m);
driver->drawMeshBuffer(buf); descriptor.draw(driver);
vertex_count += buf->getIndexCount(); vertex_count += buf->getIndexCount();
} }
@ -966,3 +950,18 @@ void ClientMap::updateTransparentMeshBuffers()
m_needs_update_transparent_meshes = false; m_needs_update_transparent_meshes = false;
} }
scene::IMeshBuffer* ClientMap::DrawDescriptor::getBuffer()
{
return m_use_partial_buffer ? m_partial_buffer->getBuffer() : m_buffer;
}
void ClientMap::DrawDescriptor::draw(video::IVideoDriver* driver)
{
if (m_use_partial_buffer) {
m_partial_buffer->beforeDraw();
driver->drawMeshBuffer(m_partial_buffer->getBuffer());
m_partial_buffer->afterDraw();
} else {
driver->drawMeshBuffer(m_buffer);
}
}

@ -174,6 +174,9 @@ private:
DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) : DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) :
m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true) m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true)
{} {}
scene::IMeshBuffer* getBuffer();
void draw(video::IVideoDriver* driver);
}; };
Client *m_client; Client *m_client;

@ -1162,15 +1162,16 @@ void MapBlockBspTree::traverse(s32 node, v3f viewpoint, std::vector<s32> &output
void PartialMeshBuffer::beforeDraw() const void PartialMeshBuffer::beforeDraw() const
{ {
// Patch the indexes in the mesh buffer before draw // Patch the indexes in the mesh buffer before draw
m_buffer->Indices = std::move(m_vertex_indexes);
m_buffer->Indices.clear();
if (!m_vertex_indexes.empty()) {
for (auto index : m_vertex_indexes)
m_buffer->Indices.push_back(index);
}
m_buffer->setDirty(scene::EBT_INDEX); m_buffer->setDirty(scene::EBT_INDEX);
} }
void PartialMeshBuffer::afterDraw() const
{
// Take the data back
m_vertex_indexes = std::move(m_buffer->Indices.steal());
}
/* /*
MapBlockMesh MapBlockMesh
*/ */
@ -1514,7 +1515,7 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
const auto &t = m_transparent_triangles[i]; const auto &t = m_transparent_triangles[i];
if (current_buffer != t.buffer) { if (current_buffer != t.buffer) {
if (current_buffer) { if (current_buffer) {
m_transparent_buffers.emplace_back(current_buffer, current_strain); m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
current_strain.clear(); current_strain.clear();
} }
current_buffer = t.buffer; current_buffer = t.buffer;
@ -1525,7 +1526,7 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
} }
if (!current_strain.empty()) if (!current_strain.empty())
m_transparent_buffers.emplace_back(current_buffer, current_strain); m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
} }
void MapBlockMesh::consolidateTransparentBuffers() void MapBlockMesh::consolidateTransparentBuffers()
@ -1539,7 +1540,7 @@ void MapBlockMesh::consolidateTransparentBuffers()
for (const auto &t : m_transparent_triangles) { for (const auto &t : m_transparent_triangles) {
if (current_buffer != t.buffer) { if (current_buffer != t.buffer) {
if (current_buffer != nullptr) { if (current_buffer != nullptr) {
this->m_transparent_buffers.emplace_back(current_buffer, current_strain); this->m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
current_strain.clear(); current_strain.clear();
} }
current_buffer = t.buffer; current_buffer = t.buffer;
@ -1550,7 +1551,7 @@ void MapBlockMesh::consolidateTransparentBuffers()
} }
if (!current_strain.empty()) { if (!current_strain.empty()) {
this->m_transparent_buffers.emplace_back(current_buffer, current_strain); this->m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
} }
} }

@ -140,20 +140,31 @@ private:
s32 root = -1; // index of the root node s32 root = -1; // index of the root node
}; };
/*
* PartialMeshBuffer
*
* Attach alternate `Indices` to an existing mesh buffer, to make it possible to use different
* indices with the same vertex buffer.
*
* Irrlicht does not currently support this: `CMeshBuffer` ties together a single vertex buffer
* and a single index buffer. There's no way to share these between mesh buffers.
*
*/
class PartialMeshBuffer class PartialMeshBuffer
{ {
public: public:
PartialMeshBuffer(scene::SMeshBuffer *buffer, const std::vector<u16> &vertex_indexes) : PartialMeshBuffer(scene::SMeshBuffer *buffer, std::vector<u16> &&vertex_indexes) :
m_buffer(buffer), m_vertex_indexes(vertex_indexes) m_buffer(buffer), m_vertex_indexes(std::move(vertex_indexes))
{} {}
scene::IMeshBuffer *getBuffer() const { return m_buffer; } scene::IMeshBuffer *getBuffer() const { return m_buffer; }
const std::vector<u16> &getVertexIndexes() const { return m_vertex_indexes; } const std::vector<u16> &getVertexIndexes() const { return m_vertex_indexes; }
void beforeDraw() const; void beforeDraw() const;
void afterDraw() const;
private: private:
scene::SMeshBuffer *m_buffer; scene::SMeshBuffer *m_buffer;
std::vector<u16> m_vertex_indexes; mutable std::vector<u16> m_vertex_indexes;
}; };
/* /*

@ -292,9 +292,6 @@ shadow_offset(0), shadow_alpha(0), fallback(0)
Driver->grab(); Driver->grab();
setInvisibleCharacters(L" "); setInvisibleCharacters(L" ");
// Glyphs aren't reference counted, so don't try to delete them when we free the array.
Glyphs.set_free_when_destroyed(false);
} }
bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antialias, const bool transparency) bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antialias, const bool transparency)
@ -411,8 +408,7 @@ CGUITTFont::~CGUITTFont()
{ {
// Delete the glyphs and glyph pages. // Delete the glyphs and glyph pages.
reset_images(); reset_images();
CGUITTAssistDelete::Delete(Glyphs); Glyphs.clear();
//Glyphs.clear();
// We aren't using this face anymore. // We aren't using this face anymore.
auto n = c_faces.find(filename); auto n = c_faces.find(filename);
@ -675,6 +671,8 @@ void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& positio
update_glyph_pages(); update_glyph_pages();
auto it = Render_Map.begin(); auto it = Render_Map.begin();
auto ie = Render_Map.end(); auto ie = Render_Map.end();
core::array<core::vector2di> tmp_positions;
core::array<core::recti> tmp_source_rects;
while (it != ie) while (it != ie)
{ {
CGUITTGlyphPage* page = it->second; CGUITTGlyphPage* page = it->second;
@ -696,10 +694,8 @@ void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& positio
do do
++i; ++i;
while (i < page->render_positions.size() && page->render_colors[i] == colprev); while (i < page->render_positions.size() && page->render_colors[i] == colprev);
core::array<core::vector2di> tmp_positions; tmp_positions.set_data(&page->render_positions[ibegin], i - ibegin);
core::array<core::recti> tmp_source_rects; tmp_source_rects.set_data(&page->render_source_rects[ibegin], i - ibegin);
tmp_positions.set_pointer(&page->render_positions[ibegin], i - ibegin, false, false); // no copy
tmp_source_rects.set_pointer(&page->render_source_rects[ibegin], i - ibegin, false, false);
--i; --i;
if (!use_transparency) if (!use_transparency)

@ -37,6 +37,7 @@
#include <map> #include <map>
#include <irrUString.h> #include <irrUString.h>
#include "util/enriched_string.h" #include "util/enriched_string.h"
#include "util/basic_macros.h"
#include FT_FREETYPE_H #include FT_FREETYPE_H
namespace irr namespace irr
@ -46,23 +47,34 @@ namespace gui
struct SGUITTFace; struct SGUITTFace;
class CGUITTFont; class CGUITTFont;
//! Class to assist in deleting glyphs.
class CGUITTAssistDelete
{
public:
template <class T, typename TAlloc>
static void Delete(core::array<T, TAlloc>& a)
{
TAlloc allocator;
allocator.deallocate(a.pointer());
}
};
//! Structure representing a single TrueType glyph. //! Structure representing a single TrueType glyph.
struct SGUITTGlyph struct SGUITTGlyph
{ {
//! Constructor. //! Constructor.
SGUITTGlyph() : isLoaded(false), glyph_page(0), surface(0), parent(0) {} SGUITTGlyph() :
isLoaded(false),
glyph_page(0),
source_rect(),
offset(),
advance(),
surface(0),
parent(0)
{}
DISABLE_CLASS_COPY(SGUITTGlyph);
//! This class would be trivially copyable except for the reference count on `surface`.
SGUITTGlyph(SGUITTGlyph &&other) :
isLoaded(other.isLoaded),
glyph_page(other.glyph_page),
source_rect(other.source_rect),
offset(other.offset),
advance(other.advance),
surface(other.surface),
parent(other.parent)
{
other.surface = 0;
}
//! Destructor. //! Destructor.
~SGUITTGlyph() { unload(); } ~SGUITTGlyph() { unload(); }