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