ddcec29cd2197d55afb035c670a19adc74487cfc
[blender.git] / source / blender / draw / engines / workbench / workbench_private.h
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 workbench_private.h
23  *  \ingroup draw_engine
24  */
25
26 #ifndef __WORKBENCH_PRIVATE_H__
27 #define __WORKBENCH_PRIVATE_H__
28
29
30 #include "BKE_studiolight.h"
31
32 #include "DNA_image_types.h"
33 #include "DNA_view3d_types.h"
34 #include "DNA_world_types.h"
35
36 #include "DRW_render.h"
37
38
39 #define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
40 #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
41 #define MAX_SHADERS (1 << 10)
42
43
44 #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
45 #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
46 #define SPECULAR_HIGHLIGHT_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT)
47 #define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED        (wpd))
48 #define NORMAL_ENCODING_ENABLED() (true)
49 #define WORKBENCH_REVEALAGE_ENABLED
50 #define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD)
51 #define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA)
52
53
54 typedef struct WORKBENCH_FramebufferList {
55         /* Deferred render buffers */
56         struct GPUFrameBuffer *prepass_fb;
57         struct GPUFrameBuffer *composite_fb;
58
59         /* Forward render buffers */
60         struct GPUFrameBuffer *object_outline_fb;
61         struct GPUFrameBuffer *transparent_accum_fb;
62
63 #ifdef WORKBENCH_REVEALAGE_ENABLED
64         struct GPUFrameBuffer *transparent_revealage_fb;
65 #endif
66 } WORKBENCH_FramebufferList;
67
68 typedef struct WORKBENCH_StorageList {
69         struct WORKBENCH_PrivateData *g_data;
70 } WORKBENCH_StorageList;
71
72 typedef struct WORKBENCH_PassList {
73         /* deferred rendering */
74         struct DRWPass *prepass_pass;
75         struct DRWPass *prepass_hair_pass;
76         struct DRWPass *shadow_depth_pass_pass;
77         struct DRWPass *shadow_depth_pass_mani_pass;
78         struct DRWPass *shadow_depth_fail_pass;
79         struct DRWPass *shadow_depth_fail_mani_pass;
80         struct DRWPass *shadow_depth_fail_caps_pass;
81         struct DRWPass *shadow_depth_fail_caps_mani_pass;
82         struct DRWPass *composite_pass;
83         struct DRWPass *composite_shadow_pass;
84
85         /* forward rendering */
86         struct DRWPass *transparent_accum_pass;
87 #ifdef WORKBENCH_REVEALAGE_ENABLED
88         struct DRWPass *transparent_revealage_pass;
89 #endif
90         struct DRWPass *object_outline_pass;
91         struct DRWPass *depth_pass;
92         struct DRWPass *checker_depth_pass;
93 } WORKBENCH_PassList;
94
95 typedef struct WORKBENCH_Data {
96         void *engine_type;
97         WORKBENCH_FramebufferList *fbl;
98         DRWViewportEmptyList *txl;
99         WORKBENCH_PassList *psl;
100         WORKBENCH_StorageList *stl;
101 } WORKBENCH_Data;
102
103 typedef struct WORKBENCH_UBO_Light {
104         float light_direction_vs[4];
105         float specular_color[3];
106         float energy;
107 } WORKBENCH_UBO_Light;
108
109 typedef struct WORKBENCH_UBO_World {
110         float diffuse_light_x_pos[4];
111         float diffuse_light_x_neg[4];
112         float diffuse_light_y_pos[4];
113         float diffuse_light_y_neg[4];
114         float diffuse_light_z_pos[4];
115         float diffuse_light_z_neg[4];
116         float background_color_low[4];
117         float background_color_high[4];
118         float object_outline_color[4];
119         float light_direction_vs[4];
120         WORKBENCH_UBO_Light lights[3];
121         int num_lights;
122         int pad[3];
123 } WORKBENCH_UBO_World;
124 BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
125
126 typedef struct WORKBENCH_UBO_Material {
127         float diffuse_color[4];
128         float specular_color[4];
129         float roughness;
130         float pad[3];
131 } WORKBENCH_UBO_Material;
132 BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_Material, 16)
133
134 typedef struct WORKBENCH_PrivateData {
135         struct GHash *material_hash;
136         struct GPUShader *prepass_solid_sh;
137         struct GPUShader *prepass_solid_hair_sh;
138         struct GPUShader *prepass_texture_sh;
139         struct GPUShader *prepass_texture_hair_sh;
140         struct GPUShader *composite_sh;
141         struct GPUShader *transparent_accum_sh;
142         struct GPUShader *transparent_accum_hair_sh;
143         struct GPUShader *transparent_accum_texture_sh;
144         struct GPUShader *transparent_accum_texture_hair_sh;
145         View3DShading shading;
146         StudioLight *studio_light;
147         int drawtype;
148         struct GPUUniformBuffer *world_ubo;
149         struct DRWShadingGroup *shadow_shgrp;
150         struct DRWShadingGroup *depth_shgrp;
151 #ifdef WORKBENCH_REVEALAGE_ENABLED
152         struct DRWShadingGroup *transparent_revealage_shgrp;
153 #endif
154         WORKBENCH_UBO_World world_data;
155         float shadow_multiplier;
156         float cached_shadow_direction[3];
157         float shadow_mat[4][4];
158         float shadow_inv[4][4];
159         float shadow_near_corners[4][3]; /* Near plane corners in shadow space. */
160         float shadow_near_min[3]; /* min and max of shadow_near_corners. allow fast test */
161         float shadow_near_max[3];
162         float shadow_near_sides[2][4]; /* This is a parallelogram, so only 2 normal and distance to the edges. */
163         bool shadow_changed;
164 } WORKBENCH_PrivateData; /* Transient data */
165
166 typedef struct WORKBENCH_MaterialData {
167         /* Solid color */
168         WORKBENCH_UBO_Material material_data;
169         struct GPUUniformBuffer *material_ubo;
170
171         int object_id;
172         int drawtype;
173         Image *ima;
174
175         /* Linked shgroup for drawing */
176         DRWShadingGroup *shgrp;
177         /* forward rendering */
178         DRWShadingGroup *shgrp_object_outline;
179 } WORKBENCH_MaterialData;
180
181 typedef struct WORKBENCH_ObjectData {
182         struct ObjectEngineData *next, *prev;
183         struct DrawEngineType *engine_type;
184         /* Only nested data, NOT the engine data itself. */
185         ObjectEngineDataFreeCb free;
186         /* Accumulated recalc flags, which corresponds to ID->recalc flags. */
187         int recalc;
188         /* Shadow direction in local object space. */
189         float shadow_dir[3];
190         float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */
191         BoundBox shadow_bbox;
192         bool shadow_bbox_dirty;
193
194         int object_id;
195 } WORKBENCH_ObjectData;
196
197 /* workbench_engine.c */
198 void workbench_solid_materials_init(WORKBENCH_Data *vedata);
199 void workbench_solid_materials_cache_init(WORKBENCH_Data *vedata);
200 void workbench_solid_materials_cache_populate(WORKBENCH_Data *vedata, Object *ob);
201 void workbench_solid_materials_cache_finish(WORKBENCH_Data *vedata);
202 void workbench_solid_materials_draw_scene(WORKBENCH_Data *vedata);
203 void workbench_solid_materials_free(void);
204
205 /* workbench_deferred.c */
206 void workbench_deferred_engine_init(WORKBENCH_Data *vedata);
207 void workbench_deferred_engine_free(void);
208 void workbench_deferred_draw_background(WORKBENCH_Data *vedata);
209 void workbench_deferred_draw_scene(WORKBENCH_Data *vedata);
210 void workbench_deferred_cache_init(WORKBENCH_Data *vedata);
211 void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob);
212 void workbench_deferred_cache_finish(WORKBENCH_Data *vedata);
213
214 /* workbench_forward.c */
215 void workbench_forward_engine_init(WORKBENCH_Data *vedata);
216 void workbench_forward_engine_free(void);
217 void workbench_forward_draw_background(WORKBENCH_Data *vedata);
218 void workbench_forward_draw_scene(WORKBENCH_Data *vedata);
219 void workbench_forward_cache_init(WORKBENCH_Data *vedata);
220 void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob);
221 void workbench_forward_cache_finish(WORKBENCH_Data *vedata);
222
223 /* workbench_materials.c */
224 char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair);
225 void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data);
226 uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template);
227 int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair);
228 void workbench_material_set_normal_world_matrix(
229         DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3]);
230
231 /* workbench_studiolight.c */
232 void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd);
233 void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3]);
234 bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
235 bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
236
237 /* workbench_data.c */
238 void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
239 void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
240 void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3]);
241
242 extern DrawEngineType draw_engine_workbench_solid;
243 extern DrawEngineType draw_engine_workbench_transparent;
244
245 #endif