Gather object in instanced calls
This commit is contained in:
parent
0fa13334ea
commit
3083df450f
8
data/shaders/glow_object.frag
Normal file
8
data/shaders/glow_object.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
in vec4 glowColor;
|
||||||
|
|
||||||
|
flat out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(glowColor.rgb, 1.0);
|
||||||
|
}
|
24
data/shaders/glow_object.vert
Normal file
24
data/shaders/glow_object.vert
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
layout(location = 0) in vec3 Position;
|
||||||
|
layout(location = 1) in vec3 Normal;
|
||||||
|
layout(location = 2) in vec4 Color;
|
||||||
|
layout(location = 3) in vec2 Texcoord;
|
||||||
|
layout(location = 5) in vec3 Tangent;
|
||||||
|
layout(location = 6) in vec3 Bitangent;
|
||||||
|
|
||||||
|
layout(location = 7) in vec3 Origin;
|
||||||
|
layout(location = 8) in vec3 Orientation;
|
||||||
|
layout(location = 9) in vec3 Scale;
|
||||||
|
layout(location = 12) in vec4 GlowColor;
|
||||||
|
|
||||||
|
flat out vec4 glowColor;
|
||||||
|
|
||||||
|
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||||
|
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||||
|
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
|
||||||
|
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||||
|
glowColor = GlowColor;
|
||||||
|
}
|
27
data/shaders/instanced_rsm.frag
Normal file
27
data/shaders/instanced_rsm.frag
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef GL_ARB_bindless_texture
|
||||||
|
uniform sampler2D tex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in vec2 uv;
|
||||||
|
in vec3 nor;
|
||||||
|
in vec4 color;
|
||||||
|
#ifdef GL_ARB_bindless_texture
|
||||||
|
flat in uvec2 handle;
|
||||||
|
#endif
|
||||||
|
layout (location = 0) out vec3 RSMColor;
|
||||||
|
layout (location = 1) out vec3 RSMNormals;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#ifdef GL_ARB_bindless_texture
|
||||||
|
vec4 col = texture(sampler2D(handle), uv);
|
||||||
|
#ifdef SRGBBindlessFix
|
||||||
|
col.xyz = pow(col.xyz, vec3(2.2));
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
vec4 col = texture(tex, uv);
|
||||||
|
#endif
|
||||||
|
if (col.a < .5) discard;
|
||||||
|
RSMColor = col.xyz * color.rgb;
|
||||||
|
RSMNormals = .5 * normalize(nor) + .5;
|
||||||
|
}
|
39
data/shaders/instanced_rsm.vert
Normal file
39
data/shaders/instanced_rsm.vert
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
uniform mat4 RSMMatrix;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 Position;
|
||||||
|
layout(location = 1) in vec3 Normal;
|
||||||
|
layout(location = 2) in vec4 Color;
|
||||||
|
layout(location = 3) in vec2 Texcoord;
|
||||||
|
layout(location = 4) in vec2 SecondTexcoord;
|
||||||
|
layout(location = 7) in vec3 Origin;
|
||||||
|
layout(location = 8) in vec3 Orientation;
|
||||||
|
layout(location = 9) in vec3 Scale;
|
||||||
|
#ifdef GL_ARB_bindless_texture
|
||||||
|
layout(location = 10) in uvec2 Handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out vec3 nor;
|
||||||
|
out vec2 uv;
|
||||||
|
out vec2 uv_bis;
|
||||||
|
out vec4 color;
|
||||||
|
#ifdef GL_ARB_bindless_texture
|
||||||
|
flat out uvec2 handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||||
|
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||||
|
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
|
||||||
|
mat4 TransposeInverseModel = transpose(inverse(ModelMatrix));
|
||||||
|
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||||
|
nor = (TransposeInverseModel * vec4(Normal, 0.)).xyz;
|
||||||
|
uv = Texcoord;
|
||||||
|
color = Color.zyxw;
|
||||||
|
#ifdef GL_ARB_bindless_texture
|
||||||
|
handle = Handle;
|
||||||
|
#endif
|
||||||
|
}
|
@ -601,9 +601,22 @@ VAOManager::VAOManager()
|
|||||||
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
|
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
|
||||||
instance_count[0] = 0;
|
instance_count[0] = 0;
|
||||||
|
|
||||||
glGenBuffers(1, &instance_vbo[0]);
|
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]);
|
{
|
||||||
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(float)* 9, 0, GL_STATIC_DRAW);
|
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)
|
static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
|
||||||
@ -618,9 +631,7 @@ static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>,
|
|||||||
void VAOManager::cleanInstanceVAOs()
|
void VAOManager::cleanInstanceVAOs()
|
||||||
{
|
{
|
||||||
cleanVAOMap(InstanceVAO);
|
cleanVAOMap(InstanceVAO);
|
||||||
cleanVAOMap(ShadowInstanceVAO);
|
|
||||||
InstanceVAO.clear();
|
InstanceVAO.clear();
|
||||||
ShadowInstanceVAO.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VAOManager::~VAOManager()
|
VAOManager::~VAOManager()
|
||||||
@ -639,7 +650,11 @@ VAOManager::~VAOManager()
|
|||||||
if (vao[i])
|
if (vao[i])
|
||||||
glDeleteVertexArrays(1, &vao[i]);
|
glDeleteVertexArrays(1, &vao[i]);
|
||||||
}
|
}
|
||||||
glDeleteBuffers(1, &instance_vbo[0]);
|
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &instance_vbo[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
|
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
|
||||||
@ -743,13 +758,11 @@ void VAOManager::regenerateInstancedVAO()
|
|||||||
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
|
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
|
||||||
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
||||||
{
|
{
|
||||||
for (unsigned j = 0; j < InstanceTypeCount; j++)
|
|
||||||
{
|
|
||||||
video::E_VERTEX_TYPE tp = IrrVT[i];
|
video::E_VERTEX_TYPE tp = IrrVT[i];
|
||||||
if (!vbo[tp] || !ibo[tp])
|
if (!vbo[tp] || !ibo[tp])
|
||||||
continue;
|
continue;
|
||||||
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[j]);
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
glEnableVertexAttribArray(7);
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||||
@ -766,10 +779,10 @@ void VAOManager::regenerateInstancedVAO()
|
|||||||
glEnableVertexAttribArray(11);
|
glEnableVertexAttribArray(11);
|
||||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||||
glVertexAttribDivisor(11, 1);
|
glVertexAttribDivisor(11, 1);
|
||||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, (InstanceType) j)] = vao;
|
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
|
||||||
|
|
||||||
GLuint shadow_vao = createVAO(vbo[tp], ibo[tp], tp);
|
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[j]);
|
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
|
||||||
|
|
||||||
glEnableVertexAttribArray(7);
|
glEnableVertexAttribArray(7);
|
||||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||||
@ -784,11 +797,47 @@ void VAOManager::regenerateInstancedVAO()
|
|||||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||||
glVertexAttribDivisor(10, 1);
|
glVertexAttribDivisor(10, 1);
|
||||||
glEnableVertexAttribArray(11);
|
glEnableVertexAttribArray(11);
|
||||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)+2 * sizeof(unsigned)));
|
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||||
glVertexAttribDivisor(11, 1);
|
glVertexAttribDivisor(11, 1);
|
||||||
ShadowInstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, (InstanceType)j)] = shadow_vao;
|
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);
|
glBindVertexArray(0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,6 +142,9 @@ void saveCompressedTexture(const std::string& compressed_tex);
|
|||||||
enum InstanceType
|
enum InstanceType
|
||||||
{
|
{
|
||||||
InstanceTypeDefault,
|
InstanceTypeDefault,
|
||||||
|
InstanceTypeShadow,
|
||||||
|
InstanceTypeRSM,
|
||||||
|
InstanceTypeGlow,
|
||||||
InstanceTypeCount,
|
InstanceTypeCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -172,23 +175,53 @@ struct InstanceData
|
|||||||
uint64_t SecondTexture;
|
uint64_t SecondTexture;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
|
||||||
#else
|
#else
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
#endif
|
#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>
|
class VAOManager : public Singleton<VAOManager>
|
||||||
{
|
{
|
||||||
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
||||||
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
||||||
GLuint instance_vbo[1];
|
GLuint instance_vbo[InstanceTypeCount];
|
||||||
size_t instance_count[1];
|
size_t instance_count[InstanceTypeCount];
|
||||||
|
void *Ptr[InstanceTypeCount];
|
||||||
void *VBOPtr[VTXTYPE_COUNT];
|
void *VBOPtr[VTXTYPE_COUNT];
|
||||||
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
||||||
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
||||||
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[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<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||||
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO, ShadowInstanceVAO;
|
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
|
||||||
|
|
||||||
void cleanInstanceVAOs();
|
void cleanInstanceVAOs();
|
||||||
void regenerateBuffer(enum VTXTYPE);
|
void regenerateBuffer(enum VTXTYPE);
|
||||||
@ -201,11 +234,12 @@ public:
|
|||||||
VAOManager();
|
VAOManager();
|
||||||
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
||||||
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
|
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)]; }
|
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
||||||
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[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 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)]; }
|
unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
|
||||||
unsigned getShadowInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return ShadowInstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
|
|
||||||
~VAOManager();
|
~VAOManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -449,6 +449,12 @@ void ParticleSystemProxy::render() {
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParticleSystemProxy::update()
|
||||||
|
{
|
||||||
|
doParticleSystem(os::Timer::getTime());
|
||||||
|
return (IsVisible && (Particles.size() != 0));
|
||||||
|
}
|
||||||
|
|
||||||
void ParticleSystemProxy::OnRegisterSceneNode()
|
void ParticleSystemProxy::OnRegisterSceneNode()
|
||||||
{
|
{
|
||||||
doParticleSystem(os::Timer::getTime());
|
doParticleSystem(os::Timer::getTime());
|
||||||
|
@ -81,6 +81,7 @@ public:
|
|||||||
const float* getColorTo() const { return m_color_to; }
|
const float* getColorTo() const { return m_color_to; }
|
||||||
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
||||||
void setFlip();
|
void setFlip();
|
||||||
|
bool update();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GPUPARTICLES_H
|
#endif // GPUPARTICLES_H
|
||||||
|
@ -166,6 +166,11 @@ void IrrDriver::IncreaseObjectCount()
|
|||||||
object_count[m_phase]++;
|
object_count[m_phase]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IrrDriver::IncreasePolyCount(unsigned Polys)
|
||||||
|
{
|
||||||
|
poly_count[m_phase] += Polys;
|
||||||
|
}
|
||||||
|
|
||||||
core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
|
core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
|
||||||
{
|
{
|
||||||
return m_mrt;
|
return m_mrt;
|
||||||
@ -1631,6 +1636,7 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void IrrDriver::setRTT(RTT* rtt)
|
void IrrDriver::setRTT(RTT* rtt)
|
||||||
{
|
{
|
||||||
|
memset(m_shadow_camnodes, 0, 4 * sizeof(void*));
|
||||||
m_rtts = rtt;
|
m_rtts = rtt;
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -1733,13 +1739,14 @@ void IrrDriver::displayFPS()
|
|||||||
if (UserConfigParams::m_artist_debug_mode)
|
if (UserConfigParams::m_artist_debug_mode)
|
||||||
{
|
{
|
||||||
sprintf(
|
sprintf(
|
||||||
buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
|
buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d",
|
||||||
min, fps, max,
|
min, fps, max,
|
||||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
poly_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
||||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
poly_count[SHADOW_PASS],
|
||||||
object_count[TRANSPARENT_PASS],
|
|
||||||
m_last_light_bucket_distance
|
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;
|
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||||
object_count[TRANSPARENT_PASS] = 0;
|
object_count[TRANSPARENT_PASS] = 0;
|
||||||
|
@ -359,12 +359,14 @@ private:
|
|||||||
/** Performance stats */
|
/** Performance stats */
|
||||||
unsigned m_last_light_bucket_distance;
|
unsigned m_last_light_bucket_distance;
|
||||||
unsigned object_count[PASS_COUNT];
|
unsigned object_count[PASS_COUNT];
|
||||||
|
unsigned poly_count[PASS_COUNT];
|
||||||
u32 m_renderpass;
|
u32 m_renderpass;
|
||||||
u32 m_lensflare_query;
|
u32 m_lensflare_query;
|
||||||
bool m_query_issued;
|
bool m_query_issued;
|
||||||
class STKMeshSceneNode *m_sun_interposer;
|
class STKMeshSceneNode *m_sun_interposer;
|
||||||
scene::CLensFlareSceneNode *m_lensflare;
|
scene::CLensFlareSceneNode *m_lensflare;
|
||||||
scene::ICameraSceneNode *m_suncam;
|
scene::ICameraSceneNode *m_suncam;
|
||||||
|
scene::ICameraSceneNode *m_shadow_camnodes[4];
|
||||||
float m_shadows_cam[4][24];
|
float m_shadows_cam[4][24];
|
||||||
|
|
||||||
std::vector<GlowData> m_glowing;
|
std::vector<GlowData> m_glowing;
|
||||||
@ -406,6 +408,7 @@ private:
|
|||||||
void renderLights(unsigned pointlightCount);
|
void renderLights(unsigned pointlightCount);
|
||||||
void renderShadowsDebug();
|
void renderShadowsDebug();
|
||||||
void doScreenShot();
|
void doScreenShot();
|
||||||
|
void PrepareDrawCalls();
|
||||||
public:
|
public:
|
||||||
IrrDriver();
|
IrrDriver();
|
||||||
~IrrDriver();
|
~IrrDriver();
|
||||||
@ -421,6 +424,7 @@ public:
|
|||||||
return sun_ortho_matrix;
|
return sun_ortho_matrix;
|
||||||
}
|
}
|
||||||
void IncreaseObjectCount();
|
void IncreaseObjectCount();
|
||||||
|
void IncreasePolyCount(unsigned);
|
||||||
core::array<video::IRenderTarget> &getMainSetup();
|
core::array<video::IRenderTarget> &getMainSetup();
|
||||||
void updateConfigIfRelevant();
|
void updateConfigIfRelevant();
|
||||||
void setAllMaterialFlags(scene::IMesh *mesh) const;
|
void setAllMaterialFlags(scene::IMesh *mesh) const;
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "utils/helpers.hpp"
|
#include "utils/helpers.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
#include "utils/profiler.hpp"
|
#include "utils/profiler.hpp"
|
||||||
|
#include "stkscenemanager.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -269,10 +270,35 @@ void IrrDriver::renderGLSL(float dt)
|
|||||||
getPostProcessing()->update(dt);
|
getPostProcessing()->update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLsync m_sync;
|
||||||
|
|
||||||
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
|
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
|
||||||
{
|
{
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||||
|
m_scene_manager->setActiveCamera(camnode);
|
||||||
|
|
||||||
|
// Add a 1 s timeout
|
||||||
|
if (!m_sync)
|
||||||
|
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
|
||||||
|
/* switch (reason)
|
||||||
|
{
|
||||||
|
case GL_ALREADY_SIGNALED:
|
||||||
|
printf("Already Signaled\n");
|
||||||
|
break;
|
||||||
|
case GL_TIMEOUT_EXPIRED:
|
||||||
|
printf("Timeout Expired\n");
|
||||||
|
break;
|
||||||
|
case GL_CONDITION_SATISFIED:
|
||||||
|
printf("Condition Satisfied\n");
|
||||||
|
break;
|
||||||
|
case GL_WAIT_FAILED:
|
||||||
|
printf("Wait Failed\n");
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
|
PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF);
|
||||||
|
PrepareDrawCalls();
|
||||||
|
PROFILER_POP_CPU_MARKER();
|
||||||
// Shadows
|
// Shadows
|
||||||
{
|
{
|
||||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||||
@ -323,6 +349,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
|
|||||||
renderSolidSecondPass();
|
renderSolidSecondPass();
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
|
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
|
||||||
if (getNormals())
|
if (getNormals())
|
||||||
{
|
{
|
||||||
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
||||||
@ -514,7 +542,9 @@ void IrrDriver::renderParticles()
|
|||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
|
for (unsigned i = 0; i < ParticlesList::getInstance()->size(); ++i)
|
||||||
|
ParticlesList::getInstance()->at(i)->render();
|
||||||
|
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of
|
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of
|
||||||
@ -593,6 +623,11 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
|||||||
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
|
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
|
||||||
|
|
||||||
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
|
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!m_shadow_camnodes[i])
|
||||||
|
m_shadow_camnodes[i] = (scene::ICameraSceneNode *) m_suncam->clone();
|
||||||
|
}
|
||||||
sun_ortho_matrix.clear();
|
sun_ortho_matrix.clear();
|
||||||
|
|
||||||
if (World::getWorld() && World::getWorld()->getTrack())
|
if (World::getWorld() && World::getWorld()->getTrack())
|
||||||
@ -670,8 +705,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
|||||||
const float units_per_w = w / 1024;
|
const float units_per_w = w / 1024;
|
||||||
const float units_per_h = h / 1024;*/
|
const float units_per_h = h / 1024;*/
|
||||||
|
|
||||||
m_suncam->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
|
m_shadow_camnodes[i]->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
|
||||||
m_suncam->render();
|
m_shadow_camnodes[i]->render();
|
||||||
|
|
||||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||||
}
|
}
|
||||||
@ -773,16 +808,35 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
|||||||
for (u32 i = 0; i < glowcount; i++)
|
for (u32 i = 0; i < glowcount; i++)
|
||||||
{
|
{
|
||||||
const GlowData &dat = glows[i];
|
const GlowData &dat = glows[i];
|
||||||
scene::ISceneNode * const cur = dat.node;
|
scene::ISceneNode * cur = dat.node;
|
||||||
|
|
||||||
//TODO : implement culling on gpu
|
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
|
||||||
// Quick box-based culling
|
node->setGlowColors(SColor(0, dat.b * 255.f, dat.g * 255.f, dat.r * 255.f));
|
||||||
// const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
if (!irr_driver->hasARB_draw_indirect())
|
||||||
// if (!nodebox.intersectsWithBox(cambox))
|
node->render();
|
||||||
// continue;
|
}
|
||||||
|
|
||||||
cb->setColor(dat.r, dat.g, dat.b);
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
cur->render();
|
{
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
glUseProgram(MeshShader::InstancedColorizeShader::getInstance()->Program);
|
||||||
|
|
||||||
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
{
|
||||||
|
if (GlowPassCmd::getInstance()->Size)
|
||||||
|
{
|
||||||
|
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
|
||||||
|
(const void*)(GlowPassCmd::getInstance()->Offset * sizeof(DrawElementsIndirectCommand)),
|
||||||
|
GlowPassCmd::getInstance()->Size,
|
||||||
|
sizeof(DrawElementsIndirectCommand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < ListInstancedGlow::getInstance()->size(); i++)
|
||||||
|
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((GlowPassCmd::getInstance()->Offset + i) * sizeof(DrawElementsIndirectCommand)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
@ -117,16 +117,16 @@ struct custom_unroll_args<N, List...>
|
|||||||
|
|
||||||
|
|
||||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename... TupleType>
|
template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename... TupleType>
|
||||||
void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
|
void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > &meshes)
|
||||||
{
|
{
|
||||||
glUseProgram(Shader::getInstance()->Program);
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||||
for (unsigned i = 0; i < meshes->size(); i++)
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
{
|
{
|
||||||
std::vector<GLuint> Textures;
|
std::vector<GLuint> Textures;
|
||||||
std::vector<uint64_t> Handles;
|
std::vector<uint64_t> Handles;
|
||||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
|
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||||
if (!irr_driver->hasARB_base_instance())
|
if (!irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(mesh.vao);
|
glBindVertexArray(mesh.vao);
|
||||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||||
@ -148,68 +148,33 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
|||||||
Shader::getInstance()->SetTextureHandles(Handles);
|
Shader::getInstance()->SetTextureHandles(Handles);
|
||||||
else
|
else
|
||||||
Shader::getInstance()->SetTextureUnits(Textures);
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
|
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int...List>
|
#ifdef Draw_Indirect
|
||||||
struct instanced_custom_unroll_args;
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
|
void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<GLMesh *> &meshes, Args...args)
|
||||||
template<>
|
|
||||||
struct instanced_custom_unroll_args<>
|
|
||||||
{
|
|
||||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
|
||||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
|
||||||
{
|
|
||||||
const GLMesh *mesh = STK::tuple_get<0>(t);
|
|
||||||
size_t instance_count = STK::tuple_get<1>(t);
|
|
||||||
irr_driver->IncreaseObjectCount();
|
|
||||||
GLenum ptype = mesh->PrimitiveType;
|
|
||||||
GLenum itype = mesh->IndexType;
|
|
||||||
size_t count = mesh->IndexCount;
|
|
||||||
|
|
||||||
Shader->setUniforms(args...);
|
|
||||||
#ifdef Base_Instance_Support
|
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glDrawElementsInstancedBaseVertexBaseInstance(ptype, count, itype, (const void*)mesh->vaoOffset, instance_count, mesh->vaoBaseVertex, mesh->vaoBaseInstance);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int N, int...List>
|
|
||||||
struct instanced_custom_unroll_args<N, List...>
|
|
||||||
{
|
|
||||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
|
||||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
|
||||||
{
|
|
||||||
instanced_custom_unroll_args<List...>::template exec<T>(Shader, t, STK::tuple_get<N>(t), args...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename... TupleType>
|
|
||||||
void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
|
|
||||||
{
|
{
|
||||||
glUseProgram(Shader::getInstance()->Program);
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
for (unsigned i = 0; i < meshes->size(); i++)
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||||
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
{
|
{
|
||||||
std::vector<GLuint> Textures;
|
std::vector<GLuint> Textures;
|
||||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
|
GLMesh *mesh = meshes[i];
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (mesh.VAOType != VertexType)
|
if (mesh->VAOType != VT)
|
||||||
Log::error("RenderGeometry", "Wrong instanced vertex format");
|
Log::error("RenderGeometry", "Wrong instanced vertex format");
|
||||||
#endif
|
#endif
|
||||||
if (!irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(mesh.vao);
|
|
||||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id]));
|
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j].m_id]));
|
||||||
Shader::getInstance()->SetTextureUnits(Textures);
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
|
|
||||||
|
Shader::getInstance()->setUniforms(args...);
|
||||||
|
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
static GLsync m_sync;
|
|
||||||
|
|
||||||
#ifdef Multi_Draw_Indirect
|
#ifdef Multi_Draw_Indirect
|
||||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
@ -228,9 +193,11 @@ void multidraw1stPass(Args...args)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static core::vector3df windDir;
|
||||||
|
|
||||||
void IrrDriver::renderSolidFirstPass()
|
void IrrDriver::renderSolidFirstPass()
|
||||||
{
|
{
|
||||||
|
windDir = getWindDir();
|
||||||
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
||||||
glClearColor(0., 0., 0., 0.);
|
glClearColor(0., 0., 0., 0.);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
@ -241,166 +208,88 @@ void IrrDriver::renderSolidFirstPass()
|
|||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
|
|
||||||
ListMatDefault::getInstance()->clear();
|
|
||||||
ListMatAlphaRef::getInstance()->clear();
|
|
||||||
ListMatSphereMap::getInstance()->clear();
|
|
||||||
ListMatDetails::getInstance()->clear();
|
|
||||||
ListMatUnlit::getInstance()->clear();
|
|
||||||
ListMatNormalMap::getInstance()->clear();
|
|
||||||
ListMatGrass::getInstance()->clear();
|
|
||||||
ListMatSplatting::getInstance()->clear();
|
|
||||||
ListInstancedMatDefault::getInstance()->clear();
|
|
||||||
ListInstancedMatAlphaRef::getInstance()->clear();
|
|
||||||
ListInstancedMatGrass::getInstance()->clear();
|
|
||||||
ListInstancedMatNormalMap::getInstance()->clear();
|
|
||||||
// Add a 30 ms timeout
|
|
||||||
if (!m_sync)
|
|
||||||
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 30000000);
|
|
||||||
/* switch (reason)
|
|
||||||
{
|
|
||||||
case GL_ALREADY_SIGNALED:
|
|
||||||
printf("Already Signaled\n");
|
|
||||||
break;
|
|
||||||
case GL_TIMEOUT_EXPIRED:
|
|
||||||
printf("Timeout Expired\n");
|
|
||||||
break;
|
|
||||||
case GL_CONDITION_SATISFIED:
|
|
||||||
printf("Condition Satisfied\n");
|
|
||||||
break;
|
|
||||||
case GL_WAIT_FAILED:
|
|
||||||
printf("Wait Failed\n");
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
||||||
|
|
||||||
if (!UserConfigParams::m_dynamic_lights)
|
if (!UserConfigParams::m_dynamic_lights)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
|
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
|
||||||
|
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < ImmediateDrawList::getInstance()->size(); i++)
|
||||||
|
ImmediateDrawList::getInstance()->at(i)->render();
|
||||||
|
|
||||||
std::vector<TexUnit> object_pass1_texunits = TexUnits(TexUnit(0, true) );
|
std::vector<TexUnit> object_pass1_texunits = TexUnits(TexUnit(0, true) );
|
||||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatDefault::getInstance());
|
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatDefault::getInstance()->SolidPass);
|
||||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::getInstance());
|
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatSplatting::getInstance()->SolidPass);
|
||||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::getInstance());
|
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(object_pass1_texunits, ListMatUnlit::getInstance()->SolidPass);
|
||||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatSplatting::getInstance());
|
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatAlphaRef::getInstance()->SolidPass);
|
||||||
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(object_pass1_texunits, ListMatUnlit::getInstance());
|
renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatGrass::getInstance()->SolidPass);
|
||||||
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatAlphaRef::getInstance());
|
|
||||||
renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatGrass::getInstance());
|
|
||||||
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS, 2, 1>(TexUnits(
|
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS, 2, 1>(TexUnits(
|
||||||
TexUnit(1, false),
|
TexUnit(1, false),
|
||||||
TexUnit(0, true)
|
TexUnit(0, true)
|
||||||
), ListMatNormalMap::getInstance());
|
), ListMatNormalMap::getInstance()->SolidPass);
|
||||||
|
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::getInstance()->SolidPass);
|
||||||
|
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::getInstance()->SolidPass);
|
||||||
|
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
|
||||||
if (UserConfigParams::m_azdo)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
|
||||||
DrawElementsIndirectCommand *CommandBufferPtr = SolidPassCmd::getInstance()->Ptr;
|
|
||||||
|
|
||||||
size_t offset = 0;
|
|
||||||
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatDefault::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatDefault::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatDefault::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = CommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = ListInstancedMatDefault::getInstance()->size();
|
|
||||||
|
|
||||||
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatNormalMap::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatNormalMap::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatNormalMap::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = CommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = ListInstancedMatNormalMap::getInstance()->size();
|
|
||||||
|
|
||||||
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatAlphaRef::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatAlphaRef::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatAlphaRef::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = CommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = ListInstancedMatAlphaRef::getInstance()->size();
|
|
||||||
|
|
||||||
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatGrass::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatGrass::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatGrass::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = CommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
SolidPassCmd::getInstance()->Size[MAT_GRASS] = ListInstancedMatGrass::getInstance()->size();
|
|
||||||
#ifdef Multi_Draw_Indirect
|
#ifdef Multi_Draw_Indirect
|
||||||
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>();
|
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>();
|
||||||
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>();
|
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>();
|
||||||
multidraw1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>();
|
multidraw1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>();
|
||||||
core::vector3df dir = ListInstancedMatGrass::getInstance()->empty() ? core::vector3df(0., 0., 0.) : STK::tuple_get<2>(ListInstancedMatGrass::getInstance()->at(0));
|
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_SPHEREMAP, video::EVT_STANDARD>();
|
||||||
multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(dir);
|
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>();
|
||||||
|
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_UNLIT, video::EVT_STANDARD>();
|
||||||
|
multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(windDir);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
#ifdef Draw_Indirect
|
||||||
|
else if (irr_driver->hasARB_draw_indirect())
|
||||||
{
|
{
|
||||||
if (irr_driver->hasARB_base_instance())
|
// Default
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>(
|
||||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, video::EVT_STANDARD>(
|
TexUnits(TexUnit(0, true)), ListInstancedMatDefault::getInstance()->SolidPass);
|
||||||
TexUnits(TexUnit(0, true)),
|
// Alpha ref
|
||||||
ListInstancedMatDefault::getInstance());
|
renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(
|
||||||
if (irr_driver->hasARB_base_instance())
|
TexUnits(TexUnit(0, true)), ListInstancedMatAlphaRef::getInstance()->SolidPass);
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
// Unlit
|
||||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader, video::EVT_STANDARD>(
|
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_UNLIT, video::EVT_STANDARD>(
|
||||||
TexUnits(TexUnit(0, true)),
|
TexUnits(TexUnit(0, true)), ListInstancedMatUnlit::getInstance()->SolidPass);
|
||||||
ListInstancedMatAlphaRef::getInstance());
|
// Spheremap
|
||||||
if (irr_driver->hasARB_base_instance())
|
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_SPHEREMAP, video::EVT_STANDARD>(
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
TexUnits(TexUnit(0, true)), ListInstancedMatSphereMap::getInstance()->SolidPass);
|
||||||
renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, video::EVT_STANDARD, 2>(
|
// Grass
|
||||||
TexUnits(TexUnit(0, true)),
|
renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(
|
||||||
ListInstancedMatGrass::getInstance());
|
TexUnits(TexUnit(0, true)), ListInstancedMatGrass::getInstance()->SolidPass, windDir);
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
|
// Detail
|
||||||
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, video::EVT_TANGENTS>(
|
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>(
|
||||||
TexUnits(TexUnit(1, false), TexUnit(0, true)),
|
TexUnits(TexUnit(0, true)), ListInstancedMatDetails::getInstance()->SolidPass);
|
||||||
ListInstancedMatNormalMap::getInstance());
|
|
||||||
|
// Normal Map
|
||||||
|
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
|
||||||
|
TexUnits(TexUnit(1, false), TexUnit(0, true)), ListInstancedMatNormalMap::getInstance()->SolidPass);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
|
template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
|
||||||
void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes, const std::vector<uint64_t> &Prefilled_Handle,
|
void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > &meshes, const std::vector<uint64_t> &Prefilled_Handle,
|
||||||
const std::vector<GLuint> &Prefilled_Tex)
|
const std::vector<GLuint> &Prefilled_Tex)
|
||||||
{
|
{
|
||||||
glUseProgram(Shader::getInstance()->Program);
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||||
for (unsigned i = 0; i < meshes->size(); i++)
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> Handles(Prefilled_Handle);
|
std::vector<uint64_t> Handles(Prefilled_Handle);
|
||||||
std::vector<GLuint> Textures(Prefilled_Tex);
|
std::vector<GLuint> Textures(Prefilled_Tex);
|
||||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
|
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||||
if (!irr_driver->hasARB_base_instance())
|
if (!irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(mesh.vao);
|
glBindVertexArray(mesh.vao);
|
||||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||||
@ -423,27 +312,28 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
|||||||
Shader::getInstance()->SetTextureHandles(Handles);
|
Shader::getInstance()->SetTextureHandles(Handles);
|
||||||
else
|
else
|
||||||
Shader::getInstance()->SetTextureUnits(Textures);
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
|
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Shader, int...List, typename... TupleType>
|
#ifdef Draw_Indirect
|
||||||
void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes, const std::vector<GLuint> &Prefilled_tex)
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
|
void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, const std::vector<GLuint> &Prefilled_tex, std::vector<GLMesh *> &meshes, Args...args)
|
||||||
{
|
{
|
||||||
glUseProgram(Shader::getInstance()->Program);
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
for (unsigned i = 0; i < meshes->size(); i++)
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||||
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
{
|
{
|
||||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
|
GLMesh *mesh = meshes[i];
|
||||||
if (!irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(mesh.vao);
|
|
||||||
|
|
||||||
std::vector<GLuint> Textures(Prefilled_tex);
|
std::vector<GLuint> Textures(Prefilled_tex);
|
||||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id]));
|
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j].m_id]));
|
||||||
Shader::getInstance()->SetTextureUnits(Textures);
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
|
Shader::getInstance()->setUniforms(args...);
|
||||||
|
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Multi_Draw_Indirect
|
#ifdef Multi_Draw_Indirect
|
||||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
@ -463,7 +353,6 @@ void multidraw2ndPass(const std::vector<uint64_t> &Handles, Args... args)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void IrrDriver::renderSolidSecondPass()
|
void IrrDriver::renderSolidSecondPass()
|
||||||
{
|
{
|
||||||
SColor clearColor(0, 150, 150, 150);
|
SColor clearColor(0, 150, 150, 150);
|
||||||
@ -513,41 +402,43 @@ void IrrDriver::renderSolidSecondPass()
|
|||||||
{
|
{
|
||||||
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2));
|
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2));
|
||||||
|
|
||||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
irr_driver->setPhase(SOLID_LIT_PASS);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < ImmediateDrawList::getInstance()->size(); i++)
|
||||||
|
ImmediateDrawList::getInstance()->at(i)->render();
|
||||||
|
|
||||||
std::vector<GLuint> DiffSpecSSAOTex = createVector<GLuint>(m_rtts->getRenderTarget(RTT_DIFFUSE), m_rtts->getRenderTarget(RTT_SPECULAR), m_rtts->getRenderTarget(RTT_HALF1_R));
|
std::vector<GLuint> DiffSpecSSAOTex = createVector<GLuint>(m_rtts->getRenderTarget(RTT_DIFFUSE), m_rtts->getRenderTarget(RTT_SPECULAR), m_rtts->getRenderTarget(RTT_HALF1_R));
|
||||||
|
|
||||||
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||||
TexUnit(0, true)
|
TexUnit(0, true)
|
||||||
), ListMatDefault::getInstance(),
|
), ListMatDefault::getInstance()->SolidPass,
|
||||||
createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD, 3, 1 >(TexUnits(
|
renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD, 3, 1 >(TexUnits(
|
||||||
TexUnit(0, true)
|
TexUnit(0, true)
|
||||||
), ListMatAlphaRef::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
), ListMatAlphaRef::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD, 2, 1>(TexUnits(
|
|
||||||
TexUnit(0, true)
|
|
||||||
), ListMatSphereMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
|
||||||
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS, 1>(TexUnits(
|
|
||||||
TexUnit(0, true),
|
|
||||||
TexUnit(1, true)
|
|
||||||
), ListMatDetails::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
|
||||||
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
|
||||||
TexUnit(0, true)
|
|
||||||
), ListMatGrass::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
|
||||||
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||||
TexUnit(0, true)
|
TexUnit(0, true)
|
||||||
), ListMatUnlit::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
), ListMatUnlit::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
|
|
||||||
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS, 1>(TexUnits(
|
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS, 1>(TexUnits(
|
||||||
TexUnit(1, false),
|
TexUnit(1, false),
|
||||||
TexUnit(2, true),
|
TexUnit(2, true),
|
||||||
TexUnit(3, true),
|
TexUnit(3, true),
|
||||||
TexUnit(4, true),
|
TexUnit(4, true),
|
||||||
TexUnit(5, true)
|
TexUnit(5, true)
|
||||||
), ListMatSplatting::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
), ListMatSplatting::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
|
renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD, 2, 1>(TexUnits(
|
||||||
|
TexUnit(0, true)
|
||||||
|
), ListMatSphereMap::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
|
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS, 1>(TexUnits(
|
||||||
|
TexUnit(0, true),
|
||||||
|
TexUnit(1, true)
|
||||||
|
), ListMatDetails::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
|
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||||
|
TexUnit(0, true)
|
||||||
|
), ListMatGrass::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS, 3, 1>(TexUnits(
|
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS, 3, 1>(TexUnits(
|
||||||
TexUnit(0, true)
|
TexUnit(0, true)
|
||||||
), ListMatNormalMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
), ListMatNormalMap::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||||
|
|
||||||
if (UserConfigParams::m_azdo)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
@ -555,38 +446,44 @@ void IrrDriver::renderSolidSecondPass()
|
|||||||
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||||
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||||
multidraw2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
multidraw2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||||
core::vector3df dir = ListInstancedMatGrass::getInstance()->empty() ? core::vector3df(0., 0., 0.) : STK::tuple_get<2>(ListInstancedMatGrass::getInstance()->at(0));
|
multidraw2ndPass<MeshShader::InstancedSphereMapShader, MAT_SPHEREMAP, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||||
|
multidraw2ndPass<MeshShader::InstancedDetailledObjectPass2Shader, MAT_DETAIL, video::EVT_2TCOORDS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0));
|
||||||
|
multidraw2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||||
multidraw2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), dir, cb->getPosition());
|
multidraw2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), windDir, cb->getPosition());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
#ifdef Draw_Indirect
|
||||||
|
else if (irr_driver->hasARB_draw_indirect())
|
||||||
{
|
{
|
||||||
if (irr_driver->hasARB_base_instance())
|
// Default
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(
|
||||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>(
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatDefault::getInstance()->SolidPass);
|
||||||
TexUnits(TexUnit(0, true)),
|
// Alpha ref
|
||||||
ListInstancedMatDefault::getInstance(), DiffSpecSSAOTex);
|
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(
|
||||||
if (irr_driver->hasARB_base_instance())
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatAlphaRef::getInstance()->SolidPass);
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
|
// Unlit
|
||||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>(
|
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(
|
||||||
TexUnits(TexUnit(0, true)),
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatUnlit::getInstance()->SolidPass);
|
||||||
ListInstancedMatNormalMap::getInstance(), DiffSpecSSAOTex);
|
// Spheremap
|
||||||
if (irr_driver->hasARB_base_instance())
|
renderInstancedMeshes2ndPass<MeshShader::InstancedSphereMapShader, MAT_SPHEREMAP, video::EVT_STANDARD>(
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatSphereMap::getInstance()->SolidPass);
|
||||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader>(
|
// Details
|
||||||
TexUnits(TexUnit(0, true)),
|
renderInstancedMeshes2ndPass<MeshShader::InstancedDetailledObjectPass2Shader, MAT_DETAIL, video::EVT_2TCOORDS>(
|
||||||
ListInstancedMatAlphaRef::getInstance(), DiffSpecSSAOTex);
|
TexUnits(TexUnit(0, true), TexUnit(1, false)), DiffSpecSSAOTex, ListInstancedMatDetails::getInstance()->SolidPass);
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
|
||||||
DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture());
|
|
||||||
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, 3, 2>(
|
|
||||||
TexUnits(TexUnit(0, true)),
|
|
||||||
ListInstancedMatGrass::getInstance(), DiffSpecSSAOTex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Normal map
|
||||||
|
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
|
||||||
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatNormalMap::getInstance()->SolidPass);
|
||||||
|
|
||||||
|
// Grass
|
||||||
|
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||||
|
DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture());
|
||||||
|
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(
|
||||||
|
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatGrass::getInstance()->SolidPass, windDir, cb->getPosition());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<enum E_VERTEX_TYPE VertexType, typename... TupleType>
|
template<enum E_VERTEX_TYPE VertexType, typename... TupleType>
|
||||||
@ -611,15 +508,14 @@ static void renderMeshNormals(std::vector<STK::Tuple<TupleType...> > *meshes)
|
|||||||
|
|
||||||
void IrrDriver::renderNormalsVisualisation()
|
void IrrDriver::renderNormalsVisualisation()
|
||||||
{
|
{
|
||||||
renderMeshNormals<video::EVT_STANDARD>(ListMatDefault::getInstance());
|
// renderMeshNormals<video::EVT_STANDARD>(ListMatDefault::getInstance());
|
||||||
renderMeshNormals<video::EVT_STANDARD>(ListMatAlphaRef::getInstance());
|
// renderMeshNormals<video::EVT_STANDARD>(ListMatAlphaRef::getInstance());
|
||||||
renderMeshNormals<video::EVT_STANDARD>(ListMatSphereMap::getInstance());
|
// renderMeshNormals<video::EVT_STANDARD>(ListMatSphereMap::getInstance());
|
||||||
// renderMeshNormals<video::EVT_STANDARD>(ListMatGrass::getInstance());
|
// renderMeshNormals<video::EVT_STANDARD>(ListMatGrass::getInstance());
|
||||||
renderMeshNormals<video::EVT_2TCOORDS>(ListMatDetails::getInstance());
|
// renderMeshNormals<video::EVT_2TCOORDS>(ListMatDetails::getInstance());
|
||||||
renderMeshNormals<video::EVT_STANDARD>(ListMatUnlit::getInstance());
|
// renderMeshNormals<video::EVT_STANDARD>(ListMatUnlit::getInstance());
|
||||||
renderMeshNormals<video::EVT_2TCOORDS>(ListMatSplatting::getInstance());
|
// renderMeshNormals<video::EVT_2TCOORDS>(ListMatSplatting::getInstance());
|
||||||
renderMeshNormals<video::EVT_TANGENTS>(ListMatNormalMap::getInstance());
|
// renderMeshNormals<video::EVT_TANGENTS>(ListMatNormalMap::getInstance());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
|
template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
|
||||||
@ -674,19 +570,17 @@ static video::ITexture *displaceTex = 0;
|
|||||||
|
|
||||||
void IrrDriver::renderTransparent()
|
void IrrDriver::renderTransparent()
|
||||||
{
|
{
|
||||||
irr_driver->setPhase(TRANSPARENT_PASS);
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
ListBlendTransparent::getInstance()->clear();
|
|
||||||
ListAdditiveTransparent::getInstance()->clear();
|
irr_driver->setPhase(TRANSPARENT_PASS);
|
||||||
ListBlendTransparentFog::getInstance()->clear();
|
|
||||||
ListAdditiveTransparentFog::getInstance()->clear();
|
for (unsigned i = 0; i < ImmediateDrawList::getInstance()->size(); i++)
|
||||||
ListDisplacement::getInstance()->clear();
|
ImmediateDrawList::getInstance()->at(i)->render();
|
||||||
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT);
|
|
||||||
|
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
|
||||||
@ -831,16 +725,16 @@ struct shadow_custom_unroll_args<N, List...>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args>
|
template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args>
|
||||||
void renderShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, const std::vector<STK::Tuple<Args...> > *t)
|
void renderShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, const std::vector<STK::Tuple<Args...> > &t)
|
||||||
{
|
{
|
||||||
glUseProgram(T::getInstance()->Program);
|
glUseProgram(T::getInstance()->Program);
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||||
for (unsigned i = 0; i < t->size(); i++)
|
for (unsigned i = 0; i < t.size(); i++)
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> Handles;
|
std::vector<uint64_t> Handles;
|
||||||
std::vector<GLuint> Textures;
|
std::vector<GLuint> Textures;
|
||||||
GLMesh *mesh = STK::tuple_get<0>(t->at(i));
|
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||||
if (!irr_driver->hasARB_base_instance())
|
if (!irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(mesh->vao);
|
glBindVertexArray(mesh->vao);
|
||||||
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
||||||
@ -855,73 +749,39 @@ void renderShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, cons
|
|||||||
T::getInstance()->SetTextureHandles(Handles);
|
T::getInstance()->SetTextureHandles(Handles);
|
||||||
else
|
else
|
||||||
T::getInstance()->SetTextureUnits(Textures);
|
T::getInstance()->SetTextureUnits(Textures);
|
||||||
shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), cascade, t->at(i));
|
shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), cascade, t.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int...List>
|
#ifdef Draw_Indirect
|
||||||
struct instanced_shadow_custom_unroll_args;
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
|
void renderInstancedShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, const std::vector<GLMesh *> &t, Args ...args)
|
||||||
template<>
|
|
||||||
struct instanced_shadow_custom_unroll_args<>
|
|
||||||
{
|
{
|
||||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
static void exec(const T *Shader, unsigned cascade, const STK::Tuple<TupleTypes...> &t, Args... args)
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeShadow));
|
||||||
{
|
for (unsigned i = 0; i < t.size(); i++)
|
||||||
const GLMesh *mesh = STK::tuple_get<0>(t);
|
|
||||||
size_t instance_count = STK::tuple_get<1>(t);
|
|
||||||
irr_driver->IncreaseObjectCount();
|
|
||||||
GLenum ptype = mesh->PrimitiveType;
|
|
||||||
GLenum itype = mesh->IndexType;
|
|
||||||
size_t count = mesh->IndexCount;
|
|
||||||
|
|
||||||
Shader->setUniforms(cascade, args...);
|
|
||||||
#ifdef Base_Instance_Support
|
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glDrawElementsInstancedBaseVertexBaseInstance(ptype, count, itype, (const void*) mesh->vaoOffset, instance_count, mesh->vaoBaseVertex, mesh->vaoBaseInstance);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int N, int...List>
|
|
||||||
struct instanced_shadow_custom_unroll_args<N, List...>
|
|
||||||
{
|
|
||||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
|
||||||
static void exec(const T *Shader, unsigned cascade, const STK::Tuple<TupleTypes...> &t, Args... args)
|
|
||||||
{
|
|
||||||
instanced_shadow_custom_unroll_args<List...>::template exec<T>(Shader, cascade, t, STK::tuple_get<N>(t), args...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, int...List, typename... Args>
|
|
||||||
void renderInstancedShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, const std::vector<STK::Tuple<Args...> > *t)
|
|
||||||
{
|
|
||||||
glUseProgram(T::getInstance()->Program);
|
|
||||||
for (unsigned i = 0; i < t->size(); i++)
|
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> Handles;
|
std::vector<uint64_t> Handles;
|
||||||
std::vector<GLuint> Textures;
|
std::vector<GLuint> Textures;
|
||||||
GLMesh *mesh = STK::tuple_get<0>(t->at(i));
|
GLMesh *mesh = t[i];
|
||||||
if (!irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(mesh->vao);
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
||||||
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
|
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
|
||||||
|
|
||||||
T::getInstance()->SetTextureUnits(Textures);
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
instanced_shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), cascade, t->at(i));
|
Shader::getInstance()->setUniforms(cascade, args...);
|
||||||
|
size_t tmp = ShadowPassCmd::getInstance()->Offset[cascade][Mat] + i;
|
||||||
|
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((tmp) * sizeof(DrawElementsIndirectCommand)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Multi_Draw_Indirect
|
#ifdef Multi_Draw_Indirect
|
||||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
static void multidrawShadow(unsigned i, Args ...args)
|
static void multidrawShadow(unsigned i, Args ...args)
|
||||||
{
|
{
|
||||||
glUseProgram(Shader::getInstance()->Program);
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(VT, InstanceTypeDefault));
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeShadow));
|
||||||
if (ShadowPassCmd::getInstance()->Size[i][Mat])
|
if (ShadowPassCmd::getInstance()->Size[i][Mat])
|
||||||
{
|
{
|
||||||
Shader::getInstance()->setUniforms(i, args...);
|
Shader::getInstance()->setUniforms(i, args...);
|
||||||
@ -943,117 +803,46 @@ void IrrDriver::renderShadows()
|
|||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
glDrawBuffer(GL_NONE);
|
glDrawBuffer(GL_NONE);
|
||||||
|
|
||||||
irr_driver->setPhase(SHADOW_PASS);
|
|
||||||
ListMatDefault::getInstance()->clear();
|
|
||||||
ListMatAlphaRef::getInstance()->clear();
|
|
||||||
ListMatSphereMap::getInstance()->clear();
|
|
||||||
ListMatDetails::getInstance()->clear();
|
|
||||||
ListMatUnlit::getInstance()->clear();
|
|
||||||
ListMatNormalMap::getInstance()->clear();
|
|
||||||
ListMatGrass::getInstance()->clear();
|
|
||||||
ListMatSplatting::getInstance()->clear();
|
|
||||||
ListInstancedMatDefault::getInstance()->clear();
|
|
||||||
ListInstancedMatAlphaRef::getInstance()->clear();
|
|
||||||
ListInstancedMatGrass::getInstance()->clear();
|
|
||||||
ListInstancedMatNormalMap::getInstance()->clear();
|
|
||||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
for (unsigned cascade = 0; cascade < 4; cascade++)
|
for (unsigned cascade = 0; cascade < 4; cascade++)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<GLuint> noTexUnits;
|
std::vector<GLuint> noTexUnits;
|
||||||
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, cascade, ListMatDefault::getInstance());
|
|
||||||
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, cascade, ListMatSphereMap::getInstance());
|
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, cascade, ListMatDefault::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, cascade, ListMatDetails::getInstance());
|
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, cascade, ListMatSphereMap::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, cascade, ListMatSplatting::getInstance());
|
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, cascade, ListMatDetails::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::ShadowShader, EVT_TANGENTS, 1>(noTexUnits, cascade, ListMatNormalMap::getInstance());
|
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, cascade, ListMatSplatting::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatAlphaRef::getInstance());
|
renderShadow<MeshShader::ShadowShader, EVT_TANGENTS, 1>(noTexUnits, cascade, ListMatNormalMap::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatUnlit::getInstance());
|
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatAlphaRef::getInstance()->Shadows[cascade]);
|
||||||
renderShadow<MeshShader::GrassShadowShader, EVT_STANDARD, 3, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatGrass::getInstance());
|
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatUnlit::getInstance()->Shadows[cascade]);
|
||||||
|
renderShadow<MeshShader::GrassShadowShader, EVT_STANDARD, 3, 1>(std::vector<GLuint>{ 0 }, cascade, ListMatGrass::getInstance()->Shadows[cascade]);
|
||||||
|
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
|
||||||
if (UserConfigParams::m_azdo)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
|
|
||||||
DrawElementsIndirectCommand *ShadowCommandBufferPtr = ShadowPassCmd::getInstance()->Ptr;
|
|
||||||
|
|
||||||
ShadowPassCmd::getInstance()->Offset[cascade][MAT_DEFAULT] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatDefault::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatDefault::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatDefault::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = ShadowCommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
ShadowPassCmd::getInstance()->Size[cascade][MAT_DEFAULT] = offset - ShadowPassCmd::getInstance()->Offset[cascade][MAT_DEFAULT];
|
|
||||||
|
|
||||||
ShadowPassCmd::getInstance()->Offset[cascade][MAT_NORMAL_MAP] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatNormalMap::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatNormalMap::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatNormalMap::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = ShadowCommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
ShadowPassCmd::getInstance()->Size[cascade][MAT_NORMAL_MAP] = offset - ShadowPassCmd::getInstance()->Offset[cascade][MAT_NORMAL_MAP];
|
|
||||||
|
|
||||||
ShadowPassCmd::getInstance()->Offset[cascade][MAT_ALPHA_REF] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatAlphaRef::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatAlphaRef::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatAlphaRef::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = ShadowCommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
ShadowPassCmd::getInstance()->Size[cascade][MAT_ALPHA_REF] = offset - ShadowPassCmd::getInstance()->Offset[cascade][MAT_ALPHA_REF];
|
|
||||||
|
|
||||||
ShadowPassCmd::getInstance()->Offset[cascade][MAT_GRASS] = offset;
|
|
||||||
for (unsigned i = 0; i < ListInstancedMatGrass::getInstance()->size(); i++)
|
|
||||||
{
|
|
||||||
const GLMesh &mesh = *(STK::tuple_get<0>(ListInstancedMatGrass::getInstance()->at(i)));
|
|
||||||
size_t &instanceCount = STK::tuple_get<1>(ListInstancedMatGrass::getInstance()->at(i));
|
|
||||||
DrawElementsIndirectCommand &CurrentCommand = ShadowCommandBufferPtr[offset++];
|
|
||||||
CurrentCommand.instanceCount = instanceCount;
|
|
||||||
CurrentCommand.baseVertex = mesh.vaoBaseVertex;
|
|
||||||
CurrentCommand.count = mesh.IndexCount;
|
|
||||||
CurrentCommand.firstIndex = mesh.vaoOffset / 2;
|
|
||||||
CurrentCommand.baseInstance = mesh.vaoBaseInstance;
|
|
||||||
}
|
|
||||||
ShadowPassCmd::getInstance()->Size[cascade][MAT_GRASS] = offset - ShadowPassCmd::getInstance()->Offset[cascade][MAT_GRASS];
|
|
||||||
#ifdef Multi_Draw_Indirect
|
#ifdef Multi_Draw_Indirect
|
||||||
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(cascade);
|
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(cascade);
|
||||||
|
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DETAIL, video::EVT_2TCOORDS>(cascade);
|
||||||
multidrawShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(cascade);
|
multidrawShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(cascade);
|
||||||
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_ALPHA_REF, video::EVT_STANDARD>(cascade);
|
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_ALPHA_REF, video::EVT_STANDARD>(cascade);
|
||||||
core::vector3df dir = ListInstancedMatGrass::getInstance()->empty() ? core::vector3df(0., 0., 0.) : STK::tuple_get<2>(ListInstancedMatGrass::getInstance()->at(0));
|
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_UNLIT, video::EVT_STANDARD>(cascade);
|
||||||
multidrawShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(cascade, dir);
|
multidrawShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(cascade, windDir);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
#ifdef Draw_Indirect
|
||||||
|
else if (irr_driver->hasARB_draw_indirect())
|
||||||
{
|
{
|
||||||
if (irr_driver->hasARB_base_instance())
|
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(noTexUnits, cascade, ListInstancedMatDefault::getInstance()->Shadows[cascade]);
|
||||||
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_DETAIL, video::EVT_2TCOORDS>(noTexUnits, cascade, ListInstancedMatDetails::getInstance()->Shadows[cascade]);
|
||||||
renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, cascade, ListInstancedMatDefault::getInstance());
|
renderInstancedShadow<MeshShader::InstancedRefShadowShader, MAT_ALPHA_REF, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, cascade, ListInstancedMatAlphaRef::getInstance()->Shadows[cascade]);
|
||||||
if (irr_driver->hasARB_base_instance())
|
renderInstancedShadow<MeshShader::InstancedRefShadowShader, MAT_UNLIT, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, cascade, ListInstancedMatUnlit::getInstance()->Shadows[cascade]);
|
||||||
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
renderInstancedShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, cascade, ListInstancedMatGrass::getInstance()->Shadows[cascade], windDir);
|
||||||
renderInstancedShadow<MeshShader::InstancedRefShadowShader>(std::vector<GLuint>{ 0 }, cascade, ListInstancedMatAlphaRef::getInstance());
|
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(noTexUnits, cascade, ListInstancedMatNormalMap::getInstance()->Shadows[cascade]);
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
|
|
||||||
renderInstancedShadow<MeshShader::InstancedGrassShadowShader, 2>(std::vector<GLuint>{ 0 }, cascade, ListInstancedMatGrass::getInstance());
|
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
|
|
||||||
renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, cascade, ListInstancedMatNormalMap::getInstance());
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
@ -1085,33 +874,93 @@ struct rsm_custom_unroll_args<N, List...>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, enum E_VERTEX_TYPE VertexType, int... Selector, typename... Args>
|
template<typename T, enum E_VERTEX_TYPE VertexType, int... Selector, typename... Args>
|
||||||
void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> &TextureUnits, std::vector<STK::Tuple<Args...> > *t)
|
void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> &TextureUnits, const std::vector<STK::Tuple<Args...> > &t)
|
||||||
{
|
{
|
||||||
glUseProgram(T::getInstance()->Program);
|
glUseProgram(T::getInstance()->Program);
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||||
for (unsigned i = 0; i < t->size(); i++)
|
for (unsigned i = 0; i < t.size(); i++)
|
||||||
{
|
{
|
||||||
std::vector<GLuint> Textures;
|
std::vector<GLuint> Textures;
|
||||||
GLMesh *mesh = STK::tuple_get<0>(t->at(i));
|
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||||
if (!irr_driver->hasARB_base_instance())
|
if (!irr_driver->hasARB_base_instance())
|
||||||
glBindVertexArray(mesh->vao);
|
glBindVertexArray(mesh->vao);
|
||||||
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
||||||
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
|
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
|
||||||
T::getInstance()->SetTextureUnits(Textures);
|
T::getInstance()->SetTextureUnits(Textures);
|
||||||
rsm_custom_unroll_args<Selector...>::template exec<T>(rsm_matrix, t->at(i));
|
rsm_custom_unroll_args<Selector...>::template exec<T>(rsm_matrix, t.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Draw_Indirect
|
||||||
|
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||||
|
void renderRSMShadow(const std::vector<GLuint> TextureUnits, const std::vector<GLMesh *> &t, Args ...args)
|
||||||
|
{
|
||||||
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeRSM));
|
||||||
|
for (unsigned i = 0; i < t.size(); i++)
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> Handles;
|
||||||
|
std::vector<GLuint> Textures;
|
||||||
|
GLMesh *mesh = t[i];
|
||||||
|
|
||||||
|
for (unsigned j = 0; j < TextureUnits.size(); j++)
|
||||||
|
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
|
||||||
|
|
||||||
|
Shader::getInstance()->SetTextureUnits(Textures);
|
||||||
|
Shader::getInstance()->setUniforms(args...);
|
||||||
|
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((RSMPassCmd::getInstance()->Offset[Mat] + i)* sizeof(DrawElementsIndirectCommand)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Multi_Draw_Indirect
|
||||||
|
template<typename Shader, MeshMaterial Mat, enum E_VERTEX_TYPE VertexType, typename... Args>
|
||||||
|
void multidrawRSM(Args...args)
|
||||||
|
{
|
||||||
|
glUseProgram(Shader::getInstance()->Program);
|
||||||
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VertexType, InstanceTypeRSM));
|
||||||
|
if (RSMPassCmd::getInstance()->Size[Mat])
|
||||||
|
{
|
||||||
|
Shader::getInstance()->setUniforms(args...);
|
||||||
|
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(RSMPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)), RSMPassCmd::getInstance()->Size[Mat], sizeof(DrawElementsIndirectCommand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void IrrDriver::renderRSM()
|
void IrrDriver::renderRSM()
|
||||||
{
|
{
|
||||||
m_rtts->getRSM().Bind();
|
m_rtts->getRSM().Bind();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatDefault::getInstance());
|
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatDefault::getInstance()->RSM);
|
||||||
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatAlphaRef::getInstance());
|
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatAlphaRef::getInstance()->RSM);
|
||||||
drawRSM<MeshShader::RSMShader, EVT_TANGENTS, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatNormalMap::getInstance());
|
drawRSM<MeshShader::RSMShader, EVT_TANGENTS, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatNormalMap::getInstance()->RSM);
|
||||||
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatUnlit::getInstance());
|
drawRSM<MeshShader::RSMShader, EVT_STANDARD, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatUnlit::getInstance()->RSM);
|
||||||
drawRSM<MeshShader::RSMShader, EVT_2TCOORDS, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatDetails::getInstance());
|
drawRSM<MeshShader::RSMShader, EVT_2TCOORDS, 3, 1>(rsm_matrix, std::vector<GLuint>{ 0 }, ListMatDetails::getInstance()->RSM);
|
||||||
drawRSM<MeshShader::SplattingRSMShader, EVT_2TCOORDS, 1>(rsm_matrix, createVector<GLuint>(1, 2, 3, 4, 5), ListMatSplatting::getInstance());
|
drawRSM<MeshShader::SplattingRSMShader, EVT_2TCOORDS, 1>(rsm_matrix, createVector<GLuint>(1, 2, 3, 4, 5), ListMatSplatting::getInstance()->RSM);
|
||||||
|
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
{
|
||||||
|
#ifdef Multi_Draw_Indirect
|
||||||
|
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DEFAULT, video::EVT_STANDARD>(rsm_matrix);
|
||||||
|
multidrawRSM<MeshShader::InstancedRSMShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(rsm_matrix);
|
||||||
|
multidrawRSM<MeshShader::InstancedRSMShader, MAT_ALPHA_REF, video::EVT_STANDARD>(rsm_matrix);
|
||||||
|
multidrawRSM<MeshShader::InstancedRSMShader, MAT_UNLIT, video::EVT_STANDARD>(rsm_matrix);
|
||||||
|
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(rsm_matrix);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef Draw_Indirect
|
||||||
|
else if (irr_driver->hasARB_draw_indirect())
|
||||||
|
{
|
||||||
|
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_DEFAULT, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, ListInstancedMatDefault::getInstance()->RSM, rsm_matrix);
|
||||||
|
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_ALPHA_REF, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, ListInstancedMatAlphaRef::getInstance()->RSM, rsm_matrix);
|
||||||
|
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_UNLIT, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, ListInstancedMatUnlit::getInstance()->RSM, rsm_matrix);
|
||||||
|
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(std::vector<GLuint>(), ListInstancedMatNormalMap::getInstance()->RSM, rsm_matrix);
|
||||||
|
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(std::vector < GLuint > { 0 }, ListInstancedMatDetails::getInstance()->RSM, rsm_matrix);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1137,6 +1137,18 @@ namespace MeshShader
|
|||||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstancedColorizeShader::InstancedColorizeShader()
|
||||||
|
{
|
||||||
|
Program = LoadProgram(
|
||||||
|
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||||
|
GL_VERTEX_SHADER, file_manager->getAsset("shaders/glow_object.vert").c_str(),
|
||||||
|
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/glow_object.frag").c_str());
|
||||||
|
AssignUniforms();
|
||||||
|
|
||||||
|
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||||
|
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ShadowShader::ShadowShader()
|
ShadowShader::ShadowShader()
|
||||||
{
|
{
|
||||||
// Geometry shader needed
|
// Geometry shader needed
|
||||||
@ -1173,6 +1185,20 @@ namespace MeshShader
|
|||||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstancedRSMShader::InstancedRSMShader()
|
||||||
|
{
|
||||||
|
Program = LoadProgram(
|
||||||
|
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||||
|
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_rsm.vert").c_str(),
|
||||||
|
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_rsm.frag").c_str());
|
||||||
|
|
||||||
|
AssignUniforms("RSMMatrix");
|
||||||
|
AssignSamplerNames(Program, 0, "tex");
|
||||||
|
|
||||||
|
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||||
|
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SplattingRSMShader::SplattingRSMShader()
|
SplattingRSMShader::SplattingRSMShader()
|
||||||
{
|
{
|
||||||
Program = LoadProgram(
|
Program = LoadProgram(
|
||||||
|
@ -615,6 +615,12 @@ public:
|
|||||||
ColorizeShader();
|
ColorizeShader();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstancedColorizeShader : public ShaderHelperSingleton<InstancedColorizeShader>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InstancedColorizeShader();
|
||||||
|
};
|
||||||
|
|
||||||
class ShadowShader : public ShaderHelperSingleton<ShadowShader, int, core::matrix4>, public TextureRead<>
|
class ShadowShader : public ShaderHelperSingleton<ShadowShader, int, core::matrix4>, public TextureRead<>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -627,6 +633,12 @@ public:
|
|||||||
RSMShader();
|
RSMShader();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstancedRSMShader : public ShaderHelperSingleton<InstancedRSMShader, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InstancedRSMShader();
|
||||||
|
};
|
||||||
|
|
||||||
class SplattingRSMShader : public ShaderHelperSingleton<SplattingRSMShader, core::matrix4, core::matrix4>,
|
class SplattingRSMShader : public ShaderHelperSingleton<SplattingRSMShader, core::matrix4, core::matrix4>,
|
||||||
public TextureRead<Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
|
public TextureRead<Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ void STKAnimatedMesh::render()
|
|||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||||
{
|
{
|
||||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||||
core::matrix4 invmodel;
|
core::matrix4 invmodel;
|
||||||
@ -185,7 +185,7 @@ void STKAnimatedMesh::render()
|
|||||||
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||||
{
|
{
|
||||||
|
@ -11,8 +11,6 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMes
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool firstTime;
|
bool firstTime;
|
||||||
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
|
||||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
|
||||||
std::vector<GLMesh> GLmeshes;
|
std::vector<GLMesh> GLmeshes;
|
||||||
core::matrix4 ModelViewProjectionMatrix;
|
core::matrix4 ModelViewProjectionMatrix;
|
||||||
void cleanGLMeshes();
|
void cleanGLMeshes();
|
||||||
@ -26,6 +24,7 @@ public:
|
|||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
|
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
|
||||||
|
virtual bool glow() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STKANIMATEDMESH_HPP
|
#endif // STKANIMATEDMESH_HPP
|
||||||
|
@ -108,8 +108,6 @@ void STKInstancedSceneNode::setFirstTimeMaterial()
|
|||||||
GLMesh &mesh = GLmeshes[i];
|
GLMesh &mesh = GLmeshes[i];
|
||||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||||
initinstancedvaostate(mesh, instanceData[i]);
|
initinstancedvaostate(mesh, instanceData[i]);
|
||||||
if (irr_driver->hasARB_base_instance())
|
|
||||||
mesh.vaoBaseInstance = VAOManager::getInstance()->appendInstance(InstanceTypeDefault, instanceData[i]);
|
|
||||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||||
InitTextures(mesh, MatType);
|
InitTextures(mesh, MatType);
|
||||||
}
|
}
|
||||||
@ -191,7 +189,7 @@ void STKInstancedSceneNode::render()
|
|||||||
|
|
||||||
setFirstTimeMaterial();
|
setFirstTimeMaterial();
|
||||||
|
|
||||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
|
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
|
||||||
{
|
{
|
||||||
@ -218,5 +216,5 @@ void STKInstancedSceneNode::render()
|
|||||||
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
|
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
|
||||||
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
|
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,6 @@
|
|||||||
#include "stkmesh.hpp"
|
#include "stkmesh.hpp"
|
||||||
#include "utils/leak_check.hpp"
|
#include "utils/leak_check.hpp"
|
||||||
|
|
||||||
class ListInstancedMatDefault : public MeshList<ListInstancedMatDefault, GLMesh *, size_t>
|
|
||||||
{};
|
|
||||||
|
|
||||||
class ListInstancedMatAlphaRef : public MeshList<ListInstancedMatAlphaRef, GLMesh *, size_t>
|
|
||||||
{};
|
|
||||||
|
|
||||||
class ListInstancedMatGrass : public MeshList<ListInstancedMatGrass, GLMesh *, size_t, core::vector3df, core::vector3df>
|
|
||||||
{};
|
|
||||||
|
|
||||||
class ListInstancedMatNormalMap : public MeshList<ListInstancedMatNormalMap, GLMesh *, size_t>
|
|
||||||
{};
|
|
||||||
|
|
||||||
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
|
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -126,6 +126,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
|||||||
GLMesh result = {};
|
GLMesh result = {};
|
||||||
if (!mb)
|
if (!mb)
|
||||||
return result;
|
return result;
|
||||||
|
result.mb = mb;
|
||||||
|
|
||||||
result.IndexCount = mb->getIndexCount();
|
result.IndexCount = mb->getIndexCount();
|
||||||
switch (mb->getIndexType())
|
switch (mb->getIndexType())
|
||||||
@ -230,7 +231,7 @@ core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
|
|||||||
return ModelViewProjectionMatrix;
|
return ModelViewProjectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::vector3df getWind()
|
core::vector3df getWindDir()
|
||||||
{
|
{
|
||||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||||
|
@ -46,9 +46,9 @@ struct GLMesh {
|
|||||||
core::matrix4 TextureMatrix;
|
core::matrix4 TextureMatrix;
|
||||||
size_t vaoBaseVertex;
|
size_t vaoBaseVertex;
|
||||||
size_t vaoOffset;
|
size_t vaoOffset;
|
||||||
size_t vaoBaseInstance;
|
|
||||||
video::E_VERTEX_TYPE VAOType;
|
video::E_VERTEX_TYPE VAOType;
|
||||||
uint64_t TextureHandles[6];
|
uint64_t TextureHandles[6];
|
||||||
|
scene::IMeshBuffer *mb;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
||||||
@ -58,61 +58,122 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
|
|||||||
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
|
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
|
||||||
bool isObject(video::E_MATERIAL_TYPE type);
|
bool isObject(video::E_MATERIAL_TYPE type);
|
||||||
|
|
||||||
core::vector3df getWind();
|
core::vector3df getWindDir();
|
||||||
|
|
||||||
|
|
||||||
class STKMeshCommon
|
class STKMeshCommon
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
||||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
||||||
public:
|
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
virtual bool glow() const = 0;
|
||||||
virtual bool isImmediateDraw() const { return false; }
|
virtual bool isImmediateDraw() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
class MeshList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
|
class MeshList : public Singleton<T>
|
||||||
{};
|
{
|
||||||
|
public:
|
||||||
|
std::vector<STK::Tuple<Args...> > SolidPass, Shadows[4], RSM;
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
SolidPass.clear();
|
||||||
|
RSM.clear();
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
Shadows[i].clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class InstancedMeshList : public Singleton<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<GLMesh *> SolidPass, Shadows[4], RSM;
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
SolidPass.clear();
|
||||||
|
RSM.clear();
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
Shadows[i].clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Default---------------------------------------------------- //
|
||||||
class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatDefault : public InstancedMeshList<ListInstancedMatDefault>
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Alpha Ref---------------------------------------------------- //
|
||||||
class ListMatAlphaRef : public MeshList<ListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatAlphaRef : public MeshList<ListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatAlphaRef : public InstancedMeshList<ListInstancedMatAlphaRef>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Normap Map---------------------------------------------------- //
|
||||||
class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatNormalMap : public InstancedMeshList<ListInstancedMatNormalMap>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Grass---------------------------------------------------- //
|
||||||
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4, core::matrix4, core::vector3df>
|
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4, core::matrix4, core::vector3df>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatGrass : public InstancedMeshList<ListInstancedMatGrass>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Sphere Map---------------------------------------------------- //
|
||||||
class ListMatSphereMap : public MeshList<ListMatSphereMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatSphereMap : public MeshList<ListMatSphereMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatSphereMap : public InstancedMeshList<ListInstancedMatSphereMap>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Splatting---------------------------------------------------- //
|
||||||
class ListMatSplatting : public MeshList<ListMatSplatting, GLMesh *, core::matrix4, core::matrix4>
|
class ListMatSplatting : public MeshList<ListMatSplatting, GLMesh *, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Unlit---------------------------------------------------- //
|
||||||
class ListMatUnlit : public MeshList<ListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatUnlit : public MeshList<ListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
class ListInstancedMatUnlit : public InstancedMeshList<ListInstancedMatUnlit>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// -----------------------------------------Mat Details---------------------------------------------------- //
|
||||||
class ListMatDetails : public MeshList<ListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
class ListMatDetails : public MeshList<ListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
class ListBlendTransparent : public MeshList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
|
class ListInstancedMatDetails : public InstancedMeshList<ListInstancedMatDetails>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
class ListAdditiveTransparent : public MeshList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
|
// Transparent
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
class MiscList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
|
||||||
{};
|
{};
|
||||||
|
|
||||||
class ListBlendTransparentFog : public MeshList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
class ListBlendTransparent : public MiscList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
class ListAdditiveTransparentFog : public MeshList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
class ListAdditiveTransparent : public MiscList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
class ListDisplacement : public MeshList<ListDisplacement, GLMesh *, core::matrix4>
|
class ListBlendTransparentFog : public MiscList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||||
|
{};
|
||||||
|
|
||||||
|
class ListAdditiveTransparentFog : public MiscList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||||
|
{};
|
||||||
|
|
||||||
|
class ListDisplacement : public MiscList<ListDisplacement, GLMesh *, core::matrix4>
|
||||||
|
{};
|
||||||
|
|
||||||
|
class ListInstancedGlow : public Singleton<ListInstancedGlow>, public std::vector<GLMesh *>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
// Forward pass (for transparents meshes)
|
// Forward pass (for transparents meshes)
|
||||||
|
@ -21,6 +21,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
|
|||||||
isDisplacement = false;
|
isDisplacement = false;
|
||||||
immediate_draw = false;
|
immediate_draw = false;
|
||||||
update_each_frame = false;
|
update_each_frame = false;
|
||||||
|
isGlow = false;
|
||||||
|
|
||||||
if (createGLMeshes)
|
if (createGLMeshes)
|
||||||
this->createGLMeshes();
|
this->createGLMeshes();
|
||||||
@ -142,14 +143,12 @@ STKMeshSceneNode::~STKMeshSceneNode()
|
|||||||
|
|
||||||
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
|
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
|
||||||
{
|
{
|
||||||
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
|
||||||
assert(mesh.VAOType == video::EVT_STANDARD);
|
assert(mesh.VAOType == video::EVT_STANDARD);
|
||||||
|
|
||||||
GLenum ptype = mesh.PrimitiveType;
|
GLenum ptype = mesh.PrimitiveType;
|
||||||
GLenum itype = mesh.IndexType;
|
GLenum itype = mesh.IndexType;
|
||||||
size_t count = mesh.IndexCount;
|
size_t count = mesh.IndexCount;
|
||||||
|
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(glowcolor.getRed() / 255.f, glowcolor.getGreen() / 255.f, glowcolor.getBlue() / 255.f));
|
||||||
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
|
|
||||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
|
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +169,6 @@ void STKMeshSceneNode::updatevbo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static video::ITexture *spareWhiteTex = 0;
|
|
||||||
|
|
||||||
void STKMeshSceneNode::update()
|
void STKMeshSceneNode::update()
|
||||||
{
|
{
|
||||||
Box = Mesh->getBoundingBox();
|
Box = Mesh->getBoundingBox();
|
||||||
@ -196,6 +193,8 @@ void STKMeshSceneNode::OnRegisterSceneNode()
|
|||||||
CMeshSceneNode::OnRegisterSceneNode();
|
CMeshSceneNode::OnRegisterSceneNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static video::ITexture *spareWhiteTex = 0;
|
||||||
|
|
||||||
void STKMeshSceneNode::render()
|
void STKMeshSceneNode::render()
|
||||||
{
|
{
|
||||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||||
@ -207,7 +206,22 @@ void STKMeshSceneNode::render()
|
|||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS && immediate_draw)
|
bool isTransparent;
|
||||||
|
|
||||||
|
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;
|
||||||
|
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||||
|
|
||||||
|
isTransparent = rnd->isTransparent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent)
|
||||||
{
|
{
|
||||||
core::matrix4 invmodel;
|
core::matrix4 invmodel;
|
||||||
AbsoluteTransformation.getInverse(invmodel);
|
AbsoluteTransformation.getInverse(invmodel);
|
||||||
@ -225,6 +239,21 @@ void STKMeshSceneNode::render()
|
|||||||
GLenum itype = mesh.IndexType;
|
GLenum itype = mesh.IndexType;
|
||||||
size_t count = mesh.IndexCount;
|
size_t count = mesh.IndexCount;
|
||||||
|
|
||||||
|
if (!mesh.textures[0])
|
||||||
|
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||||
|
compressTexture(mesh.textures[0], true);
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
{
|
||||||
|
#ifdef Bindless_Texture_Support
|
||||||
|
if (!mesh.TextureHandles[0])
|
||||||
|
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||||
|
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||||
|
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||||
|
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
|
||||||
MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
|
MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
|
||||||
assert(mesh.vao);
|
assert(mesh.vao);
|
||||||
glBindVertexArray(mesh.vao);
|
glBindVertexArray(mesh.vao);
|
||||||
@ -235,54 +264,25 @@ void STKMeshSceneNode::render()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent)
|
||||||
{
|
{
|
||||||
core::matrix4 invmodel;
|
core::matrix4 invmodel;
|
||||||
AbsoluteTransformation.getInverse(invmodel);
|
AbsoluteTransformation.getInverse(invmodel);
|
||||||
|
|
||||||
GLMesh* mesh;
|
glDisable(GL_CULL_FACE);
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_DEFAULT])
|
if (!spareWhiteTex)
|
||||||
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||||
|
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_ALPHA_REF])
|
// Only untextured
|
||||||
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||||
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_SPHEREMAP])
|
|
||||||
pushVector(ListMatSphereMap::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
|
||||||
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_DETAIL])
|
|
||||||
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
|
||||||
|
|
||||||
windDir = getWind();
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_GRASS])
|
|
||||||
pushVector(ListMatGrass::getInstance(), mesh, AbsoluteTransformation, invmodel, windDir);
|
|
||||||
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_UNLIT])
|
|
||||||
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
|
||||||
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_SPLATTING])
|
|
||||||
pushVector(ListMatSplatting::getInstance(), mesh, AbsoluteTransformation, invmodel);
|
|
||||||
|
|
||||||
for_in(mesh, MeshSolidMaterial[MAT_NORMAL_MAP])
|
|
||||||
pushVector(ListMatNormalMap::getInstance(), mesh, AbsoluteTransformation, invmodel, core::matrix4::EM4CONST_IDENTITY);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
|
||||||
{
|
|
||||||
core::matrix4 invmodel;
|
|
||||||
AbsoluteTransformation.getInverse(invmodel);
|
|
||||||
|
|
||||||
if (immediate_draw)
|
|
||||||
{
|
{
|
||||||
return;
|
irr_driver->IncreaseObjectCount();
|
||||||
glDisable(GL_CULL_FACE);
|
GLMesh &mesh = GLmeshes[i];
|
||||||
if (!spareWhiteTex)
|
GLenum ptype = mesh.PrimitiveType;
|
||||||
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
GLenum itype = mesh.IndexType;
|
||||||
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
|
size_t count = mesh.IndexCount;
|
||||||
// Only untextured
|
|
||||||
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
irr_driver->IncreaseObjectCount();
|
irr_driver->IncreaseObjectCount();
|
||||||
GLMesh &mesh = GLmeshes[i];
|
GLMesh &mesh = GLmeshes[i];
|
||||||
@ -325,10 +325,19 @@ void STKMeshSceneNode::render()
|
|||||||
glDrawElements(ptype, count, itype, 0);
|
glDrawElements(ptype, count, itype, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
glEnable(GL_CULL_FACE);
|
else
|
||||||
return;
|
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
|
||||||
|
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
|
||||||
|
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
|
||||||
|
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
|
||||||
|
getTextureGLuint(mesh.textures[0])));
|
||||||
|
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
|
||||||
|
assert(mesh.vao);
|
||||||
|
glBindVertexArray(mesh.vao);
|
||||||
|
glDrawElements(ptype, count, itype, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +357,7 @@ void STKMeshSceneNode::render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent)
|
||||||
{
|
{
|
||||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||||
|
|
||||||
@ -383,6 +392,8 @@ void STKMeshSceneNode::render()
|
|||||||
tmpcol.getGreen() / 255.0f,
|
tmpcol.getGreen() / 255.0f,
|
||||||
tmpcol.getBlue() / 255.0f);
|
tmpcol.getBlue() / 255.0f);
|
||||||
|
|
||||||
|
if (!mesh.textures[0])
|
||||||
|
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||||
compressTexture(mesh.textures[0], true);
|
compressTexture(mesh.textures[0], true);
|
||||||
if (UserConfigParams::m_azdo)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
@ -414,7 +425,8 @@ void STKMeshSceneNode::render()
|
|||||||
GLenum ptype = mesh.PrimitiveType;
|
GLenum ptype = mesh.PrimitiveType;
|
||||||
GLenum itype = mesh.IndexType;
|
GLenum itype = mesh.IndexType;
|
||||||
size_t count = mesh.IndexCount;
|
size_t count = mesh.IndexCount;
|
||||||
|
if (!mesh.textures[0])
|
||||||
|
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||||
compressTexture(mesh.textures[0], true);
|
compressTexture(mesh.textures[0], true);
|
||||||
if (UserConfigParams::m_azdo)
|
if (UserConfigParams::m_azdo)
|
||||||
{
|
{
|
||||||
@ -440,42 +452,6 @@ void STKMeshSceneNode::render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLMesh* mesh;
|
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])
|
|
||||||
pushVector(ListBlendTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
|
|
||||||
fogmax, startH, endH, start, end, col);
|
|
||||||
for_in(mesh, TransparentMesh[TM_ADDITIVE])
|
|
||||||
pushVector(ListAdditiveTransparentFog::getInstance(), 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for_in(mesh, TransparentMesh[TM_DISPLACEMENT])
|
|
||||||
pushVector(ListDisplacement::getInstance(), mesh, AbsoluteTransformation);
|
|
||||||
|
|
||||||
if (!TransparentMesh[TM_BUBBLE].empty())
|
if (!TransparentMesh[TM_BUBBLE].empty())
|
||||||
glUseProgram(MeshShader::BubbleShader::Program);
|
glUseProgram(MeshShader::BubbleShader::Program);
|
||||||
if (irr_driver->hasARB_base_instance())
|
if (irr_driver->hasARB_base_instance())
|
||||||
|
@ -22,6 +22,8 @@ protected:
|
|||||||
bool immediate_draw;
|
bool immediate_draw;
|
||||||
bool update_each_frame;
|
bool update_each_frame;
|
||||||
bool isDisplacement;
|
bool isDisplacement;
|
||||||
|
bool isGlow;
|
||||||
|
video::SColor glowcolor;
|
||||||
public:
|
public:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
void setReloadEachFrame(bool);
|
void setReloadEachFrame(bool);
|
||||||
@ -46,6 +48,9 @@ public:
|
|||||||
mb->getMaterial().MaterialType = irr_driver->getShader(ES_DISPLACE);
|
mb->getMaterial().MaterialType = irr_driver->getShader(ES_DISPLACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual bool glow() const { return isGlow; }
|
||||||
|
void setGlowColors(const video::SColor &c) { isGlow = true; glowcolor = c; }
|
||||||
|
video::SColor getGlowColor() const { return glowcolor; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
634
src/graphics/stkscenemanager.cpp
Normal file
634
src/graphics/stkscenemanager.cpp
Normal file
@ -0,0 +1,634 @@
|
|||||||
|
#include "stkscenemanager.hpp"
|
||||||
|
#include "stkmesh.hpp"
|
||||||
|
#include "stkinstancedscenenode.hpp"
|
||||||
|
#include "irr_driver.hpp"
|
||||||
|
#include <ISceneManager.h>
|
||||||
|
#include <ISceneNode.h>
|
||||||
|
#include "stkanimatedmesh.hpp"
|
||||||
|
#include "stkmeshscenenode.hpp"
|
||||||
|
#include "utils/ptr_vector.hpp"
|
||||||
|
#include <ICameraSceneNode.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
static void
|
||||||
|
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, InstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||||
|
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, int cascade)
|
||||||
|
{
|
||||||
|
// Should never be empty
|
||||||
|
GLMesh *mesh = InstanceList.front().first;
|
||||||
|
|
||||||
|
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||||
|
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||||
|
CurrentCommand.count = mesh->IndexCount;
|
||||||
|
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||||
|
CurrentCommand.baseInstance = InstanceBufferOffset;
|
||||||
|
CurrentCommand.instanceCount = InstanceList.size();
|
||||||
|
|
||||||
|
irr_driver->IncreasePolyCount(InstanceList.size() * mesh->IndexCount / 3);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < InstanceList.size(); i++)
|
||||||
|
{
|
||||||
|
auto &Tp = InstanceList[i];
|
||||||
|
InstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||||
|
scene::ISceneNode *node = Tp.second;
|
||||||
|
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||||
|
const core::vector3df &Origin = mat.getTranslation();
|
||||||
|
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||||
|
const core::vector3df &Scale = mat.getScale();
|
||||||
|
Instance.Origin.X = Origin.X;
|
||||||
|
Instance.Origin.Y = Origin.Y;
|
||||||
|
Instance.Origin.Z = Origin.Z;
|
||||||
|
Instance.Orientation.X = Orientation.X;
|
||||||
|
Instance.Orientation.Y = Orientation.Y;
|
||||||
|
Instance.Orientation.Z = Orientation.Z;
|
||||||
|
Instance.Scale.X = Scale.X;
|
||||||
|
Instance.Scale.Y = Scale.Y;
|
||||||
|
Instance.Scale.Z = Scale.Z;
|
||||||
|
Instance.Texture = mesh->TextureHandles[0];
|
||||||
|
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
FillInstancesGlow_impl(std::vector<std::pair<GLMesh *, STKMeshCommon *> > InstanceList, GlowInstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||||
|
size_t &InstanceBufferOffset, size_t &CommandBufferOffset)
|
||||||
|
{
|
||||||
|
// Should never be empty
|
||||||
|
GLMesh *mesh = InstanceList.front().first;
|
||||||
|
|
||||||
|
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||||
|
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||||
|
CurrentCommand.count = mesh->IndexCount;
|
||||||
|
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||||
|
CurrentCommand.baseInstance = InstanceBufferOffset;
|
||||||
|
CurrentCommand.instanceCount = InstanceList.size();
|
||||||
|
|
||||||
|
irr_driver->IncreasePolyCount(InstanceList.size() * mesh->IndexCount / 3);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < InstanceList.size(); i++)
|
||||||
|
{
|
||||||
|
STKMeshSceneNode *node = dynamic_cast<STKMeshSceneNode*>(InstanceList[i].second);
|
||||||
|
GlowInstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||||
|
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||||
|
const core::vector3df &Origin = mat.getTranslation();
|
||||||
|
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||||
|
const core::vector3df &Scale = mat.getScale();
|
||||||
|
Instance.Color = node->getGlowColor().color;
|
||||||
|
Instance.Origin.X = Origin.X;
|
||||||
|
Instance.Origin.Y = Origin.Y;
|
||||||
|
Instance.Origin.Z = Origin.Z;
|
||||||
|
Instance.Orientation.X = Orientation.X;
|
||||||
|
Instance.Orientation.Y = Orientation.Y;
|
||||||
|
Instance.Orientation.Z = Orientation.Z;
|
||||||
|
Instance.Scale.X = Scale.X;
|
||||||
|
Instance.Scale.Y = Scale.Y;
|
||||||
|
Instance.Scale.Z = Scale.Z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void FillInstances(const std::map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||||
|
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, int cascade)
|
||||||
|
{
|
||||||
|
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
|
||||||
|
for (; It != E; ++It)
|
||||||
|
{
|
||||||
|
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, cascade);
|
||||||
|
if (!UserConfigParams::m_azdo)
|
||||||
|
InstancedList.push_back(It->second.front().first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void FillInstancesGrass(const std::map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||||
|
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, int cascade, const core::vector3df &dir)
|
||||||
|
{
|
||||||
|
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
|
||||||
|
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||||
|
for (; It != E; ++It)
|
||||||
|
{
|
||||||
|
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, cascade);
|
||||||
|
if (!UserConfigParams::m_azdo)
|
||||||
|
InstancedList.push_back(It->second.front().first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForSolidPass[MAT_COUNT];
|
||||||
|
static std::map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForShadowPass[4][MAT_COUNT];
|
||||||
|
static std::map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForRSMPass[MAT_COUNT];
|
||||||
|
static std::map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, STKMeshCommon *> > > MeshForGlowPass;
|
||||||
|
|
||||||
|
static core::vector3df windDir;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *ImmediateDraw, bool IsCulledForSolid, bool IsCulledForShadow[4], bool IsCulledForRSM)
|
||||||
|
{
|
||||||
|
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
node->update();
|
||||||
|
|
||||||
|
if (node->isImmediateDraw())
|
||||||
|
{
|
||||||
|
ImmediateDraw->push_back(Node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
|
||||||
|
{
|
||||||
|
GLMesh *mesh;
|
||||||
|
if (!IsCulledForSolid)
|
||||||
|
{
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
{
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
{
|
||||||
|
if (node->glow())
|
||||||
|
MeshForGlowPass[mesh->mb].push_back(std::make_pair(mesh, node));
|
||||||
|
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||||
|
ModelMatrix.getInverse(InvModelMatrix);
|
||||||
|
|
||||||
|
if (mesh->TextureMatrix.isIdentity())
|
||||||
|
MeshForSolidPass[Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (Mat)
|
||||||
|
{
|
||||||
|
case MAT_DEFAULT:
|
||||||
|
ListMatDefault::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_ALPHA_REF:
|
||||||
|
ListMatAlphaRef::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_UNLIT:
|
||||||
|
ListMatUnlit::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||||
|
ModelMatrix.getInverse(InvModelMatrix);
|
||||||
|
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
{
|
||||||
|
switch (Mat)
|
||||||
|
{
|
||||||
|
case MAT_DEFAULT:
|
||||||
|
ListMatDefault::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_ALPHA_REF:
|
||||||
|
ListMatAlphaRef::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_NORMAL_MAP:
|
||||||
|
ListMatNormalMap::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_DETAIL:
|
||||||
|
ListMatDetails::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_UNLIT:
|
||||||
|
ListMatUnlit::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPHEREMAP:
|
||||||
|
ListMatSphereMap::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPLATTING:
|
||||||
|
ListMatSplatting::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_GRASS:
|
||||||
|
ListMatGrass::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned cascade = 0; cascade < 4; ++cascade)
|
||||||
|
{
|
||||||
|
if (!IsCulledForShadow[cascade])
|
||||||
|
{
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
{
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
MeshForShadowPass[cascade][Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||||
|
ModelMatrix.getInverse(InvModelMatrix);
|
||||||
|
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
{
|
||||||
|
switch (Mat)
|
||||||
|
{
|
||||||
|
case MAT_DEFAULT:
|
||||||
|
ListMatDefault::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_ALPHA_REF:
|
||||||
|
ListMatAlphaRef::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_NORMAL_MAP:
|
||||||
|
ListMatNormalMap::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_DETAIL:
|
||||||
|
ListMatDetails::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_UNLIT:
|
||||||
|
ListMatUnlit::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPHEREMAP:
|
||||||
|
ListMatSphereMap::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPLATTING:
|
||||||
|
ListMatSplatting::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_GRASS:
|
||||||
|
ListMatGrass::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!IsCulledForRSM)
|
||||||
|
{
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
{
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
MeshForRSMPass[Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||||
|
ModelMatrix.getInverse(InvModelMatrix);
|
||||||
|
|
||||||
|
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||||
|
{
|
||||||
|
switch (Mat)
|
||||||
|
{
|
||||||
|
case MAT_DEFAULT:
|
||||||
|
ListMatDefault::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_ALPHA_REF:
|
||||||
|
ListMatAlphaRef::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_NORMAL_MAP:
|
||||||
|
ListMatNormalMap::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_DETAIL:
|
||||||
|
ListMatDetails::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_UNLIT:
|
||||||
|
ListMatUnlit::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPHEREMAP:
|
||||||
|
ListMatSphereMap::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_SPLATTING:
|
||||||
|
ListMatSplatting::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
|
||||||
|
break;
|
||||||
|
case MAT_GRASS:
|
||||||
|
ListMatGrass::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Transparent
|
||||||
|
if (!IsCulledForSolid)
|
||||||
|
{
|
||||||
|
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, node->TransparentMesh[TM_DEFAULT])
|
||||||
|
pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
|
||||||
|
fogmax, startH, endH, start, end, col);
|
||||||
|
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
|
||||||
|
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
|
||||||
|
fogmax, startH, endH, start, end, col);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
|
||||||
|
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
|
||||||
|
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
|
||||||
|
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
|
||||||
|
}
|
||||||
|
for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
|
||||||
|
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parseSceneManager(core::list<scene::ISceneNode*> List, std::vector<scene::ISceneNode *> *ImmediateDraw,
|
||||||
|
scene::ICameraSceneNode *shadowCams[4], scene::ICameraSceneNode *RSM_cam)
|
||||||
|
{
|
||||||
|
core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end();
|
||||||
|
for (; I != E; ++I)
|
||||||
|
{
|
||||||
|
if (LODNode *node = dynamic_cast<LODNode *>(*I))
|
||||||
|
node->updateVisibility();
|
||||||
|
if (!(*I)->isVisible())
|
||||||
|
continue;
|
||||||
|
(*I)->updateAbsolutePosition();
|
||||||
|
core::aabbox3d<f32> tbox = (*I)->getBoundingBox();
|
||||||
|
(*I)->getAbsoluteTransformation().transformBoxEx(tbox);
|
||||||
|
|
||||||
|
const scene::ICameraSceneNode* cam = irr_driver->getSceneManager()->getActiveCamera();
|
||||||
|
bool IsCulledForSolid = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox()));
|
||||||
|
bool IsCulledForShadow[4];
|
||||||
|
bool IsCulledForRSM = false;
|
||||||
|
for (unsigned i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
const scene::ICameraSceneNode* cam = shadowCams[i];
|
||||||
|
IsCulledForShadow[i] = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCulledForSolid && IsCulledForShadow[0] && IsCulledForShadow[1] && IsCulledForShadow[2] && IsCulledForShadow[3])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!IsCulledForSolid)
|
||||||
|
{
|
||||||
|
if (ParticleSystemProxy *node = dynamic_cast<ParticleSystemProxy *>(*I))
|
||||||
|
{
|
||||||
|
if (node->update())
|
||||||
|
ParticlesList::getInstance()->push_back(node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSTKCommon(*I, ImmediateDraw, IsCulledForSolid, IsCulledForShadow, false);
|
||||||
|
|
||||||
|
parseSceneManager((*I)->getChildren(), ImmediateDraw, shadowCams, RSM_cam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<MeshMaterial Mat> static void
|
||||||
|
GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
|
||||||
|
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset)
|
||||||
|
{
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
|
||||||
|
FillInstances(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, cascade);
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<MeshMaterial Mat> static void
|
||||||
|
GenDrawCallsGrass(unsigned cascade, std::vector<GLMesh *> &InstancedList,
|
||||||
|
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir)
|
||||||
|
{
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
|
||||||
|
FillInstancesGrass(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, cascade, dir);
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrrDriver::PrepareDrawCalls()
|
||||||
|
{
|
||||||
|
windDir = getWindDir();
|
||||||
|
ListBlendTransparent::getInstance()->clear();
|
||||||
|
ListAdditiveTransparent::getInstance()->clear();
|
||||||
|
ListBlendTransparentFog::getInstance()->clear();
|
||||||
|
ListAdditiveTransparentFog::getInstance()->clear();
|
||||||
|
ListDisplacement::getInstance()->clear();
|
||||||
|
|
||||||
|
ListMatDefault::getInstance()->clear();
|
||||||
|
ListMatAlphaRef::getInstance()->clear();
|
||||||
|
ListMatSphereMap::getInstance()->clear();
|
||||||
|
ListMatDetails::getInstance()->clear();
|
||||||
|
ListMatUnlit::getInstance()->clear();
|
||||||
|
ListMatNormalMap::getInstance()->clear();
|
||||||
|
ListMatGrass::getInstance()->clear();
|
||||||
|
ListMatSplatting::getInstance()->clear();
|
||||||
|
|
||||||
|
ImmediateDrawList::getInstance()->clear();
|
||||||
|
ParticlesList::getInstance()->clear();
|
||||||
|
ListInstancedGlow::getInstance()->clear();
|
||||||
|
|
||||||
|
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
|
||||||
|
{
|
||||||
|
MeshForSolidPass[Mat].clear();
|
||||||
|
MeshForRSMPass[Mat].clear();
|
||||||
|
for (unsigned cascade = 0; cascade < 4; ++cascade)
|
||||||
|
MeshForShadowPass[cascade][Mat].clear();
|
||||||
|
}
|
||||||
|
MeshForGlowPass.clear();
|
||||||
|
core::list<scene::ISceneNode*> List = m_scene_manager->getRootSceneNode()->getChildren();
|
||||||
|
|
||||||
|
bool isCulled[4] = {};
|
||||||
|
parseSceneManager(List, ImmediateDrawList::getInstance(), m_shadow_camnodes, m_suncam);
|
||||||
|
if (!irr_driver->hasARB_draw_indirect())
|
||||||
|
return;
|
||||||
|
InstanceData *InstanceBuffer;
|
||||||
|
InstanceData *ShadowInstanceBuffer;
|
||||||
|
InstanceData *RSMInstanceBuffer;
|
||||||
|
GlowInstanceData *GlowInstanceBuffer;
|
||||||
|
DrawElementsIndirectCommand *CmdBuffer;
|
||||||
|
DrawElementsIndirectCommand *ShadowCmdBuffer;
|
||||||
|
DrawElementsIndirectCommand *RSMCmdBuffer;
|
||||||
|
DrawElementsIndirectCommand *GlowCmdBuffer;
|
||||||
|
|
||||||
|
if (irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
InstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDefault);
|
||||||
|
ShadowInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||||
|
RSMInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
|
||||||
|
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
|
||||||
|
CmdBuffer = SolidPassCmd::getInstance()->Ptr;
|
||||||
|
ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr;
|
||||||
|
GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr;
|
||||||
|
RSMCmdBuffer = RSMPassCmd::getInstance()->Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListInstancedMatDefault::getInstance()->clear();
|
||||||
|
ListInstancedMatAlphaRef::getInstance()->clear();
|
||||||
|
ListInstancedMatGrass::getInstance()->clear();
|
||||||
|
ListInstancedMatNormalMap::getInstance()->clear();
|
||||||
|
ListInstancedMatSphereMap::getInstance()->clear();
|
||||||
|
ListInstancedMatDetails::getInstance()->clear();
|
||||||
|
ListInstancedMatUnlit::getInstance()->clear();
|
||||||
|
|
||||||
|
#pragma omp parallel sections
|
||||||
|
{
|
||||||
|
#pragma omp section
|
||||||
|
{
|
||||||
|
size_t offset = 0, current_cmd = 0;
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDefault));
|
||||||
|
InstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Material
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DEFAULT];
|
||||||
|
// Alpha Ref
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
|
||||||
|
// Unlit
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_UNLIT];
|
||||||
|
// Spheremap
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_SPHEREMAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP];
|
||||||
|
// Detail
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DETAIL];
|
||||||
|
// Normal Map
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
|
||||||
|
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
|
||||||
|
|
||||||
|
// Grass
|
||||||
|
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
|
||||||
|
FillInstancesGrass(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, -1, windDir);
|
||||||
|
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
|
||||||
|
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma omp section
|
||||||
|
{
|
||||||
|
size_t offset = 0, current_cmd = 0;
|
||||||
|
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
|
||||||
|
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glow
|
||||||
|
if (irr_driver->hasARB_draw_indirect())
|
||||||
|
GlowPassCmd::getInstance()->Offset = offset; // Store command buffer offset
|
||||||
|
|
||||||
|
auto It = MeshForGlowPass.begin(), E = MeshForGlowPass.end();
|
||||||
|
for (; It != E; ++It)
|
||||||
|
{
|
||||||
|
FillInstancesGlow_impl(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd);
|
||||||
|
if (!UserConfigParams::m_azdo)
|
||||||
|
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserConfigParams::m_azdo)
|
||||||
|
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
|
||||||
|
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma omp section
|
||||||
|
{
|
||||||
|
irr_driver->setPhase(SHADOW_PASS);
|
||||||
|
|
||||||
|
size_t offset = 0, current_cmd = 0;
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
|
||||||
|
ShadowInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
// Mat default
|
||||||
|
GenDrawCalls<MAT_DEFAULT>(i, ListInstancedMatDefault::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat AlphaRef
|
||||||
|
GenDrawCalls<MAT_ALPHA_REF>(i, ListInstancedMatAlphaRef::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat Unlit
|
||||||
|
GenDrawCalls<MAT_UNLIT>(i, ListInstancedMatUnlit::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat NormalMap
|
||||||
|
GenDrawCalls<MAT_NORMAL_MAP>(i, ListInstancedMatNormalMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat Spheremap
|
||||||
|
GenDrawCalls<MAT_SPHEREMAP>(i, ListInstancedMatSphereMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat Detail
|
||||||
|
GenDrawCalls<MAT_DETAIL>(i, ListInstancedMatDetails::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd);
|
||||||
|
// Mat Grass
|
||||||
|
GenDrawCallsGrass<MAT_GRASS>(i, ListInstancedMatGrass::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, windDir);
|
||||||
|
}
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma omp section
|
||||||
|
{
|
||||||
|
size_t offset = 0, current_cmd = 0;
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
|
||||||
|
RSMInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
|
||||||
|
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Material
|
||||||
|
RSMPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
|
||||||
|
FillInstances(MeshForRSMPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, -1);
|
||||||
|
RSMPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DEFAULT];
|
||||||
|
// Alpha Ref
|
||||||
|
RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
|
||||||
|
FillInstances(MeshForRSMPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, -1);
|
||||||
|
RSMPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
|
||||||
|
// Unlit
|
||||||
|
RSMPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
|
||||||
|
FillInstances(MeshForRSMPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, -1);
|
||||||
|
RSMPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_UNLIT];
|
||||||
|
// Detail
|
||||||
|
RSMPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
|
||||||
|
FillInstances(MeshForRSMPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, -1);
|
||||||
|
RSMPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DETAIL];
|
||||||
|
// Normal Map
|
||||||
|
RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
|
||||||
|
FillInstances(MeshForRSMPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, -1);
|
||||||
|
RSMPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
|
||||||
|
|
||||||
|
if (!irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
#include "utils/singleton.hpp"
|
#include "utils/singleton.hpp"
|
||||||
#include "gl_headers.hpp"
|
#include "gl_headers.hpp"
|
||||||
#include "stkmesh.hpp"
|
#include "stkmesh.hpp"
|
||||||
|
#include "gpuparticles.hpp"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class CommandBuffer : public Singleton<T>
|
class CommandBuffer : public Singleton<T>
|
||||||
@ -16,15 +17,28 @@ public:
|
|||||||
DrawElementsIndirectCommand *Ptr;
|
DrawElementsIndirectCommand *Ptr;
|
||||||
CommandBuffer()
|
CommandBuffer()
|
||||||
{
|
{
|
||||||
#ifdef Buffer_Storage
|
|
||||||
glGenBuffers(1, &drawindirectcmd);
|
glGenBuffers(1, &drawindirectcmd);
|
||||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
|
||||||
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
#ifdef Buffer_Storage
|
||||||
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
if (irr_driver->hasBufferStorageExtension())
|
||||||
|
{
|
||||||
|
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||||
|
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ImmediateDrawList : public Singleton<ImmediateDrawList>, public std::vector<scene::ISceneNode *>
|
||||||
|
{};
|
||||||
|
|
||||||
|
class ParticlesList : public Singleton<ParticlesList>, public std::vector<ParticleSystemProxy *>
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
class SolidPassCmd : public CommandBuffer<SolidPassCmd>
|
class SolidPassCmd : public CommandBuffer<SolidPassCmd>
|
||||||
{
|
{
|
||||||
@ -38,5 +52,17 @@ public:
|
|||||||
size_t Offset[4][MAT_COUNT], Size[4][MAT_COUNT];
|
size_t Offset[4][MAT_COUNT], Size[4][MAT_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RSMPassCmd : public CommandBuffer<RSMPassCmd>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlowPassCmd : public CommandBuffer<GlowPassCmd>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t Offset, Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
x
Reference in New Issue
Block a user