Cleanup: style, duplicate header
[blender.git] / source / blender / draw / engines / basic / basic_engine.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 basic_engine.c
23  *  \ingroup draw_engine
24  *
25  * Simple engine for drawing color and/or depth.
26  * When we only need simple flat shaders.
27  */
28
29 #include "DRW_render.h"
30
31 #include "BKE_icons.h"
32 #include "BKE_idprop.h"
33 #include "BKE_main.h"
34 #include "BKE_particle.h"
35
36 #include "DNA_particle_types.h"
37
38 #include "GPU_shader.h"
39
40 #include "basic_engine.h"
41 /* Shaders */
42
43 #define BASIC_ENGINE "BLENDER_BASIC"
44
45 /* we may want this later? */
46 #define USE_DEPTH
47
48 /* *********** LISTS *********** */
49
50 /* GPUViewport.storage
51  * Is freed everytime the viewport engine changes */
52 typedef struct BASIC_StorageList {
53         struct BASIC_PrivateData *g_data;
54 } BASIC_StorageList;
55
56 typedef struct BASIC_PassList {
57 #ifdef USE_DEPTH
58         struct DRWPass *depth_pass;
59         struct DRWPass *depth_pass_cull;
60 #endif
61         struct DRWPass *color_pass;
62 } BASIC_PassList;
63
64 typedef struct BASIC_Data {
65         void *engine_type;
66         DRWViewportEmptyList *fbl;
67         DRWViewportEmptyList *txl;
68         BASIC_PassList *psl;
69         BASIC_StorageList *stl;
70 } BASIC_Data;
71
72 /* *********** STATIC *********** */
73
74 static struct {
75 #ifdef USE_DEPTH
76         /* Depth Pre Pass */
77         struct GPUShader *depth_sh;
78 #endif
79         /* Shading Pass */
80         struct GPUShader *color_sh;
81 } e_data = {NULL}; /* Engine data */
82
83 typedef struct BASIC_PrivateData {
84 #ifdef USE_DEPTH
85         DRWShadingGroup *depth_shgrp;
86         DRWShadingGroup *depth_shgrp_cull;
87         DRWShadingGroup *depth_shgrp_hair;
88 #endif
89         DRWShadingGroup *color_shgrp;
90 } BASIC_PrivateData; /* Transient data */
91
92 /* Functions */
93
94 static void basic_engine_init(void *UNUSED(vedata))
95 {
96 #ifdef USE_DEPTH
97         /* Depth prepass */
98         if (!e_data.depth_sh) {
99                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
100         }
101 #endif
102
103         /* Shading pass */
104         if (!e_data.color_sh) {
105                 e_data.color_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
106         }
107 }
108
109 static void basic_cache_init(void *vedata)
110 {
111         BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
112         BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
113
114         if (!stl->g_data) {
115                 /* Alloc transient pointers */
116                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
117         }
118
119 #ifdef USE_DEPTH
120         /* Depth Pass */
121         {
122                 psl->depth_pass = DRW_pass_create(
123                         "Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
124                 stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
125
126                 psl->depth_pass_cull = DRW_pass_create(
127                         "Depth Pass Cull",
128                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
129                 stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
130         }
131 #endif
132
133         /* Color Pass */
134         {
135                 psl->color_pass = DRW_pass_create("Color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
136                 stl->g_data->color_shgrp = DRW_shgroup_create(e_data.color_sh, psl->color_pass);
137         }
138 }
139
140 static void basic_cache_populate(void *vedata, Object *ob)
141 {
142         BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
143
144         if (!DRW_object_is_renderable(ob)) {
145                 return;
146         }
147
148         const DRWContextState *draw_ctx = DRW_context_state_get();
149         if (ob != draw_ctx->object_edit) {
150                 for (ParticleSystem *psys = ob->particlesystem.first;
151                      psys != NULL;
152                      psys = psys->next)
153                 {
154                         if (!psys_check_enabled(ob, psys, false)) {
155                                 continue;
156                         }
157                         if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
158                                 continue;
159                         }
160                         ParticleSettings *part = psys->part;
161                         const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
162                         if (draw_as == PART_DRAW_PATH) {
163                                 struct Gwn_Batch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
164                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp, hairs, NULL);
165                         }
166                 }
167         }
168
169         struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
170         if (geom) {
171                 bool do_cull = false;  /* TODO (we probably wan't to take this from the viewport?) */
172 #ifdef USE_DEPTH
173                 /* Depth Prepass */
174                 DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat);
175 #endif
176                 /* Shading */
177                 DRW_shgroup_call_add(stl->g_data->color_shgrp, geom, ob->obmat);
178         }
179 }
180
181 static void basic_cache_finish(void *vedata)
182 {
183         BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
184
185         UNUSED_VARS(stl);
186 }
187
188 static void basic_draw_scene(void *vedata)
189 {
190
191         BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
192         const bool is_select = DRW_state_is_select();
193
194         bool use_color = true;
195         bool use_depth = true;
196         bool use_depth_cull = true;
197
198         if (is_select) {
199                 /* Needed for depth-picking,
200                  * for other selection types there are no need for extra passes either. */
201                 use_color = false;
202                 use_depth_cull = false;
203         }
204
205 #ifdef USE_DEPTH
206         /* Pass 1 : Depth pre-pass */
207         if (use_depth) {
208                 DRW_draw_pass(psl->depth_pass);
209         }
210
211         if (use_depth_cull) {
212                 DRW_draw_pass(psl->depth_pass_cull);
213         }
214 #endif
215
216         /* Pass 3 : Shading */
217         if (use_color) {
218                 DRW_draw_pass(psl->color_pass);
219         }
220 }
221
222 static void basic_engine_free(void)
223 {
224         /* all shaders are builtin */
225 }
226
227 static const DrawEngineDataSize basic_data_size = DRW_VIEWPORT_DATA_SIZE(BASIC_Data);
228
229 DrawEngineType draw_engine_basic_type = {
230         NULL, NULL,
231         N_("Basic"),
232         &basic_data_size,
233         &basic_engine_init,
234         &basic_engine_free,
235         &basic_cache_init,
236         &basic_cache_populate,
237         &basic_cache_finish,
238         NULL,
239         &basic_draw_scene,
240         NULL,
241         NULL,
242         NULL,
243 };
244
245 /* Note: currently unused, we may want to register so we can see this when debugging the view. */
246
247 RenderEngineType DRW_engine_viewport_basic_type = {
248         NULL, NULL,
249         BASIC_ENGINE, N_("Basic"), RE_INTERNAL,
250         NULL, NULL, NULL, NULL, NULL, NULL, NULL,
251         &draw_engine_basic_type,
252         {NULL, NULL, NULL}
253 };
254
255
256 #undef BASIC_ENGINE