Draw Manager: Add Triangle batching and empty batch.

This is usefull for Depth Of Field because we don't need to store data for each sprites and just generate them when rendering.
This commit is contained in:
2017-05-09 21:48:46 +02:00
parent bf0ebfca1a
commit 6dc8368b8f

View File

@@ -220,6 +220,7 @@ enum {
DRW_SHG_NORMAL,
DRW_SHG_POINT_BATCH,
DRW_SHG_LINE_BATCH,
DRW_SHG_TRIANGLE_BATCH,
DRW_SHG_INSTANCE,
};
@@ -583,7 +584,7 @@ static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
BLI_addtail(&shgroup->interface->uniforms, uni);
}
static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size)
static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size, bool dummy)
{
DRWAttrib *attrib = MEM_mallocN(sizeof(DRWAttrib), "DRWAttrib");
GLuint program = GPU_shader_get_program(shgroup->shader);
@@ -592,7 +593,7 @@ static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW
attrib->type = type;
attrib->size = size;
if (attrib->location == -1) {
if (attrib->location == -1 && !dummy) {
if (G.debug & G_DEBUG)
fprintf(stderr, "Attribute '%s' not found!\n", name);
@@ -745,6 +746,20 @@ DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass
return shgroup;
}
/* Very special batch. Use this if you position
* your vertices with the vertex shader
* and dont need any VBO attrib */
DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size)
{
DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
shgroup->type = DRW_SHG_TRIANGLE_BATCH;
shgroup->interface->instance_count = size * 3;
DRW_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
return shgroup;
}
void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
{
BLI_freelistN(&shgroup->calls);
@@ -810,6 +825,16 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
BLI_addtail(&shgroup->calls, call);
}
/* Used for instancing with no attributes */
void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
{
DRWInterface *interface = shgroup->interface;
BLI_assert(interface->attribs_count == 0);
interface->instance_count = count;
}
/**
* State is added to #Pass.state while drawing.
* Use to temporarily enable draw options.
@@ -902,7 +927,8 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
DRWInterface *interface = shgroup->interface;
int nbr = interface->instance_count;
PrimitiveType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? PRIM_POINTS : PRIM_LINES;
PrimitiveType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? PRIM_POINTS :
(shgroup->type == DRW_SHG_TRIANGLE_BATCH) ? PRIM_TRIANGLES : PRIM_LINES;
if (nbr == 0)
return;
@@ -948,10 +974,10 @@ static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
int i = 0;
int offset = 0;
DRWInterface *interface = shgroup->interface;
int vert_nbr = interface->instance_count;
int instance_ct = interface->instance_count;
int buffer_size = 0;
if (vert_nbr == 0) {
if (instance_ct == 0) {
if (interface->instance_vbo) {
glDeleteBuffers(1, &interface->instance_vbo);
interface->instance_vbo = 0;
@@ -970,7 +996,7 @@ static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
}
/* Gather Data */
buffer_size = sizeof(float) * interface->attribs_stride * vert_nbr;
buffer_size = sizeof(float) * interface->attribs_stride * instance_ct;
float *data = MEM_mallocN(buffer_size, "Instance VBO data");
for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->next) {