Clay Engine: Refactoring of the dynamic batches

Support more attribs for interesting instancing
This commit is contained in:
Clément Foucault 2017-02-09 17:26:13 +01:00
parent c5f2380be7
commit fc0797142d
5 changed files with 377 additions and 269 deletions

View File

@ -158,16 +158,17 @@ typedef enum {
DRW_STATE_BLEND = (1 << 12),
} DRWState;
/* Used by DRWShadingGroup.dyntype */
#define DRW_DYN_POINTS 1
#define DRW_DYN_LINES 2
#define DRW_DYN_INSTANCE 3
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, struct Batch *geom);
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Batch *geom, float (*obmat)[4]);
void DRW_shgroup_dynamic_call_add(DRWShadingGroup *shgroup, ...);
void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_dyntype_set(DRWShadingGroup *shgroup, int type);
void DRW_shgroup_attrib_int(DRWShadingGroup *shgroup, const char *name, int size);
void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size);
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex, int loc);
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const struct GPUUniformBuffer *ubo, int loc);
@ -185,7 +186,6 @@ void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const
/* Passes */
DRWPass *DRW_pass_create(const char *name, DRWState state);
DRWShadingGroup *DRW_pass_nth_shgroup_get(DRWPass *pass, int n);
/* Viewport */
typedef enum {

View File

@ -58,6 +58,8 @@
#include "clay.h"
#define MAX_ATTRIB_NAME 32
extern char datatoc_gpu_shader_2D_vert_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_basic_vert_glsl[];
@ -74,7 +76,12 @@ typedef enum {
DRW_UNIFORM_BLOCK
} DRWUniformType;
struct DRWUniform {
typedef enum {
DRW_ATTRIB_INT,
DRW_ATTRIB_FLOAT,
} DRWAttribType;
typedef struct DRWUniform {
struct DRWUniform *next, *prev;
DRWUniformType type;
int location;
@ -82,10 +89,24 @@ struct DRWUniform {
int arraysize;
int bindloc;
const void *value;
};
} DRWUniform;
typedef struct DRWAttrib {
struct DRWAttrib *next, *prev;
char name[MAX_ATTRIB_NAME];
int location;
int format_id;
int size; /* number of component */
int type;
} DRWAttrib;
struct DRWInterface {
ListBase uniforms;
ListBase uniforms; /* DRWUniform */
ListBase attribs; /* DRWAttrib */
int attribs_count;
int attribs_stride;
int attribs_size[16];
int attribs_loc[16];
/* matrices locations */
int modelview;
int projection;
@ -93,10 +114,14 @@ struct DRWInterface {
int viewprojection;
int normal;
int eye;
/* Dynamic batch */
GLuint instance_vbo;
int instance_count;
VertexFormat vbo_format;
};
struct DRWPass {
ListBase shgroups;
ListBase shgroups; /* DRWShadingGroup */
DRWState state;
float state_param; /* Line / Point width */
};
@ -104,19 +129,33 @@ struct DRWPass {
typedef struct DRWCall {
struct DRWCall *next, *prev;
Batch *geometry;
float(*obmat)[4];
float (*obmat)[4];
} DRWCall;
typedef struct DRWDynamicCall {
struct DRWDynamicCall *next, *prev;
const void *data[];
} DRWDynamicCall;
struct DRWShadingGroup {
struct DRWShadingGroup *next, *prev;
struct GPUShader *shader; /* Shader to bind */
struct DRWInterface *interface; /* Uniforms pointers */
ListBase calls; /* List with all geometry and transforms */
ListBase calls; /* DRWCall or DRWDynamicCall depending of type*/
int state; /* State changes for this batch only */
short dyntype; /* Dynamic Batch type, 0 is normal */
Batch *dyngeom; /* Dynamic batch */
GLuint instance_vbo; /* Dynamic batch VBO storing Model Matrices */
int instance_count; /* Dynamic batch Number of instance to render */
int type;
Batch *instance_geom; /* Geometry to instance */
Batch *batch_geom; /* Result of call batching */
};
/* Used by DRWShadingGroup.type */
enum {
DRW_SHG_NORMAL,
DRW_SHG_POINT_BATCH,
DRW_SHG_LINE_BATCH,
DRW_SHG_INSTANCE,
};
/* Render State */
@ -292,8 +331,14 @@ static DRWInterface *DRW_interface_create(GPUShader *shader)
interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
interface->eye = GPU_shader_get_uniform(shader, "eye");
interface->instance_count = 0;
interface->attribs_count = 0;
interface->attribs_stride = 0;
memset(&interface->vbo_format, 0, sizeof(VertexFormat));
BLI_listbase_clear(&interface->uniforms);
BLI_listbase_clear(&interface->attribs);
return interface;
}
@ -327,6 +372,31 @@ 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)
{
DRWAttrib *attrib = MEM_mallocN(sizeof(DRWAttrib), "DRWAttrib");
GLuint program = GPU_shader_get_program(shgroup->shader);
attrib->location = glGetAttribLocation(program, name);
attrib->type = type;
attrib->size = size;
if (attrib->location == -1) {
if (G.debug & G_DEBUG)
fprintf(stderr, "Attribute '%s' not found!\n", name);
MEM_freeN(attrib);
return;
}
BLI_assert(BLI_strnlen(name, 32) < 32);
BLI_strncpy(attrib->name, name, 32);
shgroup->interface->attribs_count += 1;
BLI_addtail(&shgroup->interface->attribs, attrib);
}
void DRW_get_dfdy_factors(float dfdyfac[2])
{
GPU_get_dfdy_factors(dfdyfac);
@ -336,15 +406,47 @@ void DRW_get_dfdy_factors(float dfdyfac[2])
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = MEM_callocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
shgroup->type = DRW_SHG_NORMAL;
shgroup->shader = shader;
shgroup->interface = DRW_interface_create(shader);
shgroup->state = 0;
shgroup->dyntype = 0;
shgroup->dyngeom = NULL;
shgroup->batch_geom = NULL;
shgroup->instance_geom = NULL;
BLI_addtail(&pass->shgroups, shgroup);
BLI_listbase_clear(&shgroup->calls);
return shgroup;
}
DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Batch *geom)
{
DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
shgroup->type = DRW_SHG_INSTANCE;
shgroup->instance_geom = geom;
return shgroup;
}
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
shgroup->type = DRW_SHG_POINT_BATCH;
DRW_shgroup_attrib_float(shgroup, "pos", 3);
return shgroup;
}
DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
shgroup->type = DRW_SHG_LINE_BATCH;
DRW_shgroup_attrib_float(shgroup, "pos", 3);
return shgroup;
}
@ -353,13 +455,15 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
{
BLI_freelistN(&shgroup->calls);
BLI_freelistN(&shgroup->interface->uniforms);
BLI_freelistN(&shgroup->interface->attribs);
/* TODO free instance vbo */
MEM_freeN(shgroup->interface);
if (shgroup->dyngeom)
Batch_discard_all(shgroup->dyngeom);
if (shgroup->batch_geom) {
Batch_discard_all(shgroup->batch_geom);
}
}
/* Later use VBO */
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[4])
{
if (geom) {
@ -372,6 +476,26 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[
}
}
void DRW_shgroup_dynamic_call_add(DRWShadingGroup *shgroup, ...)
{
va_list params;
int i;
DRWInterface *interface = shgroup->interface;
int size = sizeof(ListBase) + sizeof(void *) * interface->attribs_count;
DRWDynamicCall *call = MEM_callocN(size, "DRWDynamicCall");
va_start(params, shgroup);
for (i = 0; i < interface->attribs_count; ++i) {
call->data[i] = va_arg(params, void *);
}
va_end(params);
interface->instance_count += 1;
BLI_addtail(&shgroup->calls, call);
}
/* Make sure you know what you do when using this,
* State is not revert back at the end of the shgroup */
void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state)
@ -379,9 +503,9 @@ void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state)
shgroup->state = state;
}
void DRW_shgroup_dyntype_set(DRWShadingGroup *shgroup, int type)
void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
{
shgroup->dyntype = type;
DRW_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size);
}
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex, int loc)
@ -450,85 +574,95 @@ void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const
DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
}
/* Creates OGL primitives based on DRWCall.obmat position list */
static void shgroup_dynamic_batch_primitives(DRWShadingGroup *shgroup)
/* Creates a VBO containing OGL primitives for all DRWDynamicCall */
static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
{
int i = 0;
int nbr = BLI_listbase_count(&shgroup->calls);
GLenum type;
DRWInterface *interface = shgroup->interface;
int nbr = interface->instance_count;
if (nbr == 0) {
if (shgroup->dyngeom) {
Batch_discard(shgroup->dyngeom);
shgroup->dyngeom = NULL;
}
GLenum type = (shgroup->type == DRW_SHG_POINT_BATCH) ? GL_POINTS : GL_LINES;
if (nbr == 0)
return;
}
/* Gather Data */
float *data = MEM_mallocN(sizeof(float) * 3 * nbr , "Object Center Batch data");
for (DRWCall *call = shgroup->calls.first; call; call = call->next, i++) {
copy_v3_v3(&data[i*3], call->obmat[3]);
}
/* Upload Data */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next) {
BLI_assert(attrib->size <= 4); /* matrices have no place here for now */
if (attrib->type == DRW_ATTRIB_FLOAT) {
attrib->format_id = add_attrib(&interface->vbo_format, attrib->name, GL_FLOAT, attrib->size, KEEP_FLOAT);
}
else if (attrib->type == DRW_ATTRIB_INT) {
attrib->format_id = add_attrib(&interface->vbo_format, attrib->name, GL_BYTE, attrib->size, KEEP_INT);
}
else {
BLI_assert(false);
}
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer *vbo = VertexBuffer_create_with_format(&interface->vbo_format);
VertexBuffer_allocate_data(vbo, nbr);
fillAttrib(vbo, pos_id, data);
if (shgroup->dyntype == DRW_DYN_POINTS)
type = GL_POINTS;
else
type = GL_LINES;
for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
int j = 0;
for (DRWDynamicCall *call = shgroup->calls.first; call; call = call->next, j++) {
setAttrib(vbo, attrib->format_id, j, call->data[i]);
}
}
/* TODO make the batch dynamic instead of freeing it every times */
if (shgroup->dyngeom)
Batch_discard_all(shgroup->dyngeom);
if (shgroup->batch_geom)
Batch_discard_all(shgroup->batch_geom);
shgroup->dyngeom = Batch_create(type, vbo, NULL);
MEM_freeN(data);
shgroup->batch_geom = Batch_create(type, vbo, NULL);
}
static void shgroup_dynamic_batch_instance(DRWShadingGroup *shgroup)
static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
{
int i = 0;
int nbr = BLI_listbase_count(&shgroup->calls);
int offset = 0;
DRWInterface *interface = shgroup->interface;
int vert_nbr = interface->instance_count;
shgroup->instance_count = nbr;
if (nbr == 0) {
if (shgroup->instance_vbo) {
glDeleteBuffers(1, &shgroup->instance_vbo);
shgroup->instance_vbo = 0;
if (vert_nbr == 0) {
if (interface->instance_vbo) {
glDeleteBuffers(1, &interface->instance_vbo);
interface->instance_vbo = 0;
}
return;
}
/* Gather Data */
float *data = MEM_mallocN(sizeof(float) * 4 * 4 * nbr , "Instance Model Matrix");
/* only once */
if (interface->attribs_stride == 0) {
for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
interface->attribs_stride += attrib->size;
interface->attribs_size[i] = attrib->size;
interface->attribs_loc[i] = attrib->location;
}
}
for (DRWCall *call = shgroup->calls.first; call; call = call->next, i++) {
copy_m4_m4((float (*)[4])&data[i*16], call->obmat);
/* Gather Data */
float *data = MEM_mallocN(sizeof(float) * interface->attribs_stride * vert_nbr , "Instance VBO data");
i = 0;
for (DRWDynamicCall *call = shgroup->calls.first; call; call = call->next, i++) {
int j = 0;
for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, j++) {
BLI_assert(attrib->type == DRW_ATTRIB_FLOAT); /* Only float for now */
memcpy(data + offset, call->data[j], sizeof(float) * attrib->size);
offset += attrib->size;
}
}
/* TODO poke mike to add this to gawain */
if (shgroup->instance_vbo) {
glDeleteBuffers(1, &shgroup->instance_vbo);
shgroup->instance_vbo = 0;
if (interface->instance_vbo) {
glDeleteBuffers(1, &interface->instance_vbo);
interface->instance_vbo = 0;
}
glGenBuffers(1, &shgroup->instance_vbo);
glBindBuffer(GL_ARRAY_BUFFER, shgroup->instance_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 4 * nbr, data, GL_STATIC_DRAW);
glGenBuffers(1, &interface->instance_vbo);
glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 4 * vert_nbr, data, GL_STATIC_DRAW);
MEM_freeN(data);
}
@ -536,13 +670,13 @@ static void shgroup_dynamic_batch_instance(DRWShadingGroup *shgroup)
static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
{
#ifdef WITH_VIEWPORT_CACHE_TEST
if (shgroup->dyngeom) return;
if (shgroup->interface->instance_vbo || shgroup->batch_geom) return;
#endif
if (shgroup->dyntype == DRW_DYN_INSTANCE) {
shgroup_dynamic_batch_instance(shgroup);
if (shgroup->type == DRW_SHG_INSTANCE) {
shgroup_dynamic_instance(shgroup);
}
else {
shgroup_dynamic_batch_primitives(shgroup);
shgroup_dynamic_batch(shgroup);
}
}
@ -566,19 +700,6 @@ void DRW_pass_free(DRWPass *pass)
BLI_freelistN(&pass->shgroups);
}
/* TODO this is slow we should not have to use this (better store shgroup pointer somewhere) */
DRWShadingGroup *DRW_pass_nth_shgroup_get(DRWPass *pass, int n)
{
int i = 0;
for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
if (i == n)
return shgroup;
i++;
}
return NULL;
}
/* ****************************************** DRAW ******************************************/
void DRW_draw_background(void)
@ -720,7 +841,8 @@ static void draw_geometry(DRWShadingGroup *shgroup, DRWInterface *interface, Bat
/* step 2 : bind vertex array & draw */
Batch_set_program(geom, GPU_shader_get_program(shgroup->shader));
if (instance_vbo) {
Batch_draw_stupid_instanced(geom, instance_vbo, instance_count);
Batch_draw_stupid_instanced(geom, instance_vbo, instance_count, interface->attribs_count,
interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
}
else {
Batch_draw_stupid(geom);
@ -740,7 +862,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup)
DST.shader = shgroup->shader;
}
if (shgroup->dyntype != 0) {
if (shgroup->type != DRW_SHG_NORMAL) {
shgroup_dynamic_batch_from_calls(shgroup);
}
@ -790,19 +912,18 @@ static void draw_shgroup(DRWShadingGroup *shgroup)
}
/* Rendering Calls */
if (shgroup->dyntype != 0) {
if (shgroup->type != DRW_SHG_NORMAL) {
/* Replacing multiple calls with only one */
float obmat[4][4];
unit_m4(obmat);
if (shgroup->dyntype == DRW_DYN_INSTANCE && shgroup->instance_count > 0) {
DRWCall *call = shgroup->calls.first;
draw_geometry(shgroup, interface, call->geometry, shgroup->instance_vbo, shgroup->instance_count, obmat);
if (shgroup->type == DRW_SHG_INSTANCE && interface->instance_count > 0) {
draw_geometry(shgroup, interface, shgroup->instance_geom, interface->instance_vbo, interface->instance_count, obmat);
}
else {
/* Some dynamic batch can have no geom (no call to aggregate) */
if (shgroup->dyngeom) {
draw_geometry(shgroup, interface, shgroup->dyngeom, 0, 1, obmat);
if (shgroup->batch_geom) {
draw_geometry(shgroup, interface, shgroup->batch_geom, 0, 1, obmat);
}
}
}

View File

@ -126,13 +126,19 @@ static DRWShadingGroup *center_active;
static DRWShadingGroup *center_selected;
static DRWShadingGroup *center_deselected;
static DRWShadingGroup *shgroup_instance_uniform_color(DRWPass *pass, float color[4])
/* Colors & Constant */
static float colorWire[4], colorWireEdit[4];
static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], colorGroupActive[4];
static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
static DRWShadingGroup *shgroup_instance_uniform_color(DRWPass *pass, struct Batch *geom, float color[4])
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE);
DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_INSTANCE);
return grp;
}
@ -141,9 +147,8 @@ static DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float colo
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_LINES);
return grp;
}
@ -152,10 +157,9 @@ static DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float col
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_float(grp, "size", size, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_state_set(grp, DRW_STATE_POINT);
return grp;
@ -165,9 +169,8 @@ static DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float c
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
return grp;
}
@ -176,24 +179,25 @@ static DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_state_set(grp, DRW_STATE_POINT);
return grp;
}
static DRWShadingGroup *shgroup_lamp(DRWPass *pass, float color[4], float *size)
static DRWShadingGroup *shgroup_lamp(DRWPass *pass, struct Batch *geom, float color[4], float *size)
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LAMP_COMMON);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_float(grp, "size", size, 1);
DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
DRW_shgroup_dyntype_set(grp, DRW_DYN_INSTANCE);
DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_3);
return grp;
}
@ -202,10 +206,7 @@ static DRWShadingGroup *shgroup_lamp(DRWPass *pass, float color[4], float *size)
void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **non_meshes, DRWPass **ob_center)
{
/* Theses are defined for the whole application so make sure they rely on global settings */
static float colorWire[4], colorWireEdit[4];
static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], colorGroupActive[4];
static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
UI_GetThemeColor4fv(TH_WIRE, colorWire);
UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit);
@ -239,6 +240,7 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
if (non_meshes) {
/* Non Meshes Pass (Camera, empties, lamps ...) */
DRWShadingGroup *grp;
struct Batch *geom;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
state |= DRW_STATE_WIRE;
@ -247,61 +249,69 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
/* Empties */
plain_axes_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
plain_axes_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
plain_axes_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
plain_axes_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
plain_axes_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
plain_axes_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_plain_axes_get();
plain_axes_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
plain_axes_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
plain_axes_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
plain_axes_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
plain_axes_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
plain_axes_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
cube_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
cube_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
cube_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
cube_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
cube_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
cube_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_cube_get();
cube_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
cube_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
cube_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
cube_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
cube_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
cube_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
circle_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
circle_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
circle_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
circle_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
circle_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
circle_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_circle_get();
circle_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
circle_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
circle_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
circle_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
circle_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
circle_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
sphere_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
sphere_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
sphere_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
sphere_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
sphere_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
sphere_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_empty_sphere_get();
sphere_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
sphere_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
sphere_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
sphere_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
sphere_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
sphere_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
cone_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
cone_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
cone_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
cone_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
cone_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
cone_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_empty_cone_get();
cone_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
cone_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
cone_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
cone_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
cone_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
cone_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
single_arrow_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
single_arrow_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
single_arrow_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
single_arrow_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
single_arrow_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
single_arrow_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_single_arrow_get();
single_arrow_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
single_arrow_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
single_arrow_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
single_arrow_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
single_arrow_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
single_arrow_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
single_arrow_line_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
single_arrow_line_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
single_arrow_line_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
single_arrow_line_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
single_arrow_line_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
single_arrow_line_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_single_line_get();
single_arrow_line_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
single_arrow_line_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
single_arrow_line_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
single_arrow_line_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
single_arrow_line_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
single_arrow_line_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
arrows_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
arrows_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
arrows_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
arrows_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
arrows_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
arrows_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
geom = DRW_cache_single_arrow_get();
arrows_wire = shgroup_instance_uniform_color(*non_meshes, geom, colorEmpty);
arrows_active = shgroup_instance_uniform_color(*non_meshes, geom, colorActive);
arrows_select = shgroup_instance_uniform_color(*non_meshes, geom, colorSelect);
arrows_transform = shgroup_instance_uniform_color(*non_meshes, geom, colorTransform);
arrows_group = shgroup_instance_uniform_color(*non_meshes, geom, colorGroup);
arrows_group_active = shgroup_instance_uniform_color(*non_meshes, geom, colorGroupActive);
/* Lamps */
lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize;
@ -312,24 +322,29 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
* but ideally we would only create it once */
lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize);
lamp_center_group = shgroup_dynpoints_uniform_color(*non_meshes, colorGroup, &lampCenterSize);
lamp_circle = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
lamp_circle_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
lamp_circle_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
lamp_circle_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleRad);
lamp_circle_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleRad);
lamp_circle_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleRad);
lamp_circle_shadow = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleShadowRad);
lamp_circle_shadow_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleShadowRad);
lamp_circle_shadow_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleShadowRad);
lamp_circle_shadow_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleShadowRad);
lamp_circle_shadow_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleShadowRad);
lamp_circle_shadow_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleShadowRad);
lamp_sunrays = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
lamp_sunrays_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
lamp_sunrays_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
lamp_sunrays_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleRad);
lamp_sunrays_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleRad);
lamp_sunrays_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleRad);
geom = DRW_cache_lamp_get();
lamp_circle = shgroup_lamp(*non_meshes, geom, colorLampNoAlpha, &lampCircleRad);
lamp_circle_active = shgroup_lamp(*non_meshes, geom, colorActive, &lampCircleRad);
lamp_circle_select = shgroup_lamp(*non_meshes, geom, colorSelect, &lampCircleRad);
lamp_circle_transform = shgroup_lamp(*non_meshes, geom, colorTransform, &lampCircleRad);
lamp_circle_group = shgroup_lamp(*non_meshes, geom, colorGroup, &lampCircleRad);
lamp_circle_group_active = shgroup_lamp(*non_meshes, geom, colorGroupActive, &lampCircleRad);
lamp_circle_shadow = shgroup_lamp(*non_meshes, geom, colorLampNoAlpha, &lampCircleShadowRad);
lamp_circle_shadow_active = shgroup_lamp(*non_meshes, geom, colorActive, &lampCircleShadowRad);
lamp_circle_shadow_select = shgroup_lamp(*non_meshes, geom, colorSelect, &lampCircleShadowRad);
lamp_circle_shadow_transform = shgroup_lamp(*non_meshes, geom, colorTransform, &lampCircleShadowRad);
lamp_circle_shadow_group = shgroup_lamp(*non_meshes, geom, colorGroup, &lampCircleShadowRad);
lamp_circle_shadow_group_active = shgroup_lamp(*non_meshes, geom, colorGroupActive, &lampCircleShadowRad);
geom = DRW_cache_lamp_sunrays_get();
lamp_sunrays = shgroup_lamp(*non_meshes, geom, colorLampNoAlpha, &lampCircleRad);
lamp_sunrays_active = shgroup_lamp(*non_meshes, geom, colorActive, &lampCircleRad);
lamp_sunrays_select = shgroup_lamp(*non_meshes, geom, colorSelect, &lampCircleRad);
lamp_sunrays_transform = shgroup_lamp(*non_meshes, geom, colorTransform, &lampCircleRad);
lamp_sunrays_group = shgroup_lamp(*non_meshes, geom, colorGroup, &lampCircleRad);
lamp_sunrays_group_active = shgroup_lamp(*non_meshes, geom, colorGroupActive, &lampCircleRad);
lamp_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp);
lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp);
@ -367,8 +382,7 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH);
/* Active */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
grp = DRW_shgroup_point_batch_create(sh, *ob_center);
DRW_shgroup_uniform_float(grp, "size", &size, 1);
DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
DRW_shgroup_uniform_vec4(grp, "color", colorActive, 1);
@ -376,14 +390,12 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
center_active = grp;
/* Select */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
grp = DRW_shgroup_point_batch_create(sh, *ob_center);
DRW_shgroup_uniform_vec4(grp, "color", colorSelect, 1);
center_selected = grp;
/* Deselect */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
grp = DRW_shgroup_point_batch_create(sh, *ob_center);
DRW_shgroup_uniform_vec4(grp, "color", colorDeselect, 1);
center_deselected = grp;
}
@ -534,75 +546,71 @@ void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
static void DRW_draw_lamp(Object *ob)
{
struct Batch *center = DRW_cache_single_vert_get();
struct Batch *lamp = DRW_cache_lamp_get();
struct Batch *sunrays = DRW_cache_lamp_sunrays_get();
Lamp *la = ob->data;
int theme_id = draw_object_wire_theme(ob);
/* Don't draw the center if it's selected or active */
if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_center_group, center, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_center_group, ob->obmat[3]);
else if (theme_id == TH_LAMP)
DRW_shgroup_call_add(lamp_center, center, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_center, ob->obmat[3]);
/* First circle */
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_circle_active, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_active, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_circle_select, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_select, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_circle_group, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_group, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_circle_group_active, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_group_active, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_circle_transform, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_transform, ob->obmat);
else
DRW_shgroup_call_add(lamp_circle, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle, ob->obmat);
/* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
if (la->type != LA_HEMI) {
if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_circle_shadow_active, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow_active, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_circle_shadow_select, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow_select, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_circle_shadow_group, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow_group, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_circle_shadow_group_active, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow_group_active, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_circle_shadow_transform, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow_transform, ob->obmat);
else
DRW_shgroup_call_add(lamp_circle_shadow, lamp, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_circle_shadow, ob->obmat);
}
}
/* Sunrays */
if (la->type == LA_SUN) {
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_sunrays_active, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays_active, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_sunrays_select, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays_select, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_sunrays_group, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays_group, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_sunrays_group_active, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays_group_active, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_sunrays_transform, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays_transform, ob->obmat);
else
DRW_shgroup_call_add(lamp_sunrays, sunrays, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_sunrays, ob->obmat);
}
/* Line and point going to the ground */
DRW_shgroup_call_add(lamp_groundline, center, ob->obmat);
DRW_shgroup_call_add(lamp_groundpoint, center, ob->obmat);
DRW_shgroup_dynamic_call_add(lamp_groundline, ob->obmat[3]);
DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]);
}
static void DRW_draw_empty(Object *ob)
{
struct Batch *geom, *geom2;
DRWShadingGroup *grp, *grp2;
DRWShadingGroup *grp, *grp2 = NULL;
int theme_id = draw_object_wire_theme(ob);
switch (ob->empty_drawtype) {
@ -619,9 +627,6 @@ static void DRW_draw_empty(Object *ob)
grp = plain_axes_transform;
else
grp = plain_axes_wire;
geom = DRW_cache_plain_axes_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_SINGLE_ARROW:
@ -649,10 +654,6 @@ static void DRW_draw_empty(Object *ob)
grp = single_arrow_wire;
grp2 = single_arrow_line_wire;
}
geom = DRW_cache_single_arrow_get(&geom2);
DRW_shgroup_call_add(grp, geom, ob->obmat);
DRW_shgroup_call_add(grp2, geom2, ob->obmat);
break;
case OB_CUBE:
@ -668,9 +669,6 @@ static void DRW_draw_empty(Object *ob)
grp = cube_transform;
else
grp = cube_wire;
geom = DRW_cache_cube_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_CIRCLE:
@ -686,9 +684,6 @@ static void DRW_draw_empty(Object *ob)
grp = circle_transform;
else
grp = circle_wire;
geom = DRW_cache_circle_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_EMPTY_SPHERE:
@ -704,9 +699,6 @@ static void DRW_draw_empty(Object *ob)
grp = sphere_transform;
else
grp = sphere_wire;
geom = DRW_cache_empty_sphere_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_EMPTY_CONE:
@ -722,9 +714,6 @@ static void DRW_draw_empty(Object *ob)
grp = cone_transform;
else
grp = cone_wire;
geom = DRW_cache_empty_cone_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_ARROWS:
@ -741,12 +730,14 @@ static void DRW_draw_empty(Object *ob)
grp = arrows_transform;
else
grp = arrows_wire;
geom = DRW_cache_arrows_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
/* TODO Missing axes names */
break;
}
DRW_shgroup_dynamic_call_add(grp, ob->obmat);
if (grp2 != NULL) {
DRW_shgroup_dynamic_call_add(grp2, ob->obmat);
}
}
void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), Object *ob)
@ -766,9 +757,8 @@ void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), Object *ob)
void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
{
if (ob->parent) {
struct Batch *geom = DRW_cache_single_vert_get();
DRW_shgroup_call_add(relationship_lines, geom, ob->obmat);
DRW_shgroup_call_add(relationship_lines, geom, ob->parent->obmat);
DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]);
DRW_shgroup_dynamic_call_add(relationship_lines, ob->parent->obmat[3]);
}
}
@ -776,12 +766,10 @@ void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
void DRW_shgroup_object_center(DRWPass *UNUSED(ob_center), Object *ob)
{
struct Batch *geom = DRW_cache_single_vert_get();
if ((ob->base_flag & BASE_SELECTED) != 0) {
DRW_shgroup_call_add(center_selected, geom, ob->obmat);
DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);
}
else if (0) {
DRW_shgroup_call_add(center_deselected, geom, ob->obmat);
DRW_shgroup_dynamic_call_add(center_deselected, ob->obmat[3]);
}
}

