Silence more warnings
[blender.git] / source / blender / draw / intern / draw_manager.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file blender/draw/draw_manager.c
23  *  \ingroup draw
24  */
25
26 #include <stdio.h>
27
28 #include "BLI_listbase.h"
29 #include "BLI_rect.h"
30 #include "BLI_string.h"
31
32 #include "BIF_glutil.h"
33
34 #include "BKE_global.h"
35
36 #include "BLT_translation.h"
37
38 #include "DRW_engine.h"
39 #include "DRW_render.h"
40
41 #include "DNA_view3d_types.h"
42
43 #include "GPU_basic_shader.h"
44 #include "GPU_batch.h"
45 #include "GPU_draw.h"
46 #include "GPU_extensions.h"
47 #include "GPU_framebuffer.h"
48 #include "GPU_immediate.h"
49 #include "GPU_matrix.h"
50 #include "GPU_shader.h"
51 #include "GPU_texture.h"
52 #include "GPU_uniformbuffer.h"
53 #include "GPU_viewport.h"
54
55 #include "RE_engine.h"
56
57 #include "UI_resources.h"
58
59 #include "clay.h"
60
61 extern char datatoc_gpu_shader_2D_vert_glsl[];
62 extern char datatoc_gpu_shader_3D_vert_glsl[];
63 extern char datatoc_gpu_shader_basic_vert_glsl[];
64
65 /* Structures */
66 typedef enum {
67         DRW_UNIFORM_BOOL,
68         DRW_UNIFORM_INT,
69         DRW_UNIFORM_FLOAT,
70         DRW_UNIFORM_TEXTURE,
71         DRW_UNIFORM_BUFFER,
72         DRW_UNIFORM_MAT3,
73         DRW_UNIFORM_MAT4,
74         DRW_UNIFORM_BLOCK
75 } DRWUniformType;
76
77 struct DRWUniform {
78         struct DRWUniform *next, *prev;
79         DRWUniformType type;
80         int location;
81         int length;
82         int arraysize;
83         int bindloc;
84         const void *value;
85 };
86
87 struct DRWInterface {
88         ListBase uniforms;
89         /* matrices locations */
90         int modelview;
91         int projection;
92         int modelviewprojection;
93         int viewprojection;
94         int normal;
95         int eye;
96 };
97
98 struct DRWPass {
99         ListBase shgroups;
100         DRWState state;
101         float state_param; /* Line / Point width */
102 };
103
104 typedef struct DRWCall {
105         struct DRWCall *next, *prev;
106         Batch *geometry;
107         float(*obmat)[4];
108 } DRWCall;
109
110 struct DRWShadingGroup {
111         struct DRWShadingGroup *next, *prev;
112         struct GPUShader *shader;        /* Shader to bind */
113         struct DRWInterface *interface;  /* Uniforms pointers */
114         ListBase calls;                  /* List with all geometry and transforms */
115         int state;                       /* State changes for this batch only */
116         short dyntype;                   /* Dynamic Batch type, 0 is normal */
117         Batch *dyngeom;                  /* Dynamic batch */
118         GLuint instance_vbo;             /* Dynamic batch VBO storing Model Matrices */
119         int instance_count;                /* Dynamic batch Number of instance to render */
120 };
121
122 /* Render State */
123 static struct DRWGlobalState{
124         GPUShader *shader;
125         struct GPUFrameBuffer *default_framebuffer;
126         FramebufferList *current_fbl;
127         TextureList *current_txl;
128         PassList *current_psl;
129         ListBase bound_texs;
130         int tex_bind_id;
131         float size[2];
132         /* Current rendering context set by DRW_viewport_init */
133         const struct bContext *context;
134 } DST = {NULL};
135
136 /* ***************************************** TEXTURES ******************************************/
137 static void drw_texture_get_format(DRWTextureFormat format, GPUFormat *data_type, int *channels)
138 {
139         switch (format) {
140                 case DRW_TEX_RGBA_8: *data_type = GPU_RGBA8; break;
141                 case DRW_TEX_RGBA_16: *data_type = GPU_RGBA16F; break;
142                 case DRW_TEX_RGBA_32: *data_type = GPU_RGBA32F; break;
143                 case DRW_TEX_RGB_8: *data_type = GPU_RGB8; break;
144                 case DRW_TEX_RGB_16: *data_type = GPU_RGB16F; break;
145                 case DRW_TEX_RGB_32: *data_type = GPU_RGB32F; break;
146                 case DRW_TEX_RG_8: *data_type = GPU_RG8; break;
147                 case DRW_TEX_RG_16: *data_type = GPU_RG16F; break;
148                 case DRW_TEX_RG_32: *data_type = GPU_RG32F; break;
149                 case DRW_TEX_R_8: *data_type = GPU_R8; break;
150                 case DRW_TEX_R_16: *data_type = GPU_R16F; break;
151                 case DRW_TEX_R_32: *data_type = GPU_R32F; break;
152                 case DRW_TEX_DEPTH_16: *data_type = GPU_DEPTH_COMPONENT16; break;
153                 case DRW_TEX_DEPTH_24: *data_type = GPU_DEPTH_COMPONENT24; break;
154                 case DRW_TEX_DEPTH_32: *data_type = GPU_DEPTH_COMPONENT32F; break;
155         }
156
157         switch (format) {
158                 case DRW_TEX_RGBA_8:
159                 case DRW_TEX_RGBA_16:
160                 case DRW_TEX_RGBA_32:
161                         *channels = 4;
162                         break;
163                 case DRW_TEX_RGB_8:
164                 case DRW_TEX_RGB_16:
165                 case DRW_TEX_RGB_32:
166                         *channels = 3;
167                         break;
168                 case DRW_TEX_RG_8:
169                 case DRW_TEX_RG_16:
170                 case DRW_TEX_RG_32:
171                         *channels = 2;
172                         break;
173                 default:
174                         *channels = 1;
175                         break;
176         }
177 }
178
179 static void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
180 {
181         GPU_texture_bind(tex, 0);
182         GPU_texture_filter_mode(tex, flags & DRW_TEX_FILTER);
183         GPU_texture_wrap_mode(tex, flags & DRW_TEX_WRAP);
184         GPU_texture_compare_mode(tex, flags & DRW_TEX_COMPARE);
185         GPU_texture_unbind(tex);
186 }
187
188 GPUTexture *DRW_texture_create_1D(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
189 {
190         GPUTexture *tex;
191         GPUFormat data_type;
192         int channels;
193
194         drw_texture_get_format(format, &data_type, &channels);
195         tex = GPU_texture_create_1D_custom(w, channels, data_type, fpixels, NULL);
196         drw_texture_set_parameters(tex, flags);
197
198         return tex;
199 }
200
201 GPUTexture *DRW_texture_create_2D(int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
202 {
203         GPUTexture *tex;
204         GPUFormat data_type;
205         int channels;
206
207         drw_texture_get_format(format, &data_type, &channels);
208         tex = GPU_texture_create_2D_custom(w, h, channels, data_type, fpixels, NULL);
209         drw_texture_set_parameters(tex, flags);
210
211         return tex;
212 }
213
214 /* TODO make use of format */
215 GPUTexture *DRW_texture_create_2D_array(int w, int h, int d, DRWTextureFormat UNUSED(format), DRWTextureFlag flags, const float *fpixels)
216 {
217         GPUTexture *tex;
218
219         tex = GPU_texture_create_2D_array(w, h, d, fpixels, NULL);
220         drw_texture_set_parameters(tex, flags);
221
222         return tex;
223 }
224
225 void DRW_texture_free(GPUTexture *tex)
226 {
227         GPU_texture_free(tex);
228 }
229
230
231 /* ************************************ UNIFORM BUFFER OBJECT **********************************/
232
233 GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data)
234 {
235         return GPU_uniformbuffer_create(size, data, NULL);
236 }
237
238 void DRW_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
239 {
240         GPU_uniformbuffer_update(ubo, data);
241 }
242
243 void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
244 {
245         GPU_uniformbuffer_free(ubo);
246 }
247
248 /* ****************************************** SHADERS ******************************************/
249
250 GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines)
251 {
252         return GPU_shader_create(vert, frag, geom, NULL, defines, 0, 0, 0);
253 }
254
255 GPUShader *DRW_shader_create_2D(const char *frag, const char *defines)
256 {
257         return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines, 0, 0, 0);
258 }
259
260 GPUShader *DRW_shader_create_3D(const char *frag, const char *defines)
261 {
262         return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines, 0, 0, 0);
263 }
264
265 GPUShader *DRW_shader_create_3D_depth_only(void)
266 {
267         return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
268 }
269
270 void DRW_shader_free(GPUShader *shader)
271 {
272         GPU_shader_free(shader);
273 }
274
275 /* ***************************************** INTERFACE ******************************************/
276
277 static DRWInterface *DRW_interface_create(GPUShader *shader)
278 {
279         DRWInterface *interface = MEM_mallocN(sizeof(DRWInterface), "DRWInterface");
280
281         interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix");
282         interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix");
283         interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix");
284         interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
285         interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
286         interface->eye = GPU_shader_get_uniform(shader, "eye");
287
288         BLI_listbase_clear(&interface->uniforms);
289
290         return interface;
291 }
292
293 static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
294                                   DRWUniformType type, const void *value, int length, int arraysize, int bindloc)
295 {
296         DRWUniform *uni = MEM_mallocN(sizeof(DRWUniform), "DRWUniform");
297
298         if (type == DRW_UNIFORM_BLOCK) {
299                 uni->location = GPU_shader_get_uniform_block(shgroup->shader, name);
300         }
301         else {
302                 uni->location = GPU_shader_get_uniform(shgroup->shader, name);
303         }
304
305         uni->type = type;
306         uni->value = value;
307         uni->length = length;
308         uni->arraysize = arraysize;
309         uni->bindloc = bindloc; /* for textures */
310
311         if (uni->location == -1) {
312                 if (G.debug & G_DEBUG)
313                         fprintf(stderr, "Uniform '%s' not found!\n", name);
314
315                 MEM_freeN(uni);
316                 return;
317         }
318
319         BLI_addtail(&shgroup->interface->uniforms, uni);
320 }
321
322 void DRW_get_dfdy_factors(float dfdyfac[2])
323 {
324         GPU_get_dfdy_factors(dfdyfac);
325 }
326
327 /* ***************************************** SHADING GROUP ******************************************/
328
329 DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
330 {
331         DRWShadingGroup *shgroup = MEM_callocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
332
333         shgroup->shader = shader;
334         shgroup->interface = DRW_interface_create(shader);
335         shgroup->state = 0;
336         shgroup->dyntype = 0;
337         shgroup->dyngeom = NULL;
338
339         BLI_addtail(&pass->shgroups, shgroup);
340
341         return shgroup;
342 }
343
344 void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
345 {
346         BLI_freelistN(&shgroup->calls);
347         BLI_freelistN(&shgroup->interface->uniforms);
348         MEM_freeN(shgroup->interface);
349
350         if (shgroup->dyngeom)
351                 Batch_discard(shgroup->dyngeom);
352 }
353
354 /* Later use VBO */
355 void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[4])
356 {
357         if (geom) {
358                 DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
359
360                 call->obmat = obmat;
361                 call->geometry = geom;
362
363                 BLI_addtail(&shgroup->calls, call);
364         }
365 }
366
367 /* Make sure you know what you do when using this,
368  * State is not revert back at the end of the shgroup */
369 void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state)
370 {
371         shgroup->state = state;
372 }
373
374 void DRW_shgroup_dyntype_set(DRWShadingGroup *shgroup, int type)
375 {
376         shgroup->dyntype = type;
377 }
378
379 void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex, int loc)
380 {
381         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 0, loc);
382 }
383
384 void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo, int loc)
385 {
386         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 0, loc);
387 }
388
389 void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, const int value, int loc)
390 {
391         /* we abuse the lenght attrib to store the buffer index */
392         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, NULL, value, 0, loc);
393 }
394
395 void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize)
396 {
397         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize, 0);
398 }
399
400 void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
401 {
402         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize, 0);
403 }
404
405 void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
406 {
407         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize, 0);
408 }
409
410 void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
411 {
412         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize, 0);
413 }
414
415 void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
416 {
417         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize, 0);
418 }
419
420 void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
421 {
422         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize, 0);
423 }
424
425 void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
426 {
427         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize, 0);
428 }
429
430 void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
431 {
432         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize, 0);
433 }
434
435 void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value)
436 {
437         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1, 0);
438 }
439
440 void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value)
441 {
442         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
443 }
444
445 /* Creates OGL primitives based on DRWCall.obmat position list */
446 static void shgroup_dynamic_batch_primitives(DRWShadingGroup *shgroup)
447 {
448         int i = 0;
449         int nbr = BLI_listbase_count(&shgroup->calls);
450         GLenum type;
451
452         if (nbr == 0) {
453                 if (shgroup->dyngeom) {
454                         Batch_discard(shgroup->dyngeom);
455                         shgroup->dyngeom = NULL;
456                 }
457                 return;
458         }
459
460         /* Gather Data */
461         float *data = MEM_mallocN(sizeof(float) * 3 * nbr , "Object Center Batch data");
462
463         for (DRWCall *call = shgroup->calls.first; call; call = call->next, i++) {
464                 copy_v3_v3(&data[i*3], call->obmat[3]);
465         }
466
467         /* Upload Data */
468         static VertexFormat format = { 0 };
469         static unsigned pos_id;
470         if (format.attrib_ct == 0) {
471                 pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
472         }
473
474         VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
475         VertexBuffer_allocate_data(vbo, nbr);
476
477         fillAttrib(vbo, pos_id, data);
478
479         if (shgroup->dyntype == DRW_DYN_POINTS)
480                 type = GL_POINTS;
481         else
482                 type = GL_LINES;
483
484         /* TODO make the batch dynamic instead of freeing it every times */
485         if (shgroup->dyngeom)
486                 Batch_discard(shgroup->dyngeom);
487
488         shgroup->dyngeom = Batch_create(type, vbo, NULL);
489
490         MEM_freeN(data);
491 }
492
493 static void shgroup_dynamic_batch_instance(DRWShadingGroup *shgroup)
494 {
495         int i = 0;
496         int nbr = BLI_listbase_count(&shgroup->calls);
497
498         shgroup->instance_count = nbr;
499
500         if (nbr == 0) {
501                 if (shgroup->instance_vbo) {
502                         glDeleteBuffers(1, &shgroup->instance_vbo);
503                         shgroup->instance_vbo = 0;
504                 }
505                 return;
506         }
507
508         /* Gather Data */
509         float *data = MEM_mallocN(sizeof(float) * 4 * 4 * nbr , "Instance Model Matrix");
510
511         for (DRWCall *call = shgroup->calls.first; call; call = call->next, i++) {
512                 copy_m4_m4((float (*)[4])&data[i*16], call->obmat);
513         }
514
515         /* Upload Data */
516         static VertexFormat format = { 0 };
517         static unsigned mat_id;
518         if (format.attrib_ct == 0) {
519                 mat_id = add_attrib(&format, "InstanceModelMatrix", GL_FLOAT, 4, KEEP_FLOAT);
520         }
521
522         VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
523         VertexBuffer_allocate_data(vbo, nbr);
524
525         fillAttrib(vbo, mat_id, data);
526
527         /* TODO poke mike to add this to gawain */
528         if (shgroup->instance_vbo) {
529                 glDeleteBuffers(1, &shgroup->instance_vbo);
530                 shgroup->instance_vbo = 0;
531         }
532
533         glGenBuffers(1, &shgroup->instance_vbo);
534         glBindBuffer(GL_ARRAY_BUFFER, shgroup->instance_vbo);
535         glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 4 * nbr, data, GL_STATIC_DRAW);
536
537         MEM_freeN(data);
538 }
539
540 static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
541 {
542 #ifdef WITH_VIEWPORT_CACHE_TEST
543         if (shgroup->dyngeom) return;
544 #endif
545         if (shgroup->dyntype == DRW_DYN_INSTANCE) {
546                 shgroup_dynamic_batch_instance(shgroup);
547         }
548         else {
549                 shgroup_dynamic_batch_primitives(shgroup);
550         }
551 }
552
553 /* ***************************************** PASSES ******************************************/
554
555 DRWPass *DRW_pass_create(const char *name, DRWState state)
556 {
557         DRWPass *pass = MEM_callocN(sizeof(DRWPass), name);
558         pass->state = state;
559
560         BLI_listbase_clear(&pass->shgroups);
561
562         return pass;
563 }
564
565 void DRW_pass_free(DRWPass *pass)
566 {
567         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
568                 DRW_shgroup_free(shgroup);
569         }
570         BLI_freelistN(&pass->shgroups);
571 }
572
573 /* TODO this is slow we should not have to use this (better store shgroup pointer somewhere) */
574 DRWShadingGroup *DRW_pass_nth_shgroup_get(DRWPass *pass, int n)
575 {
576         int i = 0;
577         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
578                 if (i == n)
579                         return shgroup;
580                 i++;
581         }
582
583         return NULL;
584 }
585
586 /* ****************************************** DRAW ******************************************/
587
588 void DRW_draw_background(void)
589 {
590         if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
591                 /* Gradient background Color */
592                 gpuMatrixBegin3D(); /* TODO: finish 2D API */
593
594                 glClear(GL_DEPTH_BUFFER_BIT);
595
596                 VertexFormat *format = immVertexFormat();
597                 unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
598                 unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
599                 unsigned char col_hi[3], col_lo[3];
600
601                 immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
602
603                 UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
604                 UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
605
606                 immBegin(GL_QUADS, 4);
607                 immAttrib3ubv(color, col_lo);
608                 immVertex2f(pos, -1.0f, -1.0f);
609                 immVertex2f(pos, 1.0f, -1.0f);
610
611                 immAttrib3ubv(color, col_hi);
612                 immVertex2f(pos, 1.0f, 1.0f);
613                 immVertex2f(pos, -1.0f, 1.0f);
614                 immEnd();
615
616                 immUnbindProgram();
617
618                 gpuMatrixEnd();
619         }
620         else {
621                 /* Solid background Color */
622                 UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
623                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
624         }
625 }
626
627 /* Only alter the state (does not reset it like set_state() ) */
628 static void shgroup_set_state(DRWShadingGroup *shgroup)
629 {
630         if (shgroup->state) {
631                 /* Wire width */
632                 if (shgroup->state & DRW_STATE_WIRE) {
633                         glLineWidth(1.0f);
634                 }
635                 else if (shgroup->state & DRW_STATE_WIRE_LARGE) {
636                         glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
637                 }
638
639                 /* Line Stipple */
640                 if (shgroup->state & DRW_STATE_STIPPLE_2) {
641                         setlinestyle(2);
642                 }
643                 else if (shgroup->state & DRW_STATE_STIPPLE_3) {
644                         setlinestyle(3);
645                 }
646                 else if (shgroup->state & DRW_STATE_STIPPLE_4) {
647                         setlinestyle(4);
648                 }
649         }
650 }
651
652 typedef struct DRWBoundTexture {
653         struct DRWBoundTexture *next, *prev;
654         GPUTexture *tex;
655 } DRWBoundTexture;
656
657 static void draw_geometry(DRWShadingGroup *shgroup, DRWInterface *interface, Batch *geom,
658                           unsigned int instance_vbo, int instance_count, const float (*obmat)[4])
659 {
660         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
661         
662         float mvp[4][4], mv[4][4], n[3][3];
663         float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
664
665         bool do_mvp = (interface->modelviewprojection != -1);
666         bool do_mv = (interface->modelview != -1);
667         bool do_n = (interface->normal != -1);
668         bool do_eye = (interface->eye != -1);
669
670         if (do_mvp) {
671                 mul_m4_m4m4(mvp, rv3d->persmat, obmat);
672         }
673         if (do_mv || do_n || do_eye) {
674                 mul_m4_m4m4(mv, rv3d->viewmat, obmat);
675         }
676         if (do_n || do_eye) {
677                 copy_m3_m4(n, mv);
678                 invert_m3(n);
679                 transpose_m3(n);
680         }
681         if (do_eye) {
682                 /* Used by orthographic wires */
683                 float tmp[3][3];
684                 invert_m3_m3(tmp, n);
685                 /* set eye vector, transformed to object coords */
686                 mul_m3_v3(tmp, eye);
687         }
688
689         /* Should be really simple */
690         /* step 1 : bind object dependent matrices */
691         if (interface->modelviewprojection != -1) {
692                 GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
693         }
694         if (interface->viewprojection != -1) {
695                 GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
696         }
697         if (interface->projection != -1) {
698                 GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat);
699         }
700         if (interface->modelview != -1) {
701                 GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv);
702         }
703         if (interface->normal != -1) {
704                 GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n);
705         }
706         if (interface->eye != -1) {
707                 GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
708         }
709
710         /* step 2 : bind vertex array & draw */
711         Batch_set_program(geom, GPU_shader_get_program(shgroup->shader));
712         if (instance_vbo) {
713                 Batch_draw_stupid_instanced(geom, instance_vbo, instance_count);
714         }
715         else {
716                 Batch_draw_stupid(geom);
717         }
718 }
719
720 static void draw_shgroup(DRWShadingGroup *shgroup)
721 {
722         BLI_assert(shgroup->shader);
723         BLI_assert(shgroup->interface);
724
725         DRWInterface *interface = shgroup->interface;
726
727         if (DST.shader != shgroup->shader) {
728                 if (DST.shader) GPU_shader_unbind();
729                 GPU_shader_bind(shgroup->shader);
730                 DST.shader = shgroup->shader;
731         }
732
733         if (shgroup->dyntype != 0) {
734                 shgroup_dynamic_batch_from_calls(shgroup);
735         }
736
737         shgroup_set_state(shgroup);
738
739         /* Binding Uniform */
740         /* Don't check anything, Interface should already contain the least uniform as possible */
741         for (DRWUniform *uni = interface->uniforms.first; uni; uni = uni->next) {
742                 DRWBoundTexture *bound_tex;
743
744                 switch (uni->type) {
745                         case DRW_UNIFORM_BOOL:
746                         case DRW_UNIFORM_INT:
747                                 GPU_shader_uniform_vector_int(shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->value);
748                                 break;
749                         case DRW_UNIFORM_FLOAT:
750                         case DRW_UNIFORM_MAT3:
751                         case DRW_UNIFORM_MAT4:
752                                 GPU_shader_uniform_vector(shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->value);
753                                 break;
754                         case DRW_UNIFORM_TEXTURE:
755                                 GPU_texture_bind((GPUTexture *)uni->value, uni->bindloc);
756
757                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
758                                 bound_tex->tex = (GPUTexture *)uni->value;
759                                 BLI_addtail(&DST.bound_texs, bound_tex);
760
761                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, (GPUTexture *)uni->value);
762                                 break;
763                         case DRW_UNIFORM_BUFFER:
764                                 /* restore index from lenght we abused */
765                                 GPU_texture_bind(DST.current_txl->textures[uni->length], uni->bindloc);
766                                 GPU_texture_compare_mode(DST.current_txl->textures[uni->length], false);
767                                 GPU_texture_filter_mode(DST.current_txl->textures[uni->length], false);
768                                 
769                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
770                                 bound_tex->tex = DST.current_txl->textures[uni->length];
771                                 BLI_addtail(&DST.bound_texs, bound_tex);
772
773                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, DST.current_txl->textures[uni->length]);
774                                 break;
775                         case DRW_UNIFORM_BLOCK:
776                                 GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
777                                 GPU_shader_uniform_buffer(shgroup->shader, uni->location, (GPUUniformBuffer *)uni->value);
778                                 break;
779                 }
780         }
781
782         /* Rendering Calls */
783         if (shgroup->dyntype != 0) {
784                 /* Replacing multiple calls with only one */
785                 float obmat[4][4];
786                 unit_m4(obmat);
787
788                 if (shgroup->dyntype == DRW_DYN_INSTANCE && shgroup->instance_count > 0) {
789                         DRWCall *call = shgroup->calls.first;
790                         draw_geometry(shgroup, interface, call->geometry, shgroup->instance_vbo, shgroup->instance_count, obmat);
791                 }
792                 else {
793                         /* Some dynamic batch can have no geom (no call to aggregate) */
794                         if (shgroup->dyngeom) {
795                                 draw_geometry(shgroup, interface, shgroup->dyngeom, 0, 1, obmat);
796                         }
797                 }
798         }
799         else {
800                 for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
801                         draw_geometry(shgroup, interface, call->geometry, 0, 1, call->obmat);
802                 }
803         }
804 }
805
806 static void set_state(short flag)
807 {
808         /* TODO Keep track of the state and only revert what is needed */
809
810         /* Depth Write */
811         if (flag & DRW_STATE_WRITE_DEPTH)
812                 glDepthMask(GL_TRUE);
813         else
814                 glDepthMask(GL_FALSE);
815
816         /* Color Write */
817         if (flag & DRW_STATE_WRITE_COLOR)
818                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
819         else
820                 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
821
822         /* Backface Culling */
823         if (flag & DRW_STATE_CULL_BACK ||
824             flag & DRW_STATE_CULL_FRONT) {
825
826                 glEnable(GL_CULL_FACE);
827
828                 if (flag & DRW_STATE_CULL_BACK)
829                         glCullFace(GL_BACK);
830                 else if (flag & DRW_STATE_CULL_FRONT)
831                         glCullFace(GL_FRONT);
832         }
833         else {
834                 glDisable(GL_CULL_FACE);
835         }
836
837         /* Depht Test */
838         if (flag & DRW_STATE_DEPTH_LESS ||
839             flag & DRW_STATE_DEPTH_EQUAL) {
840
841                 glEnable(GL_DEPTH_TEST);
842
843                 if (flag & DRW_STATE_DEPTH_LESS)
844                         glDepthFunc(GL_LEQUAL);
845                 else if (flag & DRW_STATE_DEPTH_EQUAL)
846                         glDepthFunc(GL_EQUAL);
847         }
848         else {
849                 glDisable(GL_DEPTH_TEST);
850         }
851
852         /* Wire Width */
853         if (flag & DRW_STATE_WIRE) {
854                 glLineWidth(1.0f);
855         }
856         else if (flag & DRW_STATE_WIRE_LARGE) {
857                 glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
858         }
859
860         /* Points Size */
861         if (flag & DRW_STATE_POINT) {
862                 GPU_enable_program_point_size();
863                 glPointSize(5.0f);
864         }
865         else {
866                 GPU_disable_program_point_size();
867         }
868
869         /* Blending (all buffer) */
870         if (flag & DRW_STATE_BLEND) {
871                 glEnable(GL_BLEND);
872         }
873         else {
874                 glDisable(GL_BLEND);
875         }
876
877         /* Line Stipple */
878         if (flag & DRW_STATE_STIPPLE_2) {
879                 setlinestyle(2);
880         }
881         else if (flag & DRW_STATE_STIPPLE_3) {
882                 setlinestyle(3);
883         }
884         else if (flag & DRW_STATE_STIPPLE_4) {
885                 setlinestyle(4);
886         }
887         else {
888                 setlinestyle(0);
889         }
890 }
891
892 void DRW_draw_pass(DRWPass *pass)
893 {
894         /* Start fresh */
895         DST.shader = NULL;
896         DST.tex_bind_id = 0;
897
898         set_state(pass->state);
899         BLI_listbase_clear(&DST.bound_texs);
900
901         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
902                 draw_shgroup(shgroup);
903         }
904
905         /* Clear Bound textures */
906         for (DRWBoundTexture *bound_tex = DST.bound_texs.first; bound_tex; bound_tex = bound_tex->next) {
907                 GPU_texture_unbind(bound_tex->tex);
908         }
909         DST.tex_bind_id = 0;
910         BLI_freelistN(&DST.bound_texs);
911
912         if (DST.shader) {
913                 GPU_shader_unbind();
914                 DST.shader = NULL;
915         }
916 }
917
918 /* Reset state to not interfer with other UI drawcall */
919 void DRW_state_reset(void)
920 {
921         DRWState state = 0;
922         state |= DRW_STATE_WRITE_DEPTH;
923         state |= DRW_STATE_WRITE_COLOR;
924         state |= DRW_STATE_DEPTH_LESS;
925         set_state(state);
926 }
927
928 /* ****************************************** Settings ******************************************/
929
930 void *DRW_material_settings_get(Material *ma, const char *engine_name, void ***runtime)
931 {
932         MaterialEngineSettings *ms = NULL;
933
934         ms = BLI_findstring(&ma->engines_settings, engine_name, offsetof(MaterialEngineSettings, name));
935
936         /* If the settings does not exists yet, create it */
937         if (ms == NULL) {
938                 ms = MEM_callocN(sizeof(RenderEngineSettings), "RenderEngineSettings");
939
940                 BLI_strncpy(ms->name, engine_name, 32);
941
942                 /* TODO make render_settings_create a polymorphic function */
943                 if (STREQ(engine_name, RE_engine_id_BLENDER_CLAY)) {
944                         ms->data = CLAY_material_settings_create();
945                 }
946                 else {
947                         /* No engine matched */
948                         BLI_assert(false);
949                 }
950
951                 BLI_addtail(&ma->engines_settings, ms);
952         }
953
954         if (runtime) {
955                 *runtime = &ms->runtime;
956         }
957
958         return ms->data;
959 }
960
961 /* If scene is NULL, use context scene */
962 void *DRW_render_settings_get(Scene *scene, const char *engine_name, void ***runtime)
963 {
964         RenderEngineSettings *rs = NULL;
965
966         if (scene == NULL)
967                 scene = CTX_data_scene(DST.context);
968
969         rs = BLI_findstring(&scene->engines_settings, engine_name, offsetof(RenderEngineSettings, name));
970
971         /* If the settings does not exists yet, create it */
972         if (rs == NULL) {
973                 rs = MEM_callocN(sizeof(RenderEngineSettings), "RenderEngineSettings");
974
975                 BLI_strncpy(rs->name, engine_name, 32);
976
977                 /* TODO make render_settings_create a polymorphic function */
978                 if (STREQ(engine_name, RE_engine_id_BLENDER_CLAY)) {
979                         rs->data = CLAY_render_settings_create();
980                 }
981                 else {
982                         /* No engine matched */
983                         BLI_assert(false);
984                 }
985
986                 BLI_addtail(&scene->engines_settings, rs);
987         }
988
989         if (runtime) {
990                 *runtime = &rs->runtime;
991         }
992
993         return rs->data;
994 }
995
996 /* ****************************************** Framebuffers ******************************************/
997
998 void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX],
999                           int texnbr)
1000 {
1001         if (!*fb) {
1002                 int color_attachment = -1;
1003                 *fb = GPU_framebuffer_create();
1004
1005                 for (int i = 0; i < texnbr; ++i)
1006                 {
1007                         DRWFboTexture fbotex = textures[i];
1008                         
1009                         if (!*fbotex.tex) {
1010                                 /* TODO refine to opengl formats */
1011                                 if (fbotex.format == DRW_BUF_DEPTH_16 ||
1012                                         fbotex.format == DRW_BUF_DEPTH_24) {
1013                                         *fbotex.tex = GPU_texture_create_depth(width, height, NULL);
1014                                         GPU_texture_compare_mode(*fbotex.tex, false);
1015                                         GPU_texture_filter_mode(*fbotex.tex, false);
1016                                 }
1017                                 else {
1018                                         *fbotex.tex = GPU_texture_create_2D(width, height, NULL, NULL);
1019                                         ++color_attachment;
1020                                 }
1021                         }
1022                         
1023                         GPU_framebuffer_texture_attach(*fb, *fbotex.tex, color_attachment);
1024                 }
1025
1026                 if (!GPU_framebuffer_check_valid(*fb, NULL)) {
1027                         printf("Error invalid framebuffer\n");
1028                 }
1029
1030                 GPU_framebuffer_bind(DST.default_framebuffer);
1031         }
1032 }
1033
1034 void DRW_framebuffer_bind(struct GPUFrameBuffer *fb)
1035 {
1036         GPU_framebuffer_bind(fb);
1037 }
1038
1039 void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, GPUTexture *tex, int slot)
1040 {
1041         GPU_framebuffer_texture_attach(fb, tex, slot);
1042 }
1043
1044 void DRW_framebuffer_texture_detach(GPUTexture *tex)
1045 {
1046         GPU_framebuffer_texture_detach(tex);
1047 }
1048
1049 /* ****************************************** Viewport ******************************************/
1050
1051 float *DRW_viewport_size_get(void)
1052 {
1053         return &DST.size[0];
1054 }
1055
1056 void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes)
1057 {
1058         RegionView3D *rv3d = CTX_wm_region_view3d(C);
1059         GPUViewport *viewport = rv3d->viewport;
1060
1061         GPU_viewport_get_engine_data(viewport, buffers, textures, passes);
1062
1063         /* Refresh DST.size */
1064         DefaultTextureList *txl = (DefaultTextureList *)*textures;
1065         DST.size[0] = (float)GPU_texture_width(txl->color);
1066         DST.size[1] = (float)GPU_texture_height(txl->color);
1067
1068         DefaultFramebufferList *fbl = (DefaultFramebufferList *)*buffers;
1069         DST.default_framebuffer = fbl->default_fb;
1070
1071         DST.current_txl = (TextureList *)*textures;
1072         DST.current_fbl = (FramebufferList *)*buffers;
1073         DST.current_psl = (PassList *)*passes;
1074
1075         /* Save context for all later needs */
1076         DST.context = C;
1077 }
1078
1079 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
1080 {
1081         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1082
1083         if (type == DRW_MAT_PERS)
1084                 copy_m4_m4(mat, rv3d->persmat);
1085         else if (type == DRW_MAT_WIEW)
1086                 copy_m4_m4(mat, rv3d->viewmat);
1087         else if (type == DRW_MAT_WIN)
1088                 copy_m4_m4(mat, rv3d->winmat);
1089 }
1090
1091 bool DRW_viewport_is_persp_get(void)
1092 {
1093         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1094         return rv3d->is_persp;
1095 }
1096
1097 bool DRW_viewport_cache_is_dirty(void)
1098 {
1099         /* TODO Use a dirty flag */
1100         return (DST.current_psl->passes[0] == NULL);
1101 }
1102
1103 /* ****************************************** INIT ******************************************/
1104
1105 void DRW_engines_init(void)
1106 {
1107         BLI_addtail(&R_engines, &viewport_clay_type);
1108 }
1109
1110 void DRW_engines_free(void)
1111 {
1112         clay_engine_free();
1113
1114         BLI_remlink(&R_engines, &viewport_clay_type);
1115 }