Factorize vaomanager in its own file.
This commit is contained in:
parent
193b588e22
commit
af4136f864
@ -397,331 +397,6 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
|
|||||||
glGetError();
|
glGetError();
|
||||||
}
|
}
|
||||||
|
|
||||||
VAOManager::VAOManager()
|
|
||||||
{
|
|
||||||
vao[0] = vao[1] = vao[2] = 0;
|
|
||||||
vbo[0] = vbo[1] = vbo[2] = 0;
|
|
||||||
ibo[0] = ibo[1] = ibo[2] = 0;
|
|
||||||
vtx_cnt[0] = vtx_cnt[1] = vtx_cnt[2] = 0;
|
|
||||||
idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
|
|
||||||
vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
|
|
||||||
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
|
|
||||||
instance_count[0] = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &instance_vbo[i]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
|
|
||||||
#ifdef Buffer_Storage
|
|
||||||
if (irr_driver->hasBufferStorageExtension())
|
|
||||||
{
|
|
||||||
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
|
||||||
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
|
|
||||||
{
|
|
||||||
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint>::iterator It = Map.begin(), E = Map.end();
|
|
||||||
for (; It != E; It++)
|
|
||||||
{
|
|
||||||
glDeleteVertexArrays(1, &(It->second));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VAOManager::cleanInstanceVAOs()
|
|
||||||
{
|
|
||||||
cleanVAOMap(InstanceVAO);
|
|
||||||
InstanceVAO.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
VAOManager::~VAOManager()
|
|
||||||
{
|
|
||||||
cleanInstanceVAOs();
|
|
||||||
for (unsigned i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
if (vtx_mirror[i])
|
|
||||||
free(vtx_mirror[i]);
|
|
||||||
if (idx_mirror[i])
|
|
||||||
free(idx_mirror[i]);
|
|
||||||
if (vbo[i])
|
|
||||||
glDeleteBuffers(1, &vbo[i]);
|
|
||||||
if (ibo[i])
|
|
||||||
glDeleteBuffers(1, &ibo[i]);
|
|
||||||
if (vao[i])
|
|
||||||
glDeleteVertexArrays(1, &vao[i]);
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &instance_vbo[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
|
|
||||||
{
|
|
||||||
glBindVertexArray(0);
|
|
||||||
if (vbo[tp])
|
|
||||||
glDeleteBuffers(1, &vbo[tp]);
|
|
||||||
glGenBuffers(1, &vbo[tp]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
|
||||||
#ifdef Buffer_Storage
|
|
||||||
if (irr_driver->hasBufferStorageExtension())
|
|
||||||
{
|
|
||||||
glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
|
||||||
VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
|
|
||||||
if (ibo[tp])
|
|
||||||
glDeleteBuffers(1, &ibo[tp]);
|
|
||||||
glGenBuffers(1, &ibo[tp]);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u16)* idx_cnt[tp], idx_mirror[tp], GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VAOManager::regenerateVAO(enum VTXTYPE tp)
|
|
||||||
{
|
|
||||||
if (vao[tp])
|
|
||||||
glDeleteVertexArrays(1, &vao[tp]);
|
|
||||||
glGenVertexArrays(1, &vao[tp]);
|
|
||||||
glBindVertexArray(vao[tp]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
|
||||||
switch (tp)
|
|
||||||
{
|
|
||||||
case VTXTYPE_STANDARD:
|
|
||||||
// Position
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
|
||||||
// Normal
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
|
||||||
// Color
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
|
||||||
// Texcoord
|
|
||||||
glEnableVertexAttribArray(3);
|
|
||||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
|
||||||
break;
|
|
||||||
case VTXTYPE_TCOORD:
|
|
||||||
// Position
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
|
||||||
// Normal
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
|
||||||
// Color
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
|
||||||
// Texcoord
|
|
||||||
glEnableVertexAttribArray(3);
|
|
||||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
|
||||||
// SecondTexcoord
|
|
||||||
glEnableVertexAttribArray(4);
|
|
||||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36);
|
|
||||||
break;
|
|
||||||
case VTXTYPE_TANGENT:
|
|
||||||
// Position
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
|
||||||
// Normal
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
|
||||||
// Color
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
|
||||||
// Texcoord
|
|
||||||
glEnableVertexAttribArray(3);
|
|
||||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
|
||||||
// Tangent
|
|
||||||
glEnableVertexAttribArray(5);
|
|
||||||
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36);
|
|
||||||
// Bitangent
|
|
||||||
glEnableVertexAttribArray(6);
|
|
||||||
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VAOManager::regenerateInstancedVAO()
|
|
||||||
{
|
|
||||||
cleanInstanceVAOs();
|
|
||||||
|
|
||||||
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
|
|
||||||
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
|
||||||
{
|
|
||||||
video::E_VERTEX_TYPE tp = IrrVT[i];
|
|
||||||
if (!vbo[tp] || !ibo[tp])
|
|
||||||
continue;
|
|
||||||
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
|
||||||
glVertexAttribDivisor(7, 1);
|
|
||||||
glEnableVertexAttribArray(8);
|
|
||||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(8, 1);
|
|
||||||
glEnableVertexAttribArray(9);
|
|
||||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(9, 1);
|
|
||||||
glEnableVertexAttribArray(10);
|
|
||||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(10, 1);
|
|
||||||
glEnableVertexAttribArray(11);
|
|
||||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
|
||||||
glVertexAttribDivisor(11, 1);
|
|
||||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
|
|
||||||
|
|
||||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
|
||||||
glVertexAttribDivisor(7, 1);
|
|
||||||
glEnableVertexAttribArray(8);
|
|
||||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(8, 1);
|
|
||||||
glEnableVertexAttribArray(9);
|
|
||||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(9, 1);
|
|
||||||
glEnableVertexAttribArray(10);
|
|
||||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(10, 1);
|
|
||||||
glEnableVertexAttribArray(11);
|
|
||||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
|
||||||
glVertexAttribDivisor(11, 1);
|
|
||||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
|
|
||||||
|
|
||||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
|
||||||
glVertexAttribDivisor(7, 1);
|
|
||||||
glEnableVertexAttribArray(8);
|
|
||||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(8, 1);
|
|
||||||
glEnableVertexAttribArray(9);
|
|
||||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(9, 1);
|
|
||||||
glEnableVertexAttribArray(10);
|
|
||||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(10, 1);
|
|
||||||
glEnableVertexAttribArray(11);
|
|
||||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
|
||||||
glVertexAttribDivisor(11, 1);
|
|
||||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeRSM)] = vao;
|
|
||||||
|
|
||||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
|
|
||||||
glVertexAttribDivisor(7, 1);
|
|
||||||
glEnableVertexAttribArray(8);
|
|
||||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(8, 1);
|
|
||||||
glEnableVertexAttribArray(9);
|
|
||||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(9, 1);
|
|
||||||
glEnableVertexAttribArray(12);
|
|
||||||
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
|
|
||||||
glVertexAttribDivisor(12, 1);
|
|
||||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
|
|
||||||
{
|
|
||||||
switch (tp)
|
|
||||||
{
|
|
||||||
case VTXTYPE_STANDARD:
|
|
||||||
return getVertexPitchFromType(video::EVT_STANDARD);
|
|
||||||
case VTXTYPE_TCOORD:
|
|
||||||
return getVertexPitchFromType(video::EVT_2TCOORDS);
|
|
||||||
case VTXTYPE_TANGENT:
|
|
||||||
return getVertexPitchFromType(video::EVT_TANGENTS);
|
|
||||||
default:
|
|
||||||
assert(0 && "Wrong vtxtype");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
assert(0 && "Wrong vtxtype");
|
|
||||||
case video::EVT_STANDARD:
|
|
||||||
return VTXTYPE_STANDARD;
|
|
||||||
case video::EVT_2TCOORDS:
|
|
||||||
return VTXTYPE_TCOORD;
|
|
||||||
case video::EVT_TANGENTS:
|
|
||||||
return VTXTYPE_TANGENT;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
|
|
||||||
{
|
|
||||||
size_t old_vtx_cnt = vtx_cnt[tp];
|
|
||||||
vtx_cnt[tp] += mb->getVertexCount();
|
|
||||||
vtx_mirror[tp] = realloc(vtx_mirror[tp], vtx_cnt[tp] * getVertexPitch(tp));
|
|
||||||
intptr_t dstptr = (intptr_t)vtx_mirror[tp] + (old_vtx_cnt * getVertexPitch(tp));
|
|
||||||
memcpy((void *)dstptr, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp));
|
|
||||||
mappedBaseVertex[tp][mb] = old_vtx_cnt;
|
|
||||||
|
|
||||||
size_t old_idx_cnt = idx_cnt[tp];
|
|
||||||
idx_cnt[tp] += mb->getIndexCount();
|
|
||||||
idx_mirror[tp] = realloc(idx_mirror[tp], idx_cnt[tp] * sizeof(u16));
|
|
||||||
|
|
||||||
dstptr = (intptr_t)idx_mirror[tp] + (old_idx_cnt * sizeof(u16));
|
|
||||||
memcpy((void *)dstptr, mb->getIndices(), mb->getIndexCount() * sizeof(u16));
|
|
||||||
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
|
|
||||||
{
|
|
||||||
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
|
|
||||||
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
|
|
||||||
{
|
|
||||||
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
|
|
||||||
storedCPUBuffer[tp].push_back(mb);
|
|
||||||
append(mb, tp);
|
|
||||||
regenerateBuffer(tp);
|
|
||||||
regenerateVAO(tp);
|
|
||||||
regenerateInstancedVAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<scene::IMeshBuffer*, unsigned>::iterator It;
|
|
||||||
It = mappedBaseVertex[tp].find(mb);
|
|
||||||
assert(It != mappedBaseVertex[tp].end());
|
|
||||||
unsigned vtx = It->second;
|
|
||||||
It = mappedBaseIndex[tp].find(mb);
|
|
||||||
assert(It != mappedBaseIndex[tp].end());
|
|
||||||
return std::pair<unsigned, unsigned>(vtx, It->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
|
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
|
||||||
{
|
{
|
||||||
if (!UserConfigParams::m_profiler_enabled) return;
|
if (!UserConfigParams::m_profiler_enabled) return;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "irr_driver.hpp"
|
#include "irr_driver.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
|
#include "vaomanager.hpp"
|
||||||
|
|
||||||
void initGL();
|
void initGL();
|
||||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||||
@ -139,109 +139,6 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
|
|||||||
bool loadCompressedTexture(const std::string& compressed_tex);
|
bool loadCompressedTexture(const std::string& compressed_tex);
|
||||||
void saveCompressedTexture(const std::string& compressed_tex);
|
void saveCompressedTexture(const std::string& compressed_tex);
|
||||||
|
|
||||||
enum InstanceType
|
|
||||||
{
|
|
||||||
InstanceTypeDefault,
|
|
||||||
InstanceTypeShadow,
|
|
||||||
InstanceTypeRSM,
|
|
||||||
InstanceTypeGlow,
|
|
||||||
InstanceTypeCount,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
#endif
|
|
||||||
struct InstanceData
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Origin;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Orientation;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Scale;
|
|
||||||
uint64_t Texture;
|
|
||||||
uint64_t SecondTexture;
|
|
||||||
#ifdef WIN32
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct GlowInstanceData
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Origin;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Orientation;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Z;
|
|
||||||
} Scale;
|
|
||||||
unsigned Color;
|
|
||||||
#ifdef WIN32
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
#pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class VAOManager : public Singleton<VAOManager>
|
|
||||||
{
|
|
||||||
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
|
||||||
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
|
||||||
GLuint instance_vbo[InstanceTypeCount];
|
|
||||||
size_t instance_count[InstanceTypeCount];
|
|
||||||
void *Ptr[InstanceTypeCount];
|
|
||||||
void *VBOPtr[VTXTYPE_COUNT];
|
|
||||||
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
|
||||||
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
|
||||||
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
|
|
||||||
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
|
||||||
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
|
|
||||||
|
|
||||||
void cleanInstanceVAOs();
|
|
||||||
void regenerateBuffer(enum VTXTYPE);
|
|
||||||
void regenerateVAO(enum VTXTYPE);
|
|
||||||
void regenerateInstancedVAO();
|
|
||||||
size_t getVertexPitch(enum VTXTYPE) const;
|
|
||||||
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
|
|
||||||
void append(scene::IMeshBuffer *, VTXTYPE tp);
|
|
||||||
public:
|
|
||||||
VAOManager();
|
|
||||||
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
|
||||||
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
|
|
||||||
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
|
|
||||||
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
|
||||||
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; }
|
|
||||||
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
|
|
||||||
unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
|
|
||||||
~VAOManager();
|
|
||||||
};
|
|
||||||
|
|
||||||
void draw3DLine(const core::vector3df& start,
|
void draw3DLine(const core::vector3df& start,
|
||||||
const core::vector3df& end, irr::video::SColor color);
|
const core::vector3df& end, irr::video::SColor color);
|
||||||
|
|
||||||
|
320
src/graphics/vaomanager.cpp
Normal file
320
src/graphics/vaomanager.cpp
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
#include "vaomanager.hpp"
|
||||||
|
#include "stkmesh.hpp"
|
||||||
|
|
||||||
|
VAOManager::VAOManager()
|
||||||
|
{
|
||||||
|
vao[0] = vao[1] = vao[2] = 0;
|
||||||
|
vbo[0] = vbo[1] = vbo[2] = 0;
|
||||||
|
ibo[0] = ibo[1] = ibo[2] = 0;
|
||||||
|
vtx_cnt[0] = vtx_cnt[1] = vtx_cnt[2] = 0;
|
||||||
|
idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
|
||||||
|
vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
|
||||||
|
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
|
||||||
|
instance_count[0] = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||||
|
{
|
||||||
|
glGenBuffers(1, &instance_vbo[i]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
|
||||||
|
#ifdef Buffer_Storage
|
||||||
|
if (irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||||
|
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VAOManager::cleanInstanceVAOs()
|
||||||
|
{
|
||||||
|
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint>::iterator It = InstanceVAO.begin(), E = InstanceVAO.end();
|
||||||
|
for (; It != E; It++)
|
||||||
|
glDeleteVertexArrays(1, &(It->second));
|
||||||
|
InstanceVAO.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
VAOManager::~VAOManager()
|
||||||
|
{
|
||||||
|
cleanInstanceVAOs();
|
||||||
|
for (unsigned i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (vtx_mirror[i])
|
||||||
|
free(vtx_mirror[i]);
|
||||||
|
if (idx_mirror[i])
|
||||||
|
free(idx_mirror[i]);
|
||||||
|
if (vbo[i])
|
||||||
|
glDeleteBuffers(1, &vbo[i]);
|
||||||
|
if (ibo[i])
|
||||||
|
glDeleteBuffers(1, &ibo[i]);
|
||||||
|
if (vao[i])
|
||||||
|
glDeleteVertexArrays(1, &vao[i]);
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &instance_vbo[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
|
||||||
|
{
|
||||||
|
glBindVertexArray(0);
|
||||||
|
if (vbo[tp])
|
||||||
|
glDeleteBuffers(1, &vbo[tp]);
|
||||||
|
glGenBuffers(1, &vbo[tp]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
||||||
|
#ifdef Buffer_Storage
|
||||||
|
if (irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||||
|
VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
|
||||||
|
if (ibo[tp])
|
||||||
|
glDeleteBuffers(1, &ibo[tp]);
|
||||||
|
glGenBuffers(1, &ibo[tp]);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u16)* idx_cnt[tp], idx_mirror[tp], GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VAOManager::regenerateVAO(enum VTXTYPE tp)
|
||||||
|
{
|
||||||
|
if (vao[tp])
|
||||||
|
glDeleteVertexArrays(1, &vao[tp]);
|
||||||
|
glGenVertexArrays(1, &vao[tp]);
|
||||||
|
glBindVertexArray(vao[tp]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
||||||
|
switch (tp)
|
||||||
|
{
|
||||||
|
case VTXTYPE_STANDARD:
|
||||||
|
// Position
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
||||||
|
// Normal
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
||||||
|
// Color
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
||||||
|
// Texcoord
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
||||||
|
break;
|
||||||
|
case VTXTYPE_TCOORD:
|
||||||
|
// Position
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
||||||
|
// Normal
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
||||||
|
// Color
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
||||||
|
// Texcoord
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
||||||
|
// SecondTexcoord
|
||||||
|
glEnableVertexAttribArray(4);
|
||||||
|
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36);
|
||||||
|
break;
|
||||||
|
case VTXTYPE_TANGENT:
|
||||||
|
// Position
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0);
|
||||||
|
// Normal
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12);
|
||||||
|
// Color
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24);
|
||||||
|
// Texcoord
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28);
|
||||||
|
// Tangent
|
||||||
|
glEnableVertexAttribArray(5);
|
||||||
|
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36);
|
||||||
|
// Bitangent
|
||||||
|
glEnableVertexAttribArray(6);
|
||||||
|
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VAOManager::regenerateInstancedVAO()
|
||||||
|
{
|
||||||
|
cleanInstanceVAOs();
|
||||||
|
|
||||||
|
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
|
||||||
|
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
||||||
|
{
|
||||||
|
video::E_VERTEX_TYPE tp = IrrVT[i];
|
||||||
|
if (!vbo[tp] || !ibo[tp])
|
||||||
|
continue;
|
||||||
|
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(7);
|
||||||
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||||
|
glVertexAttribDivisor(7, 1);
|
||||||
|
glEnableVertexAttribArray(8);
|
||||||
|
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(8, 1);
|
||||||
|
glEnableVertexAttribArray(9);
|
||||||
|
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(9, 1);
|
||||||
|
glEnableVertexAttribArray(10);
|
||||||
|
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(10, 1);
|
||||||
|
glEnableVertexAttribArray(11);
|
||||||
|
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||||
|
glVertexAttribDivisor(11, 1);
|
||||||
|
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
|
||||||
|
|
||||||
|
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(7);
|
||||||
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||||
|
glVertexAttribDivisor(7, 1);
|
||||||
|
glEnableVertexAttribArray(8);
|
||||||
|
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(8, 1);
|
||||||
|
glEnableVertexAttribArray(9);
|
||||||
|
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(9, 1);
|
||||||
|
glEnableVertexAttribArray(10);
|
||||||
|
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(10, 1);
|
||||||
|
glEnableVertexAttribArray(11);
|
||||||
|
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||||
|
glVertexAttribDivisor(11, 1);
|
||||||
|
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
|
||||||
|
|
||||||
|
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(7);
|
||||||
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||||
|
glVertexAttribDivisor(7, 1);
|
||||||
|
glEnableVertexAttribArray(8);
|
||||||
|
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(8, 1);
|
||||||
|
glEnableVertexAttribArray(9);
|
||||||
|
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(9, 1);
|
||||||
|
glEnableVertexAttribArray(10);
|
||||||
|
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(10, 1);
|
||||||
|
glEnableVertexAttribArray(11);
|
||||||
|
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||||
|
glVertexAttribDivisor(11, 1);
|
||||||
|
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeRSM)] = vao;
|
||||||
|
|
||||||
|
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(7);
|
||||||
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
|
||||||
|
glVertexAttribDivisor(7, 1);
|
||||||
|
glEnableVertexAttribArray(8);
|
||||||
|
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(8, 1);
|
||||||
|
glEnableVertexAttribArray(9);
|
||||||
|
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(9, 1);
|
||||||
|
glEnableVertexAttribArray(12);
|
||||||
|
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||||
|
glVertexAttribDivisor(12, 1);
|
||||||
|
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
|
||||||
|
{
|
||||||
|
switch (tp)
|
||||||
|
{
|
||||||
|
case VTXTYPE_STANDARD:
|
||||||
|
return getVertexPitchFromType(video::EVT_STANDARD);
|
||||||
|
case VTXTYPE_TCOORD:
|
||||||
|
return getVertexPitchFromType(video::EVT_2TCOORDS);
|
||||||
|
case VTXTYPE_TANGENT:
|
||||||
|
return getVertexPitchFromType(video::EVT_TANGENTS);
|
||||||
|
default:
|
||||||
|
assert(0 && "Wrong vtxtype");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
assert(0 && "Wrong vtxtype");
|
||||||
|
case video::EVT_STANDARD:
|
||||||
|
return VTXTYPE_STANDARD;
|
||||||
|
case video::EVT_2TCOORDS:
|
||||||
|
return VTXTYPE_TCOORD;
|
||||||
|
case video::EVT_TANGENTS:
|
||||||
|
return VTXTYPE_TANGENT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
|
||||||
|
{
|
||||||
|
size_t old_vtx_cnt = vtx_cnt[tp];
|
||||||
|
vtx_cnt[tp] += mb->getVertexCount();
|
||||||
|
vtx_mirror[tp] = realloc(vtx_mirror[tp], vtx_cnt[tp] * getVertexPitch(tp));
|
||||||
|
intptr_t dstptr = (intptr_t)vtx_mirror[tp] + (old_vtx_cnt * getVertexPitch(tp));
|
||||||
|
memcpy((void *)dstptr, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp));
|
||||||
|
mappedBaseVertex[tp][mb] = old_vtx_cnt;
|
||||||
|
|
||||||
|
size_t old_idx_cnt = idx_cnt[tp];
|
||||||
|
idx_cnt[tp] += mb->getIndexCount();
|
||||||
|
idx_mirror[tp] = realloc(idx_mirror[tp], idx_cnt[tp] * sizeof(u16));
|
||||||
|
|
||||||
|
dstptr = (intptr_t)idx_mirror[tp] + (old_idx_cnt * sizeof(u16));
|
||||||
|
memcpy((void *)dstptr, mb->getIndices(), mb->getIndexCount() * sizeof(u16));
|
||||||
|
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
|
||||||
|
{
|
||||||
|
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
|
||||||
|
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
|
||||||
|
{
|
||||||
|
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
|
||||||
|
storedCPUBuffer[tp].push_back(mb);
|
||||||
|
append(mb, tp);
|
||||||
|
regenerateBuffer(tp);
|
||||||
|
regenerateVAO(tp);
|
||||||
|
regenerateInstancedVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<scene::IMeshBuffer*, unsigned>::iterator It;
|
||||||
|
It = mappedBaseVertex[tp].find(mb);
|
||||||
|
assert(It != mappedBaseVertex[tp].end());
|
||||||
|
unsigned vtx = It->second;
|
||||||
|
It = mappedBaseIndex[tp].find(mb);
|
||||||
|
assert(It != mappedBaseIndex[tp].end());
|
||||||
|
return std::pair<unsigned, unsigned>(vtx, It->second);
|
||||||
|
}
|
113
src/graphics/vaomanager.hpp
Normal file
113
src/graphics/vaomanager.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef VAOMANAGER_HPP
|
||||||
|
#define VAOMANAGER_HPP
|
||||||
|
|
||||||
|
#include "gl_headers.hpp"
|
||||||
|
#include "utils/singleton.hpp"
|
||||||
|
#include "irr_driver.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
enum InstanceType
|
||||||
|
{
|
||||||
|
InstanceTypeDefault,
|
||||||
|
InstanceTypeShadow,
|
||||||
|
InstanceTypeRSM,
|
||||||
|
InstanceTypeGlow,
|
||||||
|
InstanceTypeCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#endif
|
||||||
|
struct InstanceData
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Origin;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Orientation;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Scale;
|
||||||
|
uint64_t Texture;
|
||||||
|
uint64_t SecondTexture;
|
||||||
|
#ifdef WIN32
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
} __attribute__((packed));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct GlowInstanceData
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Origin;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Orientation;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
float Z;
|
||||||
|
} Scale;
|
||||||
|
unsigned Color;
|
||||||
|
#ifdef WIN32
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
} __attribute__((packed));
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class VAOManager : public Singleton<VAOManager>
|
||||||
|
{
|
||||||
|
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
||||||
|
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
||||||
|
GLuint instance_vbo[InstanceTypeCount];
|
||||||
|
size_t instance_count[InstanceTypeCount];
|
||||||
|
void *Ptr[InstanceTypeCount];
|
||||||
|
void *VBOPtr[VTXTYPE_COUNT];
|
||||||
|
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
||||||
|
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
||||||
|
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
|
||||||
|
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||||
|
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
|
||||||
|
|
||||||
|
void cleanInstanceVAOs();
|
||||||
|
void regenerateBuffer(enum VTXTYPE);
|
||||||
|
void regenerateVAO(enum VTXTYPE);
|
||||||
|
void regenerateInstancedVAO();
|
||||||
|
size_t getVertexPitch(enum VTXTYPE) const;
|
||||||
|
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
|
||||||
|
void append(scene::IMeshBuffer *, VTXTYPE tp);
|
||||||
|
public:
|
||||||
|
VAOManager();
|
||||||
|
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
||||||
|
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
|
||||||
|
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
|
||||||
|
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
||||||
|
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; }
|
||||||
|
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
|
||||||
|
unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
|
||||||
|
~VAOManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user