Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
abb14c7cab
@ -49,4 +49,4 @@ struct DrawElementsIndirectCommand{
|
||||
GLuint baseInstance;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -397,340 +397,6 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
|
||||
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);
|
||||
}
|
||||
|
||||
size_t VAOManager::appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, instance_count[0] * sizeof(InstanceData), instance_data.size() * sizeof(InstanceData), instance_data.data());
|
||||
size_t result = instance_count[0];
|
||||
instance_count[0] += instance_data.size();
|
||||
return result;
|
||||
}
|
||||
|
||||
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
|
||||
{
|
||||
if (!UserConfigParams::m_profiler_enabled) return;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <vector>
|
||||
#include "irr_driver.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include "vaomanager.hpp"
|
||||
|
||||
void initGL();
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||
@ -139,110 +139,6 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
|
||||
bool loadCompressedTexture(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 *);
|
||||
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
|
||||
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,
|
||||
const core::vector3df& end, irr::video::SColor color);
|
||||
|
||||
|
@ -506,27 +506,27 @@ void IrrDriver::initDevice()
|
||||
// Default false value for hasVSLayer if --no-graphics argument is used
|
||||
if (!ProfileWorld::isNoGraphics())
|
||||
{
|
||||
if (GLEW_AMD_vertex_shader_layer) {
|
||||
if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
|
||||
hasVSLayer = true;
|
||||
Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
|
||||
}
|
||||
if (GLEW_ARB_buffer_storage) {
|
||||
if (hasGLExtension("GL_ARB_buffer_storage")) {
|
||||
hasBuffserStorage = true;
|
||||
Log::info("GLDriver", "ARB Buffer Storage enabled");
|
||||
}
|
||||
if (GLEW_ARB_base_instance) {
|
||||
if (hasGLExtension("GL_ARB_base_instance")) {
|
||||
hasBaseInstance = true;
|
||||
Log::info("GLDriver", "ARB Base Instance enabled");
|
||||
}
|
||||
if (GLEW_ARB_draw_indirect) {
|
||||
if (hasGLExtension("GL_ARB_draw_indirect")) {
|
||||
hasDrawIndirect = true;
|
||||
Log::info("GLDriver", "ARB Draw Indirect enabled");
|
||||
}
|
||||
if (GLEW_ARB_compute_shader) {
|
||||
if (hasGLExtension("GL_ARB_compute_shader")) {
|
||||
hasComputeShaders = true;
|
||||
Log::info("GLDriver", "ARB Compute Shader enabled");
|
||||
}
|
||||
if (GLEW_ARB_texture_storage) {
|
||||
if (hasGLExtension("GL_ARB_texture_storage")) {
|
||||
hasTextureStorage = true;
|
||||
Log::info("GLDriver", "ARB Texture Storage enabled");
|
||||
}
|
||||
@ -1742,17 +1742,23 @@ void IrrDriver::displayFPS()
|
||||
if (low > kilotris) low = kilotris;
|
||||
if (high < kilotris) high = kilotris;
|
||||
|
||||
static char buffer[128];
|
||||
core::stringw fpsString;
|
||||
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
{
|
||||
sprintf(
|
||||
buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d",
|
||||
min, fps, max,
|
||||
poly_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
||||
poly_count[SHADOW_PASS],
|
||||
m_last_light_bucket_distance
|
||||
);
|
||||
fpsString += _("FPS: ");
|
||||
fpsString += core::stringw(min);
|
||||
fpsString += _("/");
|
||||
fpsString += core::stringw(fps);
|
||||
fpsString += _("/");
|
||||
fpsString += core::stringw(max);
|
||||
fpsString += _(" PolyCount: ");
|
||||
fpsString += _(" (Solid) ");
|
||||
fpsString += core::stringw(poly_count[SOLID_NORMAL_AND_DEPTH_PASS]);
|
||||
fpsString += _(" (Shadows) ");
|
||||
fpsString += core::stringw(poly_count[SHADOW_PASS]);
|
||||
fpsString += _(" LightDist: ");
|
||||
fpsString += core::stringw(m_last_light_bucket_distance);
|
||||
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
poly_count[SHADOW_PASS] = 0;
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
@ -1761,12 +1767,17 @@ void IrrDriver::displayFPS()
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "FPS: %i/%i/%i - %i KTris", min, fps, max,
|
||||
(int)roundf(kilotris));
|
||||
fpsString += _("FPS: ");
|
||||
fpsString += core::stringw(min);
|
||||
fpsString += _("/");
|
||||
fpsString += core::stringw(fps);
|
||||
fpsString += _("/");
|
||||
fpsString += core::stringw(max);
|
||||
fpsString += _(" - ");
|
||||
fpsString += core::stringw((int)roundf(kilotris));
|
||||
fpsString += _("KTris");
|
||||
}
|
||||
|
||||
core::stringw fpsString = buffer;
|
||||
|
||||
static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
|
||||
|
||||
font->draw( fpsString.c_str(), core::rect< s32 >(100,0,400,50), fpsColor, false );
|
||||
|
@ -419,7 +419,7 @@ private:
|
||||
void renderRSM();
|
||||
void renderGlow(std::vector<GlowData>& glows);
|
||||
void renderSSAO();
|
||||
void renderLights(unsigned pointlightCount);
|
||||
void renderLights(unsigned pointlightCount, bool hasShadow);
|
||||
void renderShadowsDebug();
|
||||
void doScreenShot();
|
||||
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);
|
||||
|
@ -311,7 +311,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
|
||||
// Lights
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
|
||||
renderLights(pointlightcount);
|
||||
renderLights(pointlightcount, hasShadow);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,10 @@ unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, fl
|
||||
return lightnum;
|
||||
}
|
||||
|
||||
void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
|
||||
glDisable(GL_BLEND);
|
||||
@ -171,7 +171,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
return;
|
||||
|
||||
m_rtts->getFBO(FBO_DIFFUSE).Bind();
|
||||
if (UserConfigParams::m_gi)
|
||||
if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
|
@ -439,7 +439,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
|
||||
swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
delete[] tmp;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
|
||||
@ -574,4 +574,4 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ const core::vector3df& rotation,
|
||||
const core::vector3df& scale) :
|
||||
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
firstTime = true;
|
||||
isGLInitialized = false;
|
||||
isMaterialInitialized = false;
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::cleanGLMeshes()
|
||||
@ -34,8 +35,6 @@ void STKAnimatedMesh::cleanGLMeshes()
|
||||
glDeleteVertexArrays(1, &(mesh.vao));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
if (mesh.instance_buffer)
|
||||
glDeleteBuffers(1, &(mesh.instance_buffer));
|
||||
#ifdef Bindless_Texture_Support
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
@ -48,16 +47,16 @@ void STKAnimatedMesh::cleanGLMeshes()
|
||||
|
||||
void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
|
||||
{
|
||||
firstTime = true;
|
||||
isGLInitialized = false;
|
||||
isMaterialInitialized = false;
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < MAT_COUNT; i++)
|
||||
MeshSolidMaterial[i].clearWithoutDeleting();
|
||||
CAnimatedMeshSceneNode::setMesh(mesh);
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::update()
|
||||
void STKAnimatedMesh::updateNoGL()
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
scene::IMesh* m = getMeshForCurrentFrame();
|
||||
|
||||
if (m)
|
||||
@ -68,8 +67,9 @@ void STKAnimatedMesh::update()
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstTime)
|
||||
if (!isMaterialInitialized)
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
@ -101,6 +101,32 @@ void STKAnimatedMesh::update()
|
||||
{
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
}
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::updateGL()
|
||||
{
|
||||
|
||||
scene::IMesh* m = getMeshForCurrentFrame();
|
||||
|
||||
if (!isGLInitialized)
|
||||
{
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
|
||||
if (!rnd->isTransparent())
|
||||
{
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
InitTextures(mesh, MatType);
|
||||
}
|
||||
|
||||
@ -117,8 +143,8 @@ void STKAnimatedMesh::update()
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
isGLInitialized = true;
|
||||
}
|
||||
firstTime = false;
|
||||
|
||||
for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
@ -164,71 +190,6 @@ void STKAnimatedMesh::render()
|
||||
|
||||
++PassCount;
|
||||
|
||||
update();
|
||||
|
||||
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||
core::matrix4 invmodel;
|
||||
AbsoluteTransformation.getInverse(invmodel);
|
||||
|
||||
GLMesh* mesh;
|
||||
for_in(mesh, MeshSolidMaterial[MAT_DEFAULT])
|
||||
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterial[MAT_ALPHA_REF])
|
||||
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterial[MAT_DETAIL])
|
||||
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterial[MAT_UNLIT])
|
||||
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
||||
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
{
|
||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||
|
||||
if (!TransparentMesh[TM_BUBBLE].empty())
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
|
||||
GLMesh* mesh;
|
||||
if (World::getWorld() && World::getWorld()->isFogEnabled())
|
||||
{
|
||||
const Track * const track = World::getWorld()->getTrack();
|
||||
|
||||
// Todo : put everything in a ubo
|
||||
const float fogmax = track->getFogMax();
|
||||
const float startH = track->getFogStartHeight();
|
||||
const float endH = track->getFogEndHeight();
|
||||
const float start = track->getFogStart();
|
||||
const float end = track->getFogEnd();
|
||||
const video::SColor tmpcol = track->getFogColor();
|
||||
|
||||
video::SColorf col(tmpcol.getRed() / 255.0f,
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f);
|
||||
|
||||
for_in(mesh, TransparentMesh[TM_DEFAULT])
|
||||
ListBlendTransparentFog::getInstance()->push_back(
|
||||
STK::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col));
|
||||
for_in(mesh, TransparentMesh[TM_ADDITIVE])
|
||||
ListAdditiveTransparentFog::getInstance()->push_back(
|
||||
STK::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col));
|
||||
}
|
||||
else
|
||||
{
|
||||
for_in(mesh, TransparentMesh[TM_DEFAULT])
|
||||
pushVector(ListBlendTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, TransparentMesh[TM_ADDITIVE])
|
||||
pushVector(ListAdditiveTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
|
||||
}
|
||||
return;
|
||||
}
|
||||
updateNoGL();
|
||||
updateGL();
|
||||
}
|
||||
|
@ -10,12 +10,14 @@
|
||||
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool firstTime;
|
||||
bool isMaterialInitialized;
|
||||
bool isGLInitialized;
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix;
|
||||
void cleanGLMeshes();
|
||||
public:
|
||||
virtual void update();
|
||||
virtual void updateNoGL();
|
||||
virtual void updateGL();
|
||||
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
|
||||
irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
|
||||
|
@ -36,7 +36,6 @@ struct GLMesh {
|
||||
GLuint vao;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint instance_buffer;
|
||||
video::ITexture *textures[6];
|
||||
GLenum PrimitiveType;
|
||||
GLenum IndexType;
|
||||
@ -69,7 +68,8 @@ protected:
|
||||
public:
|
||||
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
||||
virtual void update() = 0;
|
||||
virtual void updateNoGL() = 0;
|
||||
virtual void updateGL() = 0;
|
||||
virtual bool glow() const = 0;
|
||||
virtual bool isImmediateDraw() const { return false; }
|
||||
bool isCulledForPlayerCam() const { return m_culledForPlayerCam; }
|
||||
|
@ -43,63 +43,7 @@ void STKMeshSceneNode::createGLMeshes()
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
isMaterialInitialized = false;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setFirstTimeMaterial()
|
||||
{
|
||||
if (isMaterialInitialized)
|
||||
return;
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
if (!isObject(type))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", type);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
if (rnd->isTransparent())
|
||||
{
|
||||
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
|
||||
if (!immediate_draw)
|
||||
TransparentMesh[TranspMat].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!isDisplacement);
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
if (!immediate_draw)
|
||||
{
|
||||
InitTextures(mesh, MatType);
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
}
|
||||
}
|
||||
|
||||
if (!immediate_draw && irr_driver->hasARB_base_instance())
|
||||
{
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
isGLInitialized = false;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::cleanGLMeshes()
|
||||
@ -115,8 +59,6 @@ void STKMeshSceneNode::cleanGLMeshes()
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
if (mesh.index_buffer)
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
if (mesh.instance_buffer)
|
||||
glDeleteBuffers(1, &(mesh.instance_buffer));
|
||||
#ifdef Bindless_Texture_Support
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
@ -170,11 +112,47 @@ void STKMeshSceneNode::updatevbo()
|
||||
}
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::update()
|
||||
void STKMeshSceneNode::updateNoGL()
|
||||
{
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
setFirstTimeMaterial();
|
||||
if (!isMaterialInitialized)
|
||||
{
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
if (!isObject(type))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", type);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
if (rnd->isTransparent())
|
||||
{
|
||||
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
|
||||
if (!immediate_draw)
|
||||
TransparentMesh[TranspMat].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!isDisplacement);
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
if (!immediate_draw)
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
}
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
@ -185,6 +163,45 @@ void STKMeshSceneNode::update()
|
||||
}
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::updateGL()
|
||||
{
|
||||
if (isGLInitialized)
|
||||
return;
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
|
||||
|
||||
if (!rnd->isTransparent())
|
||||
{
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
if (!immediate_draw)
|
||||
InitTextures(mesh, MatType);
|
||||
}
|
||||
|
||||
if (!immediate_draw && irr_driver->hasARB_base_instance())
|
||||
{
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
isGLInitialized = true;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
@ -205,7 +222,8 @@ void STKMeshSceneNode::render()
|
||||
|
||||
++PassCount;
|
||||
|
||||
update();
|
||||
updateNoGL();
|
||||
updateGL();
|
||||
|
||||
bool isTransparent;
|
||||
|
||||
|
@ -19,13 +19,15 @@ protected:
|
||||
void setFirstTimeMaterial();
|
||||
void updatevbo();
|
||||
bool isMaterialInitialized;
|
||||
bool isGLInitialized;
|
||||
bool immediate_draw;
|
||||
bool update_each_frame;
|
||||
bool isDisplacement;
|
||||
bool isGlow;
|
||||
video::SColor glowcolor;
|
||||
public:
|
||||
virtual void update();
|
||||
virtual void updateNoGL();
|
||||
virtual void updateGL();
|
||||
void setReloadEachFrame(bool);
|
||||
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <SViewFrustum.h>
|
||||
#include "callbacks.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include <omp.h>
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "lod_node.hpp"
|
||||
@ -179,6 +178,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
|
||||
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
|
||||
if (!node)
|
||||
return;
|
||||
node->updateNoGL();
|
||||
DeferredUpdate.push_back(node);
|
||||
|
||||
if (node->isImmediateDraw())
|
||||
@ -507,7 +507,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
break;
|
||||
}*/
|
||||
for (unsigned i = 0; i < DeferredUpdate.size(); i++)
|
||||
DeferredUpdate[i]->update();
|
||||
DeferredUpdate[i]->updateGL();
|
||||
|
||||
if (!irr_driver->hasARB_draw_indirect())
|
||||
return;
|
||||
|
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::unordered_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);
|
||||
}
|
114
src/graphics/vaomanager.hpp
Normal file
114
src/graphics/vaomanager.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef VAOMANAGER_HPP
|
||||
#define VAOMANAGER_HPP
|
||||
|
||||
#include "gl_headers.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
#include "irr_driver.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_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::unordered_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
|
@ -422,7 +422,7 @@ XMLNode *FileManager::createXMLTreeFromString(const std::string & content)
|
||||
{
|
||||
char *b = new char[content.size()];
|
||||
memcpy(b, content.c_str(), content.size());
|
||||
io::IReadFile * ireadfile = m_file_system->createMemoryReadFile(b, strlen(b), "tempfile", true);
|
||||
io::IReadFile * ireadfile = m_file_system->createMemoryReadFile(b, content.size(), "tempfile", true);
|
||||
io::IXMLReader * reader = m_file_system->createXMLReader(ireadfile);
|
||||
XMLNode* node = new XMLNode(reader);
|
||||
reader->drop();
|
||||
@ -791,7 +791,7 @@ void FileManager::checkAndCreateConfigDir()
|
||||
{
|
||||
m_user_config_dir = getenv("HOME");
|
||||
checkAndCreateDirectory(m_user_config_dir);
|
||||
|
||||
|
||||
m_user_config_dir += "/.config";
|
||||
if(!checkAndCreateDirectory(m_user_config_dir))
|
||||
{
|
||||
|
@ -193,6 +193,9 @@ void TrackInfoScreen::init()
|
||||
getWidget<LabelWidget>("highscore2")->setVisible(false);
|
||||
getWidget<LabelWidget>("highscore3")->setVisible(false);
|
||||
}
|
||||
|
||||
RibbonWidget* bt_start = getWidget<GUIEngine::RibbonWidget>("buttons");
|
||||
bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
} // init
|
||||
|
||||
@ -325,3 +328,37 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GUIEngine::EventPropagation TrackInfoScreen::filterActions(PlayerAction action,
|
||||
int deviceID,
|
||||
const unsigned int value,
|
||||
Input::InputType type,
|
||||
int playerId)
|
||||
{
|
||||
GUIEngine::EventPropagation result = EVENT_LET;
|
||||
RibbonWidget* bt_start = getWidget<GUIEngine::RibbonWidget>("buttons");
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case PA_MENU_LEFT:
|
||||
case PA_MENU_RIGHT:
|
||||
{
|
||||
if (bt_start->isFocusedForPlayer(playerId))
|
||||
{
|
||||
result = EVENT_BLOCK;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PA_MENU_UP:
|
||||
case PA_MENU_DOWN:
|
||||
case PA_MENU_SELECT:
|
||||
case PA_MENU_CANCEL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
} // filterActions
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -74,6 +74,14 @@ public:
|
||||
virtual void loadedFromFile();
|
||||
virtual void eventCallback(GUIEngine::Widget *,const std::string &name ,
|
||||
const int player_id);
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual GUIEngine::EventPropagation filterActions( PlayerAction action,
|
||||
int deviceID,
|
||||
const unsigned int value,
|
||||
Input::InputType type,
|
||||
int playerId) OVERRIDE;
|
||||
|
||||
void onEnterPressedInternal();
|
||||
void setTrack(Track *track);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user