Merge branch 'blender-v2.81-release'
[blender.git] / source / blender / draw / intern / draw_view.c
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 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw
21  *
22  * Contains dynamic drawing using immediate mode
23  */
24
25 #include "DNA_brush_types.h"
26 #include "DNA_screen_types.h"
27 #include "DNA_userdef_types.h"
28 #include "DNA_view3d_types.h"
29
30 #include "ED_screen.h"
31 #include "ED_view3d.h"
32
33 #include "GPU_shader.h"
34 #include "GPU_immediate.h"
35 #include "GPU_matrix.h"
36
37 #include "UI_resources.h"
38
39 #include "WM_types.h"
40
41 #include "BKE_object.h"
42 #include "BKE_paint.h"
43
44 #include "view3d_intern.h"
45
46 #include "draw_manager.h"
47
48 /* ******************** region info ***************** */
49
50 void DRW_draw_region_info(void)
51 {
52   const DRWContextState *draw_ctx = DRW_context_state_get();
53   ARegion *ar = draw_ctx->ar;
54
55   DRW_draw_cursor();
56
57   view3d_draw_region_info(draw_ctx->evil_C, ar);
58 }
59
60 /* ************************* Background ************************** */
61 void DRW_clear_background()
62 {
63   GPU_clear_color(0.0, 0.0, 0.0, 0.0);
64   GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT);
65 }
66
67 void DRW_draw_background(bool do_alpha_checker)
68 {
69   drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL);
70   if (do_alpha_checker) {
71     /* Transparent render, do alpha checker. */
72     GPU_matrix_push();
73     GPU_matrix_identity_set();
74     GPU_matrix_identity_projection_set();
75
76     imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f);
77
78     GPU_matrix_pop();
79   }
80   else {
81     float m[4][4];
82     unit_m4(m);
83
84     GPUVertFormat *format = immVertexFormat();
85     uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
86     uint color = GPU_vertformat_attr_add(
87         format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
88     uchar col_hi[3], col_lo[3];
89
90     GPU_matrix_push();
91     GPU_matrix_identity_set();
92     GPU_matrix_projection_set(m);
93
94     immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER);
95
96     UI_GetThemeColor3ubv(TH_BACK, col_hi);
97     UI_GetThemeColor3ubv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, col_lo);
98
99     immBegin(GPU_PRIM_TRI_FAN, 4);
100     immAttr3ubv(color, col_lo);
101     immVertex2f(pos, -1.0f, -1.0f);
102     immVertex2f(pos, 1.0f, -1.0f);
103
104     immAttr3ubv(color, col_hi);
105     immVertex2f(pos, 1.0f, 1.0f);
106     immVertex2f(pos, -1.0f, 1.0f);
107     immEnd();
108
109     immUnbindProgram();
110
111     GPU_matrix_pop();
112   }
113 }
114
115 GPUBatch *DRW_draw_background_clipping_batch_from_rv3d(const RegionView3D *rv3d)
116 {
117   const BoundBox *bb = rv3d->clipbb;
118   const uint clipping_index[6][4] = {
119       {0, 1, 2, 3},
120       {0, 4, 5, 1},
121       {4, 7, 6, 5},
122       {7, 3, 2, 6},
123       {1, 5, 6, 2},
124       {7, 4, 0, 3},
125   };
126   GPUVertBuf *vbo;
127   GPUIndexBuf *el;
128   GPUIndexBufBuilder elb = {0};
129
130   /* Elements */
131   GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, ARRAY_SIZE(clipping_index) * 2, ARRAY_SIZE(bb->vec));
132   for (int i = 0; i < ARRAY_SIZE(clipping_index); i++) {
133     const uint *idx = clipping_index[i];
134     GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
135     GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]);
136   }
137   el = GPU_indexbuf_build(&elb);
138
139   GPUVertFormat format = {0};
140   uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
141
142   vbo = GPU_vertbuf_create_with_format(&format);
143   GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bb->vec));
144   GPU_vertbuf_attr_fill(vbo, pos_id, bb->vec);
145
146   return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, el, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
147 }
148
149 /* **************************** 3D Cursor ******************************** */
150
151 static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer)
152 {
153   View3D *v3d = draw_ctx->v3d;
154   if ((v3d->flag2 & V3D_HIDE_OVERLAYS) || (v3d->overlay.flag & V3D_OVERLAY_HIDE_CURSOR)) {
155     return false;
156   }
157
158   /* don't draw cursor in paint modes, but with a few exceptions */
159   if (draw_ctx->object_mode & OB_MODE_ALL_PAINT) {
160     /* exception: object is in weight paint and has deforming armature in pose mode */
161     if (draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
162       if (BKE_object_pose_armature_get(draw_ctx->obact) != NULL) {
163         return true;
164       }
165     }
166     /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
167     else if (draw_ctx->object_mode & OB_MODE_TEXTURE_PAINT) {
168       const Paint *p = BKE_paint_get_active(scene, view_layer);
169
170       if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
171         if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
172           return true;
173         }
174       }
175     }
176
177     /* no exception met? then don't draw cursor! */
178     return false;
179   }
180   else if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) {
181     /* grease pencil hide always in some modes */
182     return false;
183   }
184
185   return true;
186 }
187
188 void DRW_draw_cursor(void)
189 {
190   const DRWContextState *draw_ctx = DRW_context_state_get();
191   ARegion *ar = draw_ctx->ar;
192   Scene *scene = draw_ctx->scene;
193   ViewLayer *view_layer = draw_ctx->view_layer;
194
195   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
196   glDepthMask(GL_FALSE);
197   glDisable(GL_DEPTH_TEST);
198
199   if (is_cursor_visible(draw_ctx, scene, view_layer)) {
200     int co[2];
201
202     /* Get cursor data into quaternion form */
203     const View3DCursor *cursor = &scene->cursor;
204
205     if (ED_view3d_project_int_global(
206             ar, cursor->location, co, V3D_PROJ_TEST_NOP | V3D_PROJ_TEST_CLIP_NEAR) ==
207         V3D_PROJ_RET_OK) {
208       RegionView3D *rv3d = ar->regiondata;
209
210       float cursor_quat[4];
211       BKE_scene_cursor_rot_to_quat(cursor, cursor_quat);
212
213       /* Draw nice Anti Aliased cursor. */
214       GPU_line_width(1.0f);
215       GPU_blend(true);
216       GPU_line_smooth(true);
217
218       float eps = 1e-5f;
219       rv3d->viewquat[0] = -rv3d->viewquat[0];
220       bool is_aligned = compare_v4v4(cursor_quat, rv3d->viewquat, eps);
221       if (is_aligned == false) {
222         float tquat[4];
223         rotation_between_quats_to_quat(tquat, rv3d->viewquat, cursor_quat);
224         is_aligned = tquat[0] - eps < -1.0f;
225       }
226       rv3d->viewquat[0] = -rv3d->viewquat[0];
227
228       /* Draw lines */
229       if (is_aligned == false) {
230         uint pos = GPU_vertformat_attr_add(
231             immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
232         immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
233         immUniformThemeColor3(TH_VIEW_OVERLAY);
234         immBegin(GPU_PRIM_LINES, 12);
235
236         const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) *
237                             U.widget_unit;
238
239 #define CURSOR_VERT(axis_vec, axis, fac) \
240   immVertex3f(pos, \
241               cursor->location[0] + axis_vec[0] * (fac), \
242               cursor->location[1] + axis_vec[1] * (fac), \
243               cursor->location[2] + axis_vec[2] * (fac))
244
245 #define CURSOR_EDGE(axis_vec, axis, sign) \
246   { \
247     CURSOR_VERT(axis_vec, axis, sign 1.0f); \
248     CURSOR_VERT(axis_vec, axis, sign 0.25f); \
249   } \
250   ((void)0)
251
252         for (int axis = 0; axis < 3; axis++) {
253           float axis_vec[3] = {0};
254           axis_vec[axis] = scale;
255           mul_qt_v3(cursor_quat, axis_vec);
256           CURSOR_EDGE(axis_vec, axis, +);
257           CURSOR_EDGE(axis_vec, axis, -);
258         }
259
260 #undef CURSOR_VERT
261 #undef CURSOR_EDGE
262
263         immEnd();
264         immUnbindProgram();
265       }
266
267       float original_proj[4][4];
268       GPU_matrix_projection_get(original_proj);
269       GPU_matrix_push();
270       ED_region_pixelspace(ar);
271       GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
272       GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
273
274       GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned);
275       GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
276       GPU_batch_program_set(
277           cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
278
279       GPU_batch_draw(cursor_batch);
280
281       GPU_blend(false);
282       GPU_line_smooth(false);
283       GPU_matrix_pop();
284       GPU_matrix_projection_set(original_proj);
285     }
286   }
287 }
288
289 /* **************************** 3D Gizmo ******************************** */
290
291 void DRW_draw_gizmo_3d(void)
292 {
293   const DRWContextState *draw_ctx = DRW_context_state_get();
294   ARegion *ar = draw_ctx->ar;
295
296   /* draw depth culled gizmos - gizmos need to be updated *after* view matrix was set up */
297   /* TODO depth culling gizmos is not yet supported, just drawing _3D here, should
298    * later become _IN_SCENE (and draw _3D separate) */
299   WM_gizmomap_draw(ar->gizmo_map, draw_ctx->evil_C, WM_GIZMOMAP_DRAWSTEP_3D);
300 }
301
302 void DRW_draw_gizmo_2d(void)
303 {
304   const DRWContextState *draw_ctx = DRW_context_state_get();
305   ARegion *ar = draw_ctx->ar;
306
307   WM_gizmomap_draw(ar->gizmo_map, draw_ctx->evil_C, WM_GIZMOMAP_DRAWSTEP_2D);
308
309   glDepthMask(GL_TRUE);
310 }