Blender  V2.93
external_engine.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2017, Blender Foundation.
17  */
18 
26 #include "DRW_render.h"
27 
28 #include "DNA_modifier_types.h"
29 #include "DNA_screen_types.h"
30 #include "DNA_view3d_types.h"
31 
32 #include "BKE_object.h"
33 #include "BKE_particle.h"
34 
35 #include "ED_screen.h"
36 
37 #include "GPU_matrix.h"
38 #include "GPU_shader.h"
39 #include "GPU_state.h"
40 #include "GPU_viewport.h"
41 
42 #include "external_engine.h" /* own include */
43 
44 /* Shaders */
45 
46 #define EXTERNAL_ENGINE "BLENDER_EXTERNAL"
47 
48 extern char datatoc_depth_frag_glsl[];
49 extern char datatoc_depth_vert_glsl[];
50 
51 extern char datatoc_common_view_lib_glsl[];
52 
53 /* *********** LISTS *********** */
54 
55 /* GPUViewport.storage
56  * Is freed every time the viewport engine changes. */
57 typedef struct EXTERNAL_Storage {
58  int dummy;
60 
61 typedef struct EXTERNAL_StorageList {
65 
66 typedef struct EXTERNAL_FramebufferList {
69 
70 typedef struct EXTERNAL_TextureList {
71  /* default */
74 
75 typedef struct EXTERNAL_PassList {
78 
79 typedef struct EXTERNAL_Data {
80  void *engine_type;
85  char info[GPU_INFO_SIZE];
87 
88 /* *********** STATIC *********** */
89 
90 static struct {
91  /* Depth Pre Pass */
93 } e_data = {NULL}; /* Engine data */
94 
95 typedef struct EXTERNAL_PrivateData {
97 
98  /* Do we need to update the depth or can we reuse the last calculated texture. */
99  bool need_depth;
101 } EXTERNAL_PrivateData; /* Transient data */
102 
103 /* Functions */
104 
105 static void external_engine_init(void *vedata)
106 {
107  EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
108  const DRWContextState *draw_ctx = DRW_context_state_get();
109  ARegion *region = draw_ctx->region;
110 
111  /* Depth pre-pass. */
112  if (!e_data.depth_sh) {
114 
116  .vert = (const char *[]){sh_cfg->lib,
119  NULL},
120  .frag = (const char *[]){datatoc_depth_frag_glsl, NULL},
121  .defs = (const char *[]){sh_cfg->def, NULL},
122  });
123  }
124 
125  if (!stl->g_data) {
126  /* Alloc transient pointers */
127  stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
128  stl->g_data->need_depth = true;
129  }
130 
131  stl->g_data->update_depth = true;
132 
133  /* Progressive render samples are tagged with no rebuild, in that case we
134  * can skip updating the depth buffer */
135  if (region && (region->do_draw & RGN_DRAW_NO_REBUILD)) {
136  stl->g_data->update_depth = false;
137  }
138 }
139 
140 static void external_cache_init(void *vedata)
141 {
142  EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
143  EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
144  EXTERNAL_TextureList *txl = ((EXTERNAL_Data *)vedata)->txl;
145  EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
146  const DRWContextState *draw_ctx = DRW_context_state_get();
147  const View3D *v3d = draw_ctx->v3d;
148 
149  {
151 
152  GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb,
153  {
154  GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
155  });
156  }
157 
158  /* Depth Pass */
159  {
160  psl->depth_pass = DRW_pass_create("Depth Pass",
162  stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
163  }
164 
165  /* Do not draw depth pass when overlays are turned off. */
166  stl->g_data->need_depth = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
167 }
168 
169 static void external_cache_populate(void *vedata, Object *ob)
170 {
171  EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
172 
173  if (!(DRW_object_is_renderable(ob) &&
175  return;
176  }
177 
178  if (ob->type == OB_GPENCIL) {
179  /* Grease Pencil objects need correct depth to do the blending. */
180  stl->g_data->need_depth = true;
181  return;
182  }
183 
184  if (ob->type == OB_MESH && ob->modifiers.first != NULL) {
185  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
186  if (md->type != eModifierType_ParticleSystem) {
187  continue;
188  }
189  ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
191  continue;
192  }
193  ParticleSettings *part = psys->part;
194  const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
195 
196  if (draw_as == PART_DRAW_PATH) {
197  struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
198  DRW_shgroup_call(stl->g_data->depth_shgrp, hairs, NULL);
199  }
200  }
201  }
202  struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
203  if (geom) {
204  /* Depth Prepass */
205  DRW_shgroup_call(stl->g_data->depth_shgrp, geom, ob);
206  }
207 }
208 
209 static void external_cache_finish(void *UNUSED(vedata))
210 {
211 }
212 
213 static void external_draw_scene_do(void *vedata)
214 {
215  const DRWContextState *draw_ctx = DRW_context_state_get();
216  Scene *scene = draw_ctx->scene;
217  RegionView3D *rv3d = draw_ctx->rv3d;
218  ARegion *region = draw_ctx->region;
219  const RenderEngineType *type;
220 
222 
223  /* Create render engine. */
224  if (!rv3d->render_engine) {
225  RenderEngineType *engine_type = draw_ctx->engine_type;
226 
227  if (!(engine_type->view_update && engine_type->view_draw)) {
228  return;
229  }
230 
231  RenderEngine *engine = RE_engine_create(engine_type);
232  engine->tile_x = scene->r.tilex;
233  engine->tile_y = scene->r.tiley;
234  engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
235  rv3d->render_engine = engine;
236  }
237 
238  /* Rendered draw. */
240  GPU_matrix_push();
241  ED_region_pixelspace(region);
242 
243  /* Render result draw. */
244  type = rv3d->render_engine->type;
245  type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
246 
247  GPU_bgl_end();
248 
249  GPU_matrix_pop();
251 
252  /* Set render info. */
253  EXTERNAL_Data *data = vedata;
254  if (rv3d->render_engine->text[0] != '\0') {
255  BLI_strncpy(data->info, rv3d->render_engine->text, sizeof(data->info));
256  }
257  else {
258  data->info[0] = '\0';
259  }
260 }
261 
262 static void external_draw_scene(void *vedata)
263 {
264  const DRWContextState *draw_ctx = DRW_context_state_get();
265  EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
266  EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
267  EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
269 
270  /* Will be NULL during OpenGL render.
271  * OpenGL render is used for quick preview (thumbnails or sequencer preview)
272  * where using the rendering engine to preview doesn't make so much sense. */
273  if (draw_ctx->evil_C) {
274  const float clear_col[4] = {0, 0, 0, 0};
275  /* This is to keep compatibility with external engine. */
276  /* TODO(fclem): remove it eventually. */
278  GPU_framebuffer_clear_color(dfbl->default_fb, clear_col);
279 
280  external_draw_scene_do(vedata);
281  }
282 
283  if (stl->g_data->update_depth && stl->g_data->need_depth) {
285  /* Copy main depth buffer to cached framebuffer. */
287  }
288 
289  /* Copy cached depth buffer to main framebuffer. */
291 }
292 
293 static void external_engine_free(void)
294 {
295  DRW_SHADER_FREE_SAFE(e_data.depth_sh);
296 }
297 
299 
301  NULL,
302  NULL,
303  N_("External"),
311  NULL,
312  NULL,
313  NULL,
314  NULL,
315 };
316 
317 /* Note: currently unused,
318  * we should not register unless we want to see this when debugging the view. */
319 
321  NULL,
322  NULL,
324  N_("External"),
326  NULL,
327  NULL,
328  NULL,
329  NULL,
330  NULL,
331  NULL,
332  NULL,
334  {NULL, NULL, NULL},
335 };
336 
337 #undef EXTERNAL_ENGINE
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define N_(msgid)
@ eModifierType_ParticleSystem
@ OB_MESH
@ OB_GPENCIL
#define PART_DRAW_PATH
#define PART_DRAW_REND
@ RGN_DRAW_NO_REBUILD
#define V3D_HIDE_OVERLAYS
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
#define DRW_SHADER_FREE_SAFE(shader)
Definition: DRW_render.h:279
#define DRW_STATE_DEFAULT
Definition: DRW_render.h:360
#define DRW_VIEWPORT_DATA_SIZE(ty)
Definition: DRW_render.h:97
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
void ED_region_pixelspace(struct ARegion *region)
Definition: area.c:137
GPUBatch
Definition: GPU_batch.h:93
struct GPUFrameBuffer GPUFrameBuffer
@ GPU_DEPTH_BIT
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:156
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:149
struct GPUShader GPUShader
Definition: GPU_shader.h:33
@ GPU_SHADER_CFG_DEFAULT
Definition: GPU_shader.h:392
const GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN]
#define GPU_shader_create_from_arrays(...)
Definition: GPU_shader.h:69
void GPU_bgl_end(void)
Definition: gpu_state.cc:367
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:121
#define RE_USE_STEREO_VIEWPORT
Definition: RE_engine.h:65
#define RE_INTERNAL
Definition: RE_engine.h:57
Scene scene
GPUBatch * DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
Definition: draw_cache.c:3332
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:886
DefaultFramebufferList * DRW_viewport_framebuffer_list_get(void)
Definition: draw_manager.c:697
bool DRW_object_is_renderable(const Object *ob)
Definition: draw_manager.c:183
int DRW_object_visibility_in_active_context(const Object *ob)
Definition: draw_manager.c:235
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:271
const DRWContextState * DRW_context_state_get(void)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
DRWPass * DRW_pass_create(const char *name, DRWState state)
void DRW_draw_pass(DRWPass *pass)
void DRW_state_reset_ex(DRWState state)
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex, eGPUTextureFormat format, DRWTextureFlag flags)
RenderEngine * RE_engine_create(RenderEngineType *type)
Definition: engine.c:133
static void external_cache_populate(void *vedata, Object *ob)
RenderEngineType DRW_engine_viewport_external_type
struct EXTERNAL_FramebufferList EXTERNAL_FramebufferList
struct EXTERNAL_StorageList EXTERNAL_StorageList
struct EXTERNAL_PassList EXTERNAL_PassList
struct EXTERNAL_Storage EXTERNAL_Storage
static void external_draw_scene(void *vedata)
char datatoc_common_view_lib_glsl[]
static DrawEngineType draw_engine_external_type
static void external_engine_init(void *vedata)
static struct @208 e_data
static void external_cache_finish(void *UNUSED(vedata))
struct EXTERNAL_TextureList EXTERNAL_TextureList
struct GPUShader * depth_sh
static void external_engine_free(void)
struct EXTERNAL_Data EXTERNAL_Data
char datatoc_depth_vert_glsl[]
struct EXTERNAL_PrivateData EXTERNAL_PrivateData
#define EXTERNAL_ENGINE
static const DrawEngineDataSize external_data_size
char datatoc_depth_frag_glsl[]
static void external_draw_scene_do(void *vedata)
static void external_cache_init(void *vedata)
void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, int read_slot, GPUFrameBuffer *gpufb_write, int write_slot, eGPUFrameBufferBits blit_buffers)
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
struct Scene * scene
Definition: DRW_render.h:745
const struct bContext * evil_C
Definition: DRW_render.h:763
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct View3D * v3d
Definition: DRW_render.h:742
struct ARegion * region
Definition: DRW_render.h:740
struct RenderEngineType * engine_type
Definition: DRW_render.h:751
struct RegionView3D * rv3d
Definition: DRW_render.h:741
struct GPUFrameBuffer * depth_only_fb
struct GPUFrameBuffer * default_fb
EXTERNAL_FramebufferList * fbl
char info[GPU_INFO_SIZE]
EXTERNAL_StorageList * stl
EXTERNAL_PassList * psl
EXTERNAL_TextureList * txl
struct GPUFrameBuffer * depth_buffer_fb
struct DRWPass * depth_pass
DRWShadingGroup * depth_shgrp
struct EXTERNAL_PrivateData * g_data
struct EXTERNAL_Storage * storage
struct GPUTexture * depth_buffer_tx
const char * lib
Definition: GPU_shader.h:398
const char * def
Definition: GPU_shader.h:399
void * first
Definition: DNA_listBase.h:47
ListBase modifiers
ParticleSettings * part
struct RenderEngine * render_engine
void(* view_draw)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition: RE_engine.h:100
void(* view_update)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition: RE_engine.h:97
RenderEngineType * type
Definition: RE_engine.h:126
char text[512]
Definition: RE_engine.h:138
struct RenderData r