View File

@ -291,7 +291,8 @@ void Batch_draw_stupid(Batch* batch)
}
// clement : temp stuff
void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count)
void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count,
int attrib_nbr, int attrib_stride, int attrib_size[16], int attrib_loc[16])
{
if (batch->vao_id)
glBindVertexArray(batch->vao_id);
@ -301,27 +302,24 @@ void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int in
if (batch->program_dirty)
Batch_update_program_bindings(batch);
const GLint loc = glGetAttribLocation(batch->program, "InstanceModelMatrix");
#if TRUST_NO_ONE
assert(loc != -1);
#endif
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc + 0, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)0);
glEnableVertexAttribArray(loc + 1);
glVertexAttribPointer(loc + 1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(sizeof(float)*4));
glEnableVertexAttribArray(loc + 2);
glVertexAttribPointer(loc + 2, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(2 * sizeof(float)*4));
glEnableVertexAttribArray(loc + 3);
glVertexAttribPointer(loc + 3, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(3 * sizeof(float)*4));
glBindBuffer(GL_ARRAY_BUFFER, 0);
int ptr_ofs = 0;
for (int i = 0; i < attrib_nbr; ++i) {
int size = attrib_size[i];
int loc = attrib_loc[i];
int atr_ofs = 0;
glVertexAttribDivisor(loc + 0, 1);
glVertexAttribDivisor(loc + 1, 1);
glVertexAttribDivisor(loc + 2, 1);
glVertexAttribDivisor(loc + 3, 1);
while (size > 0) {
glEnableVertexAttribArray(loc + atr_ofs);
glVertexAttribPointer(loc + atr_ofs, (size > 4) ? 4 : size, GL_FLOAT, GL_FALSE,
sizeof(float) * attrib_stride, (GLvoid*)(sizeof(float) * ptr_ofs));
glVertexAttribDivisor(loc + atr_ofs, 1);
size -= 4;
atr_ofs++;
ptr_ofs += (size > 4) ? 4 : size;
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Batch_use_program(batch);

View File

@ -61,8 +61,9 @@ void Batch_draw(Batch*);
// clement : temp stuff
void Batch_draw_stupid(Batch* batch);
void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count);
void Batch_draw_stupid(Batch*);
void Batch_draw_stupid_instanced(Batch*, unsigned int instance_vbo, int instance_count,
int attrib_nbr, int attrib_stride, int attrib_loc[16], int attrib_size[16]);