Workspace: Move engines to workspace and Properties Editor cleanup
[blender.git] / source / blender / draw / engines / external / external_engine.c
1 /*
2  * Copyright 2017, 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 external_engine.c
23  *  \ingroup draw_engine
24  *
25  * Base engine for external render engines.
26  * We use it for depth and non-mesh objects.
27  */
28
29 #include "DRW_render.h"
30
31 #include "DNA_screen_types.h"
32 #include "DNA_view3d_types.h"
33
34 #include "BKE_icons.h"
35 #include "BKE_idprop.h"
36 #include "BKE_main.h"
37
38 #include "ED_view3d.h"
39 #include "ED_screen.h"
40
41 #include "GPU_glew.h"
42 #include "GPU_matrix.h"
43 #include "GPU_shader.h"
44 #include "GPU_viewport.h"
45
46 #include "external_engine.h"
47 /* Shaders */
48
49 #define EXTERNAL_ENGINE "BLENDER_EXTERNAL"
50
51 /* *********** LISTS *********** */
52
53 /* GPUViewport.storage
54  * Is freed everytime the viewport engine changes */
55 typedef struct EXTERNAL_Storage {
56         int dummy;
57 } EXTERNAL_Storage;
58
59 typedef struct EXTERNAL_StorageList {
60         struct EXTERNAL_Storage *storage;
61         struct EXTERNAL_PrivateData *g_data;
62 } EXTERNAL_StorageList;
63
64 typedef struct EXTERNAL_FramebufferList {
65         struct GPUFrameBuffer *default_fb;
66 } EXTERNAL_FramebufferList;
67
68 typedef struct EXTERNAL_TextureList {
69         /* default */
70         struct GPUTexture *depth;
71 } EXTERNAL_TextureList;
72
73 typedef struct EXTERNAL_PassList {
74         struct DRWPass *depth_pass;
75 } EXTERNAL_PassList;
76
77 typedef struct EXTERNAL_Data {
78         void *engine_type;
79         EXTERNAL_FramebufferList *fbl;
80         EXTERNAL_TextureList *txl;
81         EXTERNAL_PassList *psl;
82         EXTERNAL_StorageList *stl;
83         char info[GPU_INFO_SIZE];
84 } EXTERNAL_Data;
85
86 /* *********** STATIC *********** */
87
88 static struct {
89         /* Depth Pre Pass */
90         struct GPUShader *depth_sh;
91 } e_data = {NULL}; /* Engine data */
92
93 typedef struct EXTERNAL_PrivateData {
94         DRWShadingGroup *depth_shgrp;
95 } EXTERNAL_PrivateData; /* Transient data */
96
97 /* Functions */
98
99 static void EXTERNAL_engine_init(void *UNUSED(vedata))
100 {
101         /* Depth prepass */
102         if (!e_data.depth_sh) {
103                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
104         }
105 }
106
107 static void EXTERNAL_cache_init(void *vedata)
108 {
109         EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
110         EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
111
112         if (!stl->g_data) {
113                 /* Alloc transient pointers */
114                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
115         }
116
117         /* Depth Pass */
118         {
119                 psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
120                 stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
121         }
122 }
123
124 static void EXTERNAL_cache_populate(void *vedata, Object *ob)
125 {
126         EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
127
128         if (!DRW_object_is_renderable(ob))
129                 return;
130
131         struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
132         if (geom) {
133                 /* Depth Prepass */
134                 DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
135         }
136 }
137
138 static void EXTERNAL_cache_finish(void *UNUSED(vedata))
139 {
140 }
141
142 static void external_draw_scene(void *vedata)
143 {
144         const DRWContextState *draw_ctx = DRW_context_state_get();
145         Scene *scene = draw_ctx->scene;
146         RegionView3D *rv3d = draw_ctx->rv3d;
147         ARegion *ar = draw_ctx->ar;
148         RenderEngineType *type;
149
150         DRW_state_reset_ex(DRW_STATE_DEFAULT & ~DRW_STATE_DEPTH_LESS);
151
152         /* Create render engine. */
153         if (!rv3d->render_engine) {
154                 RenderEngineType *engine_type = draw_ctx->engine;
155
156                 if (!(engine_type->view_update && engine_type->render_to_view)) {
157                         return;
158                 }
159
160                 RenderEngine *engine = RE_engine_create_ex(engine_type, true);
161                 engine->tile_x = scene->r.tilex;
162                 engine->tile_y = scene->r.tiley;
163                 engine_type->view_update(engine, draw_ctx->evil_C);
164                 rv3d->render_engine = engine;
165         }
166
167         /* Rendered draw. */
168         gpuPushProjectionMatrix();
169         ED_region_pixelspace(ar);
170
171         /* Render result draw. */
172         type = rv3d->render_engine->type;
173         type->render_to_view(rv3d->render_engine, draw_ctx->evil_C);
174
175         gpuPopProjectionMatrix();
176
177         /* Set render info. */
178         EXTERNAL_Data *data = vedata;
179         if (rv3d->render_engine->text[0] != '\0') {
180                 BLI_strncpy(data->info, rv3d->render_engine->text, sizeof(data->info));
181         }
182         else {
183                 data->info[0] = '\0';
184         }
185 }
186
187 static void EXTERNAL_draw_scene(void *vedata)
188 {
189         const DRWContextState *draw_ctx = DRW_context_state_get();
190         EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
191
192         /* Will be NULL during OpenGL render.
193          * OpenGL render is used for quick preview (thumbnails or sequencer preview)
194          * where using the rendering engine to preview doesn't make so much sense. */
195         if (draw_ctx->evil_C) {
196                 external_draw_scene(vedata);
197         }
198         DRW_draw_pass(psl->depth_pass);
199 }
200
201 static void EXTERNAL_engine_free(void)
202 {
203         /* All shaders are builtin. */
204 }
205
206 static const DrawEngineDataSize EXTERNAL_data_size = DRW_VIEWPORT_DATA_SIZE(EXTERNAL_Data);
207
208 DrawEngineType draw_engine_external_type = {
209         NULL, NULL,
210         N_("External"),
211         &EXTERNAL_data_size,
212         &EXTERNAL_engine_init,
213         &EXTERNAL_engine_free,
214         &EXTERNAL_cache_init,
215         &EXTERNAL_cache_populate,
216         &EXTERNAL_cache_finish,
217         NULL,
218         &EXTERNAL_draw_scene,
219         NULL,
220 };
221
222 /* Note: currently unused, we should not register unless we want to see this when debugging the view. */
223
224 RenderEngineType DRW_engine_viewport_external_type = {
225         NULL, NULL,
226         EXTERNAL_ENGINE, N_("External"), RE_INTERNAL,
227         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
228         &draw_engine_external_type,
229         {NULL, NULL, NULL}
230 };
231
232 #undef EXTERNAL_ENGINE