2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-12-18 17:38:21 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-12-18 17:38:21 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/view3d_draw.c
|
|
|
|
* \ingroup spview3d
|
|
|
|
*/
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "BIF_gl.h"
|
2016-10-14 01:24:27 +00:00
|
|
|
#include "BIF_glutil.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "BKE_camera.h"
|
|
|
|
#include "BKE_context.h"
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "BKE_key.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "BKE_scene.h"
|
2016-12-05 02:50:28 -05:00
|
|
|
#include "BKE_object.h"
|
|
|
|
#include "BKE_paint.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "BKE_unit.h"
|
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
#include "BLF_api.h"
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "BLI_listbase.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "BLI_math.h"
|
|
|
|
#include "BLI_rect.h"
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "BLI_string.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "BLI_threads.h"
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "BLT_translation.h"
|
|
|
|
|
|
|
|
#include "DNA_armature_types.h"
|
2016-12-05 02:50:28 -05:00
|
|
|
#include "DNA_brush_types.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "DNA_camera_types.h"
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "DNA_key_types.h"
|
2016-10-07 01:45:28 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
#include "DNA_windowmanager_types.h"
|
|
|
|
|
2017-03-08 20:00:09 +01:00
|
|
|
#include "DRW_engine.h"
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "ED_keyframing.h"
|
|
|
|
#include "ED_armature.h"
|
2008-12-21 10:33:24 +00:00
|
|
|
#include "ED_keyframing.h"
|
2009-08-26 12:01:15 +00:00
|
|
|
#include "ED_gpencil.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "ED_screen.h"
|
2016-10-13 02:50:42 +00:00
|
|
|
#include "ED_transform.h"
|
2017-02-14 17:47:11 +01:00
|
|
|
#include "ED_gpencil.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
#include "GPU_matrix.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "GPU_immediate.h"
|
2016-10-24 18:58:12 +00:00
|
|
|
#include "GPU_material.h"
|
2016-10-13 04:22:28 +00:00
|
|
|
#include "GPU_viewport.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
|
2016-10-21 20:50:00 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
#include "UI_interface.h"
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "UI_resources.h"
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
#include "RE_engine.h"
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
#include "WM_api.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
#include "view3d_intern.h" /* own include */
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
/* prototypes */
|
|
|
|
static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth);
|
|
|
|
|
|
|
|
typedef struct DrawData {
|
|
|
|
rcti border_rect;
|
|
|
|
bool render_border;
|
|
|
|
bool clip_border;
|
|
|
|
bool is_render;
|
2016-10-21 20:50:00 +00:00
|
|
|
GPUViewport *viewport;
|
2016-10-07 01:45:28 +00:00
|
|
|
} DrawData;
|
|
|
|
|
2016-10-21 20:50:00 +00:00
|
|
|
static void view3d_draw_data_init(const bContext *C, ARegion *ar, RegionView3D *rv3d, DrawData *draw_data)
|
2016-10-07 01:45:28 +00:00
|
|
|
{
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
draw_data->is_render = (v3d->drawtype == OB_RENDER);
|
|
|
|
|
|
|
|
draw_data->render_border = ED_view3d_calc_render_border(scene, v3d, ar, &draw_data->border_rect);
|
|
|
|
draw_data->clip_border = (draw_data->render_border && !BLI_rcti_compare(&ar->drawrct, &draw_data->border_rect));
|
2016-10-21 20:50:00 +00:00
|
|
|
|
|
|
|
draw_data->viewport = rv3d->viewport;
|
2016-10-07 01:45:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
/* ******************** general functions ***************** */
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
static bool use_depth_doit(Scene *scene, View3D *v3d)
|
|
|
|
{
|
|
|
|
if (v3d->drawtype > OB_WIRE)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/* special case (depth for wire color) */
|
|
|
|
if (v3d->drawtype <= OB_WIRE) {
|
|
|
|
if (scene->obedit && scene->obedit->type == OB_MESH) {
|
|
|
|
Mesh *me = scene->obedit->data;
|
|
|
|
if (me->drawflag & ME_DRAWEIGHT) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool use_depth(const bContext *C)
|
|
|
|
{
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
return use_depth_doit(scene, v3d);
|
|
|
|
}
|
2016-10-06 19:55:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
|
|
|
|
*/
|
|
|
|
void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
|
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-11-21 16:44:05 +00:00
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
|
|
|
|
/* setup window matrices */
|
|
|
|
if (winmat)
|
|
|
|
copy_m4_m4(rv3d->winmat, winmat);
|
|
|
|
else
|
|
|
|
view3d_winmatrix_set(ar, v3d, NULL);
|
|
|
|
|
|
|
|
/* setup view matrix */
|
|
|
|
if (viewmat)
|
|
|
|
copy_m4_m4(rv3d->viewmat, viewmat);
|
|
|
|
else
|
|
|
|
view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
|
|
|
|
|
2016-12-01 10:29:46 +01:00
|
|
|
/* update utility matrices */
|
2016-10-06 19:55:06 +00:00
|
|
|
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
|
|
|
|
invert_m4_m4(rv3d->persinv, rv3d->persmat);
|
|
|
|
invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
|
|
|
|
|
|
|
|
/* calculate GLSL view dependent values */
|
|
|
|
|
|
|
|
/* store window coordinates scaling/offset */
|
|
|
|
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
|
2016-12-01 10:29:46 +01:00
|
|
|
rctf cameraborder;
|
2016-10-06 19:55:06 +00:00
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
|
|
|
|
rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
|
|
|
|
rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
|
|
|
|
|
|
|
|
rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
|
|
|
|
rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
|
|
|
|
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate pixelsize factor once, is used for lamps and obcenters */
|
|
|
|
{
|
|
|
|
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
|
|
|
|
* because of float point precision problems at large values [#23908] */
|
|
|
|
float v1[3], v2[3];
|
|
|
|
float len_px, len_sc;
|
|
|
|
|
|
|
|
v1[0] = rv3d->persmat[0][0];
|
|
|
|
v1[1] = rv3d->persmat[1][0];
|
|
|
|
v1[2] = rv3d->persmat[2][0];
|
|
|
|
|
|
|
|
v2[0] = rv3d->persmat[0][1];
|
|
|
|
v2[1] = rv3d->persmat[1][1];
|
|
|
|
v2[2] = rv3d->persmat[2][1];
|
|
|
|
|
|
|
|
len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
|
|
|
|
len_sc = (float)MAX2(ar->winx, ar->winy);
|
|
|
|
|
|
|
|
rv3d->pixsize = len_px / len_sc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
|
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat);
|
|
|
|
|
|
|
|
/* set for opengl */
|
2016-12-04 20:11:12 -05:00
|
|
|
/* TODO(merwin): transition to GPU_matrix API */
|
2016-10-06 19:55:06 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadMatrixf(rv3d->winmat);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadMatrixf(rv3d->viewmat);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
|
|
|
|
if ((scene->r.scemode & R_MULTIVIEW) == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (WM_stereo3d_enabled(win, true) == false)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
|
|
|
|
if (v3d->stereo3d_camera == STEREO_MONO_ID)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return BKE_scene_multiview_is_stereo3d(&scene->r);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup the view and win matrices for the multiview cameras
|
|
|
|
*
|
|
|
|
* unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
|
|
|
|
* we have no winmatrix (i.e., projection matrix) defined at that time.
|
|
|
|
* Since the camera and the camera shift are needed for the winmat calculation
|
|
|
|
* we do a small hack to replace it temporarily so we don't need to change the
|
|
|
|
* view3d)main_region_setup_view() code to account for that.
|
|
|
|
*/
|
|
|
|
static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
|
|
|
|
{
|
|
|
|
bool is_left;
|
|
|
|
const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
|
|
|
|
const char *viewname;
|
|
|
|
|
|
|
|
/* show only left or right camera */
|
|
|
|
if (v3d->stereo3d_camera != STEREO_3D_ID)
|
|
|
|
v3d->multiview_eye = v3d->stereo3d_camera;
|
|
|
|
|
|
|
|
is_left = v3d->multiview_eye == STEREO_LEFT_ID;
|
|
|
|
viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
|
|
|
|
|
|
|
|
/* update the viewport matrices with the new camera */
|
|
|
|
if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
|
|
|
|
Camera *data;
|
|
|
|
float viewmat[4][4];
|
|
|
|
float shiftx;
|
|
|
|
|
|
|
|
data = (Camera *)v3d->camera->data;
|
|
|
|
shiftx = data->shiftx;
|
|
|
|
|
|
|
|
BLI_lock_thread(LOCK_VIEW3D);
|
|
|
|
data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
|
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
|
|
|
|
|
|
|
|
data->shiftx = shiftx;
|
|
|
|
BLI_unlock_thread(LOCK_VIEW3D);
|
|
|
|
}
|
|
|
|
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
|
|
|
|
float viewmat[4][4];
|
|
|
|
Object *view_ob = v3d->camera;
|
|
|
|
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
|
|
|
|
|
|
|
|
BLI_lock_thread(LOCK_VIEW3D);
|
|
|
|
v3d->camera = camera;
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
|
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
|
|
|
|
|
|
|
|
v3d->camera = view_ob;
|
|
|
|
BLI_unlock_thread(LOCK_VIEW3D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-21 20:50:00 +00:00
|
|
|
/* ******************** debug ***************** */
|
|
|
|
|
2016-10-25 04:46:07 -04:00
|
|
|
#define VIEW3D_DRAW_DEBUG 1
|
|
|
|
/* TODO: expand scope of this flag so UI reflects the underlying code */
|
|
|
|
|
|
|
|
#if VIEW3D_DRAW_DEBUG
|
|
|
|
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_debug_store_depth(ARegion *UNUSED(ar), DrawData *draw_data)
|
2016-10-21 20:50:00 +00:00
|
|
|
{
|
|
|
|
GPUViewport *viewport = draw_data->viewport;
|
|
|
|
GLint viewport_size[4];
|
|
|
|
glGetIntegerv(GL_VIEWPORT, viewport_size);
|
|
|
|
|
|
|
|
const int x = viewport_size[0];
|
|
|
|
const int y = viewport_size[1];
|
|
|
|
const int w = viewport_size[2];
|
|
|
|
const int h = viewport_size[3];
|
|
|
|
|
|
|
|
if (GPU_viewport_debug_depth_is_valid(viewport)) {
|
|
|
|
if ((GPU_viewport_debug_depth_width(viewport) != w) ||
|
2017-02-22 18:52:07 +01:00
|
|
|
(GPU_viewport_debug_depth_height(viewport) != h))
|
2016-10-21 20:50:00 +00:00
|
|
|
{
|
|
|
|
GPU_viewport_debug_depth_free(viewport);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GPU_viewport_debug_depth_is_valid(viewport)) {
|
|
|
|
char error[256];
|
2017-01-10 18:17:29 +01:00
|
|
|
if (!GPU_viewport_debug_depth_create(viewport, w, h, error)) {
|
2016-10-21 20:50:00 +00:00
|
|
|
fprintf(stderr, "Failed to create depth buffer for debug: %s\n", error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GPU_viewport_debug_depth_store(viewport, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void view3d_draw_debug_post_solid(const bContext *C, ARegion *ar, DrawData *draw_data)
|
|
|
|
{
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
if ((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_SCENE_DEPTH) != 0) {
|
|
|
|
view3d_draw_debug_store_depth(ar, draw_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void view3d_draw_debug(const bContext *C, ARegion *ar, DrawData *draw_data)
|
|
|
|
{
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
if ((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_COMBINED_DEPTH) != 0) {
|
|
|
|
/* store */
|
|
|
|
view3d_draw_debug_store_depth(ar, draw_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_SCENE_DEPTH) != 0) ||
|
2017-02-22 18:52:07 +01:00
|
|
|
((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_COMBINED_DEPTH) != 0))
|
2016-10-21 20:50:00 +00:00
|
|
|
{
|
|
|
|
/* draw */
|
|
|
|
if (GPU_viewport_debug_depth_is_valid(draw_data->viewport)) {
|
|
|
|
GPU_viewport_debug_depth_draw(draw_data->viewport, v3d->debug.znear, v3d->debug.zfar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* cleanup */
|
|
|
|
GPU_viewport_debug_depth_free(draw_data->viewport);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-25 04:46:07 -04:00
|
|
|
#endif /* VIEW3D_DRAW_DEBUG */
|
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
/* ******************** view border ***************** */
|
|
|
|
|
|
|
|
static void view3d_camera_border(
|
|
|
|
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
|
|
|
|
rctf *r_viewborder, const bool no_shift, const bool no_zoom)
|
|
|
|
{
|
|
|
|
CameraParams params;
|
|
|
|
rctf rect_view, rect_camera;
|
|
|
|
|
|
|
|
/* get viewport viewplane */
|
|
|
|
BKE_camera_params_init(¶ms);
|
|
|
|
BKE_camera_params_from_view3d(¶ms, v3d, rv3d);
|
|
|
|
if (no_zoom)
|
|
|
|
params.zoom = 1.0f;
|
|
|
|
BKE_camera_params_compute_viewplane(¶ms, ar->winx, ar->winy, 1.0f, 1.0f);
|
|
|
|
rect_view = params.viewplane;
|
|
|
|
|
|
|
|
/* get camera viewplane */
|
|
|
|
BKE_camera_params_init(¶ms);
|
|
|
|
/* fallback for non camera objects */
|
|
|
|
params.clipsta = v3d->near;
|
|
|
|
params.clipend = v3d->far;
|
|
|
|
BKE_camera_params_from_object(¶ms, v3d->camera);
|
|
|
|
if (no_shift) {
|
|
|
|
params.shiftx = 0.0f;
|
|
|
|
params.shifty = 0.0f;
|
|
|
|
}
|
|
|
|
BKE_camera_params_compute_viewplane(¶ms, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
|
|
|
|
rect_camera = params.viewplane;
|
|
|
|
|
|
|
|
/* get camera border within viewport */
|
|
|
|
r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
|
|
|
|
r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
|
|
|
|
r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
|
|
|
|
r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ED_view3d_calc_camera_border_size(
|
|
|
|
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
|
|
|
|
float r_size[2])
|
|
|
|
{
|
|
|
|
rctf viewborder;
|
|
|
|
|
|
|
|
view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, true, true);
|
|
|
|
r_size[0] = BLI_rctf_size_x(&viewborder);
|
|
|
|
r_size[1] = BLI_rctf_size_y(&viewborder);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ED_view3d_calc_camera_border(
|
|
|
|
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
|
|
|
|
rctf *r_viewborder, const bool no_shift)
|
|
|
|
{
|
|
|
|
view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawviewborder_grid3(unsigned pos, float x1, float x2, float y1, float y2, float fac)
|
|
|
|
{
|
|
|
|
float x3, y3, x4, y4;
|
|
|
|
|
|
|
|
x3 = x1 + fac * (x2 - x1);
|
|
|
|
y3 = y1 + fac * (y2 - y1);
|
|
|
|
x4 = x1 + (1.0f - fac) * (x2 - x1);
|
|
|
|
y4 = y1 + (1.0f - fac) * (y2 - y1);
|
|
|
|
|
|
|
|
immBegin(GL_LINES, 8);
|
|
|
|
immVertex2f(pos, x1, y3);
|
|
|
|
immVertex2f(pos, x2, y3);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y4);
|
|
|
|
immVertex2f(pos, x2, y4);
|
|
|
|
|
|
|
|
immVertex2f(pos, x3, y1);
|
|
|
|
immVertex2f(pos, x3, y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x4, y1);
|
|
|
|
immVertex2f(pos, x4, y2);
|
|
|
|
immEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* harmonious triangle */
|
|
|
|
static void drawviewborder_triangle(unsigned pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
|
|
|
|
{
|
|
|
|
float ofs;
|
|
|
|
float w = x2 - x1;
|
|
|
|
float h = y2 - y1;
|
|
|
|
|
|
|
|
immBegin(GL_LINES, 6);
|
|
|
|
if (w > h) {
|
|
|
|
if (golden) {
|
|
|
|
ofs = w * (1.0f - (1.0f / 1.61803399f));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ofs = h * (h / w);
|
|
|
|
}
|
|
|
|
if (dir == 'B') SWAP(float, y1, y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y1);
|
|
|
|
immVertex2f(pos, x2, y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x2, y1);
|
|
|
|
immVertex2f(pos, x1 + (w - ofs), y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y2);
|
|
|
|
immVertex2f(pos, x1 + ofs, y1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (golden) {
|
|
|
|
ofs = h * (1.0f - (1.0f / 1.61803399f));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ofs = w * (w / h);
|
|
|
|
}
|
|
|
|
if (dir == 'B') SWAP(float, x1, x2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y1);
|
|
|
|
immVertex2f(pos, x2, y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x2, y1);
|
|
|
|
immVertex2f(pos, x1, y1 + ofs);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y2);
|
|
|
|
immVertex2f(pos, x2, y1 + (h - ofs));
|
|
|
|
}
|
|
|
|
immEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
|
|
|
|
{
|
|
|
|
float x1, x2, y1, y2;
|
|
|
|
float x1i, x2i, y1i, y2i;
|
|
|
|
|
|
|
|
rctf viewborder;
|
|
|
|
Camera *ca = NULL;
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
if (v3d->camera == NULL)
|
|
|
|
return;
|
|
|
|
if (v3d->camera->type == OB_CAMERA)
|
|
|
|
ca = v3d->camera->data;
|
|
|
|
|
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
|
|
|
|
/* the offsets */
|
|
|
|
x1 = viewborder.xmin;
|
|
|
|
y1 = viewborder.ymin;
|
|
|
|
x2 = viewborder.xmax;
|
|
|
|
y2 = viewborder.ymax;
|
|
|
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
|
|
|
/* apply offsets so the real 3D camera shows through */
|
|
|
|
|
|
|
|
/* note: quite un-scientific but without this bit extra
|
|
|
|
* 0.0001 on the lower left the 2D border sometimes
|
|
|
|
* obscures the 3D camera border */
|
|
|
|
/* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
|
|
|
|
* but keep it here in case we need to remove the workaround */
|
|
|
|
x1i = (int)(x1 - 1.0001f);
|
|
|
|
y1i = (int)(y1 - 1.0001f);
|
|
|
|
x2i = (int)(x2 + (1.0f - 0.0001f));
|
|
|
|
y2i = (int)(y2 + (1.0f - 0.0001f));
|
|
|
|
|
|
|
|
/* use the same program for everything */
|
2016-11-15 11:49:00 -05:00
|
|
|
unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
|
2016-10-14 01:38:04 +00:00
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
|
|
|
|
|
|
|
/* passepartout, specified in camera edit buttons */
|
|
|
|
if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
|
|
|
|
const float winx = (ar->winx + 1);
|
|
|
|
const float winy = (ar->winy + 1);
|
|
|
|
|
|
|
|
float alpha = 1.0f;
|
|
|
|
|
|
|
|
if (ca->passepartalpha != 1.0f) {
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
alpha = ca->passepartalpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
|
|
|
|
|
|
|
|
if (x1i > 0.0f)
|
|
|
|
immRectf(pos, 0.0f, winy, x1i, 0.0f);
|
|
|
|
if (x2i < winx)
|
|
|
|
immRectf(pos, x2i, winy, winx, 0.0f);
|
|
|
|
if (y2i < winy)
|
|
|
|
immRectf(pos, x1i, winy, x2i, y2i);
|
|
|
|
if (y2i > 0.0f)
|
|
|
|
immRectf(pos, x1i, y1i, x2i, 0.0f);
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
}
|
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
immUniformThemeColor(TH_BACK);
|
|
|
|
imm_draw_line_box(pos, x1i, y1i, x2i, y2i);
|
|
|
|
|
|
|
|
#ifdef VIEW3D_CAMERA_BORDER_HACK
|
|
|
|
if (view3d_camera_border_hack_test == true) {
|
|
|
|
immUniformColor3ubv(view3d_camera_border_hack_col);
|
|
|
|
imm_draw_line_box(pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
|
|
|
|
view3d_camera_border_hack_test = false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
setlinestyle(3);
|
|
|
|
|
|
|
|
/* outer line not to confuse with object selecton */
|
|
|
|
if (v3d->flag2 & V3D_LOCK_CAMERA) {
|
|
|
|
immUniformThemeColor(TH_REDALERT);
|
|
|
|
imm_draw_line_box(pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
immUniformThemeColor(TH_VIEW_OVERLAY);
|
|
|
|
imm_draw_line_box(pos, x1i, y1i, x2i, y2i);
|
|
|
|
|
|
|
|
/* border */
|
|
|
|
if (scene->r.mode & R_BORDER) {
|
|
|
|
float x3, y3, x4, y4;
|
|
|
|
|
|
|
|
x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
|
|
|
|
y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
|
|
|
|
x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
|
|
|
|
y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
|
|
|
|
|
|
|
|
imm_cpack(0x4040FF);
|
|
|
|
imm_draw_line_box(pos, x3, y3, x4, y4);
|
|
|
|
}
|
2017-02-15 02:56:52 +01:00
|
|
|
immUnbindProgram();
|
2016-10-14 01:38:04 +00:00
|
|
|
|
|
|
|
/* safety border */
|
|
|
|
if (ca) {
|
2017-02-15 02:56:52 +01:00
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
2016-10-14 01:38:04 +00:00
|
|
|
if (ca->dtx & CAM_DTX_CENTER) {
|
|
|
|
float x3, y3;
|
|
|
|
|
|
|
|
x3 = x1 + 0.5f * (x2 - x1);
|
|
|
|
y3 = y1 + 0.5f * (y2 - y1);
|
|
|
|
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
immBegin(GL_LINES, 4);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y3);
|
|
|
|
immVertex2f(pos, x2, y3);
|
|
|
|
|
|
|
|
immVertex2f(pos, x3, y1);
|
|
|
|
immVertex2f(pos, x3, y2);
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_CENTER_DIAG) {
|
|
|
|
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
immBegin(GL_LINES, 4);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y1);
|
|
|
|
immVertex2f(pos, x2, y2);
|
|
|
|
|
|
|
|
immVertex2f(pos, x1, y2);
|
|
|
|
immVertex2f(pos, x2, y1);
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_THIRDS) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_grid3(pos, x1, x2, y1, y2, 1.0f / 3.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_grid3(pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_triangle(pos, x1, x2, y1, y2, 0, 'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_triangle(pos, x1, x2, y1, y2, 0, 'B');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_triangle(pos, x1, x2, y1, y2, 1, 'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
|
|
|
|
immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
|
|
|
|
drawviewborder_triangle(pos, x1, x2, y1, y2, 1, 'B');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
|
|
|
|
UI_draw_safe_areas(
|
|
|
|
pos, x1, x2, y1, y2,
|
|
|
|
scene->safe_areas.title,
|
|
|
|
scene->safe_areas.action);
|
|
|
|
|
|
|
|
if (ca->flag & CAM_SHOW_SAFE_CENTER) {
|
|
|
|
UI_draw_safe_areas(
|
|
|
|
pos, x1, x2, y1, y2,
|
|
|
|
scene->safe_areas.title_center,
|
|
|
|
scene->safe_areas.action_center);
|
|
|
|
}
|
|
|
|
}
|
2017-02-15 02:56:52 +01:00
|
|
|
immUnbindProgram();
|
2016-10-14 01:38:04 +00:00
|
|
|
|
|
|
|
if (ca->flag & CAM_SHOWSENSOR) {
|
|
|
|
/* determine sensor fit, and get sensor x/y, for auto fit we
|
|
|
|
* assume and square sensor and only use sensor_x */
|
|
|
|
float sizex = scene->r.xsch * scene->r.xasp;
|
|
|
|
float sizey = scene->r.ysch * scene->r.yasp;
|
|
|
|
int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
|
|
|
|
float sensor_x = ca->sensor_x;
|
|
|
|
float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
|
|
|
|
|
|
|
|
/* determine sensor plane */
|
|
|
|
rctf rect;
|
|
|
|
|
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
|
|
|
|
float sensor_scale = (x2i - x1i) / sensor_x;
|
|
|
|
float sensor_height = sensor_scale * sensor_y;
|
|
|
|
|
|
|
|
rect.xmin = x1i;
|
|
|
|
rect.xmax = x2i;
|
|
|
|
rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
|
|
|
|
rect.ymax = rect.ymin + sensor_height;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float sensor_scale = (y2i - y1i) / sensor_y;
|
|
|
|
float sensor_width = sensor_scale * sensor_x;
|
|
|
|
|
|
|
|
rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
|
|
|
|
rect.xmax = rect.xmin + sensor_width;
|
|
|
|
rect.ymin = y1i;
|
|
|
|
rect.ymax = y2i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw */
|
|
|
|
float color[4];
|
|
|
|
UI_GetThemeColorShade4fv(TH_VIEW_OVERLAY, 100, color);
|
|
|
|
UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
/* camera name - draw in highlighted text color */
|
|
|
|
if (ca && (ca->flag & CAM_SHOWNAME)) {
|
2017-02-05 00:54:21 -05:00
|
|
|
UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
|
2016-10-14 01:38:04 +00:00
|
|
|
BLF_draw_default(
|
|
|
|
x1i, y1i - (0.7f * U.widget_unit), 0.0f,
|
|
|
|
v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-10-16 17:28:12 +02:00
|
|
|
static void drawrenderborder(ARegion *ar, View3D *v3d)
|
2016-10-14 01:24:27 +00:00
|
|
|
{
|
|
|
|
/* use the same program for everything */
|
2016-11-15 11:49:00 -05:00
|
|
|
unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
|
2016-10-14 01:24:27 +00:00
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
|
|
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
setlinestyle(3);
|
|
|
|
imm_cpack(0x4040FF);
|
|
|
|
|
|
|
|
imm_draw_line_box(
|
|
|
|
pos, v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
|
|
|
|
v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
|
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
immUnbindProgram();
|
|
|
|
}
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
/* ******************** offline engine ***************** */
|
|
|
|
|
|
|
|
static bool view3d_draw_render_draw(const bContext *C, Scene *scene,
|
2017-01-10 18:17:29 +01:00
|
|
|
ARegion *ar, View3D *UNUSED(v3d),
|
|
|
|
bool clip_border, const rcti *border_rect)
|
2016-10-07 01:45:28 +00:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
RenderEngineType *type;
|
|
|
|
GLint scissor[4];
|
|
|
|
|
|
|
|
/* create render engine */
|
|
|
|
if (!rv3d->render_engine) {
|
|
|
|
RenderEngine *engine;
|
|
|
|
|
|
|
|
type = RE_engines_find(scene->r.engine);
|
|
|
|
|
|
|
|
if (!(type->view_update && type->view_draw))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
engine = RE_engine_create_ex(type, true);
|
|
|
|
|
|
|
|
engine->tile_x = scene->r.tilex;
|
|
|
|
engine->tile_y = scene->r.tiley;
|
|
|
|
|
|
|
|
type->view_update(engine, C);
|
|
|
|
|
|
|
|
rv3d->render_engine = engine;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* background draw */
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
|
|
|
|
if (clip_border) {
|
|
|
|
/* for border draw, we only need to clear a subset of the 3d view */
|
|
|
|
if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
|
|
|
|
glGetIntegerv(GL_SCISSOR_BOX, scissor);
|
|
|
|
glScissor(border_rect->xmin, border_rect->ymin,
|
|
|
|
BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
/* don't change depth buffer */
|
2016-10-25 04:39:55 -04:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT); /* is this necessary? -- merwin */
|
2016-10-07 01:45:28 +00:00
|
|
|
|
|
|
|
/* render result draw */
|
|
|
|
type = rv3d->render_engine->type;
|
|
|
|
type->view_draw(rv3d->render_engine, C);
|
|
|
|
|
|
|
|
if (clip_border) {
|
|
|
|
/* restore scissor as it was before */
|
|
|
|
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-24 18:58:12 +00:00
|
|
|
/* ******************** background plates ***************** */
|
|
|
|
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_background_gradient(void)
|
2016-10-24 18:58:12 +00:00
|
|
|
{
|
2016-10-25 04:39:55 -04:00
|
|
|
gpuMatrixBegin3D(); /* TODO: finish 2D API */
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
VertexFormat *format = immVertexFormat();
|
2016-11-15 11:49:00 -05:00
|
|
|
unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
|
2016-10-25 04:39:55 -04:00
|
|
|
unsigned char col_hi[3], col_lo[3];
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
|
|
|
|
UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
immBegin(GL_QUADS, 4);
|
|
|
|
immAttrib3ubv(color, col_lo);
|
|
|
|
immVertex2f(pos, -1.0f, -1.0f);
|
|
|
|
immVertex2f(pos, 1.0f, -1.0f);
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
immAttrib3ubv(color, col_hi);
|
|
|
|
immVertex2f(pos, 1.0f, 1.0f);
|
|
|
|
immVertex2f(pos, -1.0f, 1.0f);
|
|
|
|
immEnd();
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
immUnbindProgram();
|
2016-10-24 19:40:34 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
gpuMatrixEnd();
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_background_none(void)
|
2016-10-25 04:39:55 -04:00
|
|
|
{
|
|
|
|
if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
|
|
|
|
view3d_draw_background_gradient();
|
2016-10-24 19:40:34 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
}
|
2016-10-24 18:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
if (scene->world) {
|
|
|
|
GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
|
|
|
|
|
|
|
|
/* calculate full shader for background */
|
|
|
|
GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
|
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
if (GPU_material_bound(gpumat)) {
|
2016-10-24 18:58:12 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
2016-10-24 18:58:12 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
/* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode,
|
|
|
|
* we can't get rid of the following code without a bigger refactor
|
|
|
|
* or we dropping this functionality. */
|
2016-10-24 18:58:12 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
|
|
glVertex2f(-1.0f, -1.0f);
|
|
|
|
glVertex2f(1.0f, -1.0f);
|
|
|
|
glVertex2f(-1.0f, 1.0f);
|
|
|
|
glVertex2f(1.0f, 1.0f);
|
|
|
|
glEnd();
|
2016-10-24 18:58:12 +00:00
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
GPU_material_unbind(gpumat);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
view3d_draw_background_none();
|
|
|
|
}
|
2016-10-24 18:58:12 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
view3d_draw_background_none();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/* ******************** solid plates ***************** */
|
|
|
|
|
|
|
|
/**
|
2016-10-24 18:58:12 +00:00
|
|
|
* Clear the buffer and draw the proper shader
|
2016-10-06 14:14:41 +00:00
|
|
|
*/
|
|
|
|
static void view3d_draw_background(const bContext *C)
|
|
|
|
{
|
2016-10-24 18:58:12 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
2016-10-25 11:17:53 +00:00
|
|
|
glDepthMask(GL_TRUE);
|
2016-10-25 04:39:55 -04:00
|
|
|
/* Background functions do not read or write depth, but they do clear or completely
|
|
|
|
* overwrite color buffer. It's more efficient to clear color & depth in once call, so
|
|
|
|
* background functions do this even though they don't use depth.
|
|
|
|
*/
|
|
|
|
|
2016-10-24 18:58:12 +00:00
|
|
|
switch (v3d->debug.background) {
|
|
|
|
case V3D_DEBUG_BACKGROUND_WORLD:
|
|
|
|
view3d_draw_background_world(scene, v3d, rv3d);
|
|
|
|
break;
|
|
|
|
case V3D_DEBUG_BACKGROUND_GRADIENT:
|
|
|
|
view3d_draw_background_gradient();
|
|
|
|
break;
|
|
|
|
case V3D_DEBUG_BACKGROUND_NONE:
|
|
|
|
default:
|
2016-10-25 04:39:55 -04:00
|
|
|
view3d_draw_background_none();
|
2016-10-24 18:58:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_render_solid_surfaces(const bContext *C, ARegion *ar, const bool UNUSED(run_screen_shaders))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
2016-10-07 01:45:28 +00:00
|
|
|
draw_all_objects(C, ar, false, use_depth(C));
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_render_transparent_surfaces(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_post_draw(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** geometry overlay ***************** */
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* Front/back wire frames
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_wire_plates(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* Special treatment for selected objects
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_outline_plates(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
/* ******************** other elements ***************** */
|
|
|
|
|
|
|
|
|
|
|
|
#define DEBUG_GRID 0
|
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count)
|
2016-10-06 19:55:06 +00:00
|
|
|
{
|
|
|
|
/* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
|
|
|
|
* x0 is gridline 0, the axis in screen space
|
|
|
|
* Area covers [0 .. max) pixels */
|
|
|
|
|
|
|
|
int first = (int)ceil(-x0 / dx);
|
|
|
|
int last = (int)floor((max - x0) / dx);
|
|
|
|
|
|
|
|
if (first <= last) {
|
2017-02-22 18:52:07 +01:00
|
|
|
*r_first = first;
|
|
|
|
*r_count = last - first + 1;
|
2016-10-06 19:55:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2017-02-22 18:52:07 +01:00
|
|
|
*r_first = 0;
|
|
|
|
*r_count = 0;
|
2016-10-06 19:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf(" first %d * dx = %f\n", first, x0 + first * dx);
|
|
|
|
printf(" last %d * dx = %f\n", last, x0 + last * dx);
|
|
|
|
printf(" count = %d\n", *count_out);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static int gridline_count(ARegion *ar, double x0, double y0, double dx)
|
|
|
|
{
|
|
|
|
/* x0 & y0 establish the "phase" of the grid within this 2D region
|
|
|
|
* dx is the frequency, shared by x & y directions
|
|
|
|
* pass in dx of smallest (highest precision) grid we want to draw */
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf(" %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int first, x_ct, y_ct;
|
|
|
|
|
|
|
|
gridline_range(x0, dx, ar->winx, &first, &x_ct);
|
|
|
|
gridline_range(y0, dx, ar->winy, &first, &y_ct);
|
|
|
|
|
|
|
|
int total_ct = x_ct + y_ct;
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf(" %d + %d = %d gridlines\n", x_ct, y_ct, total_ct);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return total_ct;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3])
|
|
|
|
{
|
|
|
|
/* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
|
|
|
|
* always skip exact x0 & y0 axes; they will be drawn later in color
|
|
|
|
*
|
|
|
|
* set grid color once, just before the first line is drawn
|
|
|
|
* it's harmless to set same color for every line, or every vertex
|
|
|
|
* but if no lines are drawn, color must not be set! */
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf(" %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const float x_max = (float)ar->winx;
|
|
|
|
const float y_max = (float)ar->winy;
|
|
|
|
|
|
|
|
int first, ct;
|
|
|
|
int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
|
|
|
|
int lines_skipped_for_next_unit = 0;
|
|
|
|
|
|
|
|
/* draw vertical lines */
|
|
|
|
gridline_range(x0, dx, x_max, &first, &ct);
|
|
|
|
|
|
|
|
for (int i = first; i < first + ct; ++i) {
|
|
|
|
if (i == 0)
|
|
|
|
continue;
|
|
|
|
else if (skip_mod && (i % skip_mod) == 0) {
|
|
|
|
++lines_skipped_for_next_unit;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x_ct == 0)
|
|
|
|
immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
|
|
|
|
|
|
|
|
float x = (float)(x0 + i * dx);
|
|
|
|
immVertex2f(pos, x, 0.0f);
|
|
|
|
immVertex2f(pos, x, y_max);
|
|
|
|
++x_ct;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw horizontal lines */
|
|
|
|
gridline_range(y0, dx, y_max, &first, &ct);
|
|
|
|
|
|
|
|
for (int i = first; i < first + ct; ++i) {
|
|
|
|
if (i == 0)
|
|
|
|
continue;
|
|
|
|
else if (skip_mod && (i % skip_mod) == 0) {
|
|
|
|
++lines_skipped_for_next_unit;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x_ct + y_ct == 0)
|
|
|
|
immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
|
|
|
|
|
|
|
|
float y = (float)(y0 + i * dx);
|
|
|
|
immVertex2f(pos, 0.0f, y);
|
|
|
|
immVertex2f(pos, x_max, y);
|
|
|
|
++y_ct;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
int total_ct = x_ct + y_ct;
|
|
|
|
printf(" %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return lines_skipped_for_next_unit > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GRID_MIN_PX_D 6.0
|
|
|
|
#define GRID_MIN_PX_F 6.0f
|
|
|
|
|
|
|
|
static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
|
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
double fx = rv3d->persmat[3][0];
|
|
|
|
double fy = rv3d->persmat[3][1];
|
|
|
|
double fw = rv3d->persmat[3][3];
|
|
|
|
|
|
|
|
const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */
|
|
|
|
const double wy = 0.5 * ar->winy;
|
|
|
|
|
|
|
|
double x = wx * fx / fw;
|
|
|
|
double y = wy * fy / fw;
|
|
|
|
|
|
|
|
double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 };
|
|
|
|
mul_m4_v4d(rv3d->persmat, vec4);
|
|
|
|
fx = vec4[0];
|
|
|
|
fy = vec4[1];
|
|
|
|
fw = vec4[3];
|
|
|
|
|
|
|
|
double dx = fabs(x - wx * fx / fw);
|
|
|
|
if (dx == 0) dx = fabs(y - wy * fy / fw);
|
|
|
|
|
|
|
|
x += wx;
|
|
|
|
y += wy;
|
|
|
|
|
|
|
|
/* now x, y, and dx have their final values
|
|
|
|
* (x,y) is the world origin (0,0,0) mapped to Area-relative screen space
|
|
|
|
* dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */
|
|
|
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
2016-10-25 04:39:55 -04:00
|
|
|
#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */
|
2016-10-06 19:55:06 +00:00
|
|
|
glDepthMask(GL_FALSE); /* disable write in zbuffer */
|
2016-10-25 04:39:55 -04:00
|
|
|
#endif
|
2016-10-06 19:55:06 +00:00
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned int pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
unsigned int color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
|
2016-10-06 19:55:06 +00:00
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
|
|
|
|
|
|
|
unsigned char col[3], col2[3];
|
|
|
|
UI_GetThemeColor3ubv(TH_GRID, col);
|
|
|
|
|
|
|
|
if (unit->system) {
|
|
|
|
const void *usys;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
|
|
|
|
|
|
|
|
bool first = true;
|
|
|
|
|
|
|
|
if (usys) {
|
|
|
|
int i = len;
|
|
|
|
while (i--) {
|
|
|
|
double scalar = bUnit_GetScaler(usys, i);
|
|
|
|
|
|
|
|
double dx_scalar = dx * scalar / (double)unit->scale_length;
|
|
|
|
if (dx_scalar < (GRID_MIN_PX_D * 2.0)) {
|
|
|
|
/* very very small grid items are less useful when dealing with units */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
first = false;
|
|
|
|
|
|
|
|
/* Store the smallest drawn grid size units name so users know how big each grid cell is */
|
|
|
|
*grid_unit = bUnit_GetNameDisplay(usys, i);
|
|
|
|
rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
|
|
|
|
|
|
|
|
int gridline_ct = gridline_count(ar, x, y, dx_scalar);
|
|
|
|
if (gridline_ct == 0)
|
|
|
|
goto drawgrid_cleanup; /* nothing to draw */
|
|
|
|
|
|
|
|
immBegin(GL_LINES, gridline_ct * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
|
|
|
|
/* tweak to have the fade a bit nicer */
|
|
|
|
blend_fac = (blend_fac * blend_fac) * 2.0f;
|
|
|
|
CLAMP(blend_fac, 0.3f, 1.0f);
|
|
|
|
|
|
|
|
UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2);
|
|
|
|
|
|
|
|
const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar);
|
|
|
|
#if DEBUG_GRID
|
|
|
|
printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar);
|
|
|
|
if (i > 0)
|
|
|
|
printf("next unit is %d times larger\n", skip_mod);
|
|
|
|
else
|
|
|
|
printf("largest unit\n");
|
|
|
|
#endif
|
|
|
|
if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const double sublines = v3d->gridsubdiv;
|
|
|
|
const float sublines_fl = v3d->gridsubdiv;
|
|
|
|
|
|
|
|
int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */
|
|
|
|
|
|
|
|
if (dx < GRID_MIN_PX_D) {
|
|
|
|
rv3d->gridview *= sublines_fl;
|
|
|
|
dx *= sublines;
|
|
|
|
if (dx < GRID_MIN_PX_D) {
|
|
|
|
rv3d->gridview *= sublines_fl;
|
|
|
|
dx *= sublines;
|
|
|
|
if (dx < GRID_MIN_PX_D) {
|
|
|
|
rv3d->gridview *= sublines_fl;
|
|
|
|
dx *= sublines;
|
|
|
|
grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2017-02-22 18:52:07 +01:00
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
|
2016-10-06 19:55:06 +00:00
|
|
|
rv3d->gridview /= sublines_fl;
|
|
|
|
dx /= sublines;
|
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
|
|
|
|
rv3d->gridview /= sublines_fl;
|
|
|
|
dx /= sublines;
|
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) {
|
|
|
|
grids_to_draw = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int gridline_ct = gridline_count(ar, x, y, dx);
|
|
|
|
if (gridline_ct == 0)
|
|
|
|
goto drawgrid_cleanup; /* nothing to draw */
|
|
|
|
|
|
|
|
immBegin(GL_LINES, gridline_ct * 2);
|
|
|
|
|
|
|
|
if (grids_to_draw == 2) {
|
|
|
|
UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
|
|
|
|
if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2))
|
|
|
|
drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
|
|
|
|
}
|
|
|
|
else if (grids_to_draw == 1) {
|
|
|
|
drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw visible axes */
|
|
|
|
/* horizontal line */
|
|
|
|
if (0 <= y && y < ar->winy) {
|
|
|
|
UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
|
|
|
|
immAttrib3ub(color, col2[0], col2[1], col2[2]);
|
|
|
|
immVertex2f(pos, 0.0f, y);
|
|
|
|
immVertex2f(pos, (float)ar->winx, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vertical line */
|
|
|
|
if (0 <= x && x < ar->winx) {
|
|
|
|
UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
|
|
|
|
immAttrib3ub(color, col2[0], col2[1], col2[2]);
|
|
|
|
immVertex2f(pos, x, 0.0f);
|
|
|
|
immVertex2f(pos, x, (float)ar->winy);
|
|
|
|
}
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
drawgrid_cleanup:
|
|
|
|
immUnbindProgram();
|
2016-10-25 04:39:55 -04:00
|
|
|
|
|
|
|
#if 0 /* depth write is left enabled above */
|
2016-10-06 19:55:06 +00:00
|
|
|
glDepthMask(GL_TRUE); /* enable write in zbuffer */
|
2016-10-25 04:39:55 -04:00
|
|
|
#endif
|
2016-10-06 19:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef DEBUG_GRID
|
|
|
|
#undef GRID_MIN_PX_D
|
|
|
|
#undef GRID_MIN_PX_F
|
|
|
|
|
|
|
|
static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
|
|
|
|
{
|
|
|
|
/* draw only if there is something to draw */
|
|
|
|
if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
|
|
|
|
/* draw how many lines?
|
|
|
|
* trunc(v3d->gridlines / 2) * 4
|
|
|
|
* + 2 for xy axes (possibly with special colors)
|
|
|
|
* + 1 for z axis (the only line not in xy plane)
|
|
|
|
* even v3d->gridlines are honored, odd rounded down */
|
|
|
|
const int gridlines = v3d->gridlines / 2;
|
|
|
|
const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
|
|
|
|
const float grid = gridlines * grid_scale;
|
|
|
|
|
|
|
|
const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
|
|
|
|
|
|
|
|
bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
|
|
|
|
bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
|
|
|
|
bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
|
|
|
|
|
|
|
|
unsigned char col_grid[3], col_axis[3];
|
|
|
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
|
|
|
UI_GetThemeColor3ubv(TH_GRID, col_grid);
|
|
|
|
|
|
|
|
if (!write_depth)
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
|
|
|
if (show_floor) {
|
|
|
|
const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
|
|
|
|
const int sublines = v3d->gridsubdiv;
|
|
|
|
|
|
|
|
unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
|
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned int pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
unsigned int color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
|
2016-10-06 19:55:06 +00:00
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
|
|
|
|
|
|
|
|
immBegin(GL_LINES, vertex_ct);
|
|
|
|
|
|
|
|
/* draw normal grid lines */
|
|
|
|
UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
|
|
|
|
|
|
|
|
for (int a = 1; a <= gridlines; a++) {
|
|
|
|
/* skip emphasised divider lines */
|
|
|
|
if (a % sublines != 0) {
|
|
|
|
const float line = a * grid_scale;
|
|
|
|
|
2016-10-07 13:00:23 -04:00
|
|
|
immAttrib3ubv(color, col_grid_light);
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
immVertex2f(pos, -grid, -line);
|
|
|
|
immVertex2f(pos, +grid, -line);
|
|
|
|
immVertex2f(pos, -grid, +line);
|
|
|
|
immVertex2f(pos, +grid, +line);
|
|
|
|
|
|
|
|
immVertex2f(pos, -line, -grid);
|
|
|
|
immVertex2f(pos, -line, +grid);
|
|
|
|
immVertex2f(pos, +line, -grid);
|
|
|
|
immVertex2f(pos, +line, +grid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw emphasised grid lines */
|
|
|
|
UI_GetThemeColor3ubv(TH_BACK, col_bg);
|
|
|
|
/* emphasise division lines lighter instead of darker, if background is darker than grid */
|
|
|
|
UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
|
|
|
|
(col_grid[0] + col_grid[1] + col_grid[2] + 30 >
|
|
|
|
col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
|
|
|
|
|
|
|
|
if (sublines <= gridlines) {
|
|
|
|
immAttrib3ubv(color, col_grid_emphasise);
|
|
|
|
|
|
|
|
for (int a = sublines; a <= gridlines; a += sublines) {
|
|
|
|
const float line = a * grid_scale;
|
|
|
|
|
|
|
|
immVertex2f(pos, -grid, -line);
|
|
|
|
immVertex2f(pos, +grid, -line);
|
|
|
|
immVertex2f(pos, -grid, +line);
|
|
|
|
immVertex2f(pos, +grid, +line);
|
|
|
|
|
|
|
|
immVertex2f(pos, -line, -grid);
|
|
|
|
immVertex2f(pos, -line, +grid);
|
|
|
|
immVertex2f(pos, +line, -grid);
|
|
|
|
immVertex2f(pos, +line, +grid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw X axis */
|
|
|
|
if (show_axis_x) {
|
|
|
|
show_axis_x = false; /* drawing now, won't need to draw later */
|
|
|
|
UI_make_axis_color(col_grid, col_axis, 'X');
|
|
|
|
immAttrib3ubv(color, col_axis);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
immAttrib3ubv(color, col_grid_emphasise);
|
|
|
|
|
|
|
|
immVertex2f(pos, -grid, 0.0f);
|
|
|
|
immVertex2f(pos, +grid, 0.0f);
|
|
|
|
|
|
|
|
/* draw Y axis */
|
|
|
|
if (show_axis_y) {
|
|
|
|
show_axis_y = false; /* drawing now, won't need to draw later */
|
|
|
|
UI_make_axis_color(col_grid, col_axis, 'Y');
|
|
|
|
immAttrib3ubv(color, col_axis);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
immAttrib3ubv(color, col_grid_emphasise);
|
|
|
|
|
|
|
|
immVertex2f(pos, 0.0f, -grid);
|
|
|
|
immVertex2f(pos, 0.0f, +grid);
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
immUnbindProgram();
|
|
|
|
|
|
|
|
/* done with XY plane */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (show_axis_x || show_axis_y || show_axis_z) {
|
|
|
|
/* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
|
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned int pos = add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
|
|
|
unsigned int color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
|
2016-10-06 19:55:06 +00:00
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
|
|
|
|
immBegin(GL_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
|
|
|
|
|
|
|
|
if (show_axis_x) {
|
|
|
|
UI_make_axis_color(col_grid, col_axis, 'X');
|
|
|
|
immAttrib3ubv(color, col_axis);
|
|
|
|
immVertex3f(pos, -grid, 0.0f, 0.0f);
|
|
|
|
immVertex3f(pos, +grid, 0.0f, 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (show_axis_y) {
|
|
|
|
UI_make_axis_color(col_grid, col_axis, 'Y');
|
|
|
|
immAttrib3ubv(color, col_axis);
|
|
|
|
immVertex3f(pos, 0.0f, -grid, 0.0f);
|
|
|
|
immVertex3f(pos, 0.0f, +grid, 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (show_axis_z) {
|
|
|
|
UI_make_axis_color(col_grid, col_axis, 'Z');
|
|
|
|
immAttrib3ubv(color, col_axis);
|
|
|
|
immVertex3f(pos, 0.0f, 0.0f, -grid);
|
|
|
|
immVertex3f(pos, 0.0f, 0.0f, +grid);
|
|
|
|
}
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
immUnbindProgram();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!write_depth)
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
|
|
|
|
float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
|
|
|
|
{
|
|
|
|
/* apply units */
|
|
|
|
if (scene->unit.system) {
|
|
|
|
const void *usys;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
|
|
|
|
|
|
|
|
if (usys) {
|
|
|
|
int i = bUnit_GetBaseUnit(usys);
|
|
|
|
if (grid_unit)
|
|
|
|
*grid_unit = bUnit_GetNameDisplay(usys, i);
|
|
|
|
return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
|
|
|
|
{
|
|
|
|
return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
|
|
|
|
}
|
|
|
|
|
2016-12-05 02:50:28 -05:00
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
static void view3d_draw_grid(const bContext *C, ARegion *ar)
|
|
|
|
{
|
|
|
|
/* TODO viewport
|
|
|
|
* Missing is the flags to check whether to draw it
|
|
|
|
* for now now we are using the flags in v3d itself.
|
|
|
|
*
|
|
|
|
* Also for now always assume depth is there, so we
|
|
|
|
* draw on top of it.
|
|
|
|
*/
|
2016-12-01 10:29:46 +01:00
|
|
|
/**
|
|
|
|
* Calculate pixel-size factor once, is used for lamps and object centers.
|
|
|
|
* Used by #ED_view3d_pixel_size and typically not accessed directly.
|
|
|
|
*
|
|
|
|
* \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
|
|
|
|
* passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
|
|
|
|
* but in perspective mode its offset by the near-clip.
|
|
|
|
*
|
|
|
|
* 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
|
|
|
|
*/
|
2016-10-06 19:55:06 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
|
|
|
|
const char *grid_unit = NULL;
|
|
|
|
|
|
|
|
/* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
|
2016-10-14 22:40:55 -04:00
|
|
|
* objects if done last
|
|
|
|
* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views.
|
|
|
|
*/
|
|
|
|
rv3d->gridview = ED_view3d_grid_scale(scene, v3d, &grid_unit);
|
2016-10-06 19:55:06 +00:00
|
|
|
|
2016-10-06 23:40:48 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
2016-10-25 04:39:55 -04:00
|
|
|
glDepthMask(GL_FALSE); /* read & test depth, but don't alter it. TODO: separate UI depth buffer */
|
2016-10-06 23:40:48 +00:00
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
if (!draw_floor) {
|
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
*(&grid_unit) = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
|
|
|
|
drawgrid(&scene->unit, ar, v3d, &grid_unit);
|
2016-10-06 23:40:48 +00:00
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadMatrixf(rv3d->winmat);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadMatrixf(rv3d->viewmat);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
drawfloor(scene, v3d, &grid_unit, false);
|
|
|
|
}
|
|
|
|
|
2016-10-06 23:40:48 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
}
|
2016-10-06 19:55:06 +00:00
|
|
|
|
2017-03-02 15:03:02 +01:00
|
|
|
static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
|
2016-12-05 02:50:28 -05:00
|
|
|
{
|
2017-03-02 15:03:02 +01:00
|
|
|
Object *ob = OBACT_NEW;
|
2016-12-05 02:50:28 -05:00
|
|
|
|
|
|
|
/* don't draw cursor in paint modes, but with a few exceptions */
|
|
|
|
if (ob && ob->mode & OB_MODE_ALL_PAINT) {
|
|
|
|
/* exception: object is in weight paint and has deforming armature in pose mode */
|
|
|
|
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
|
|
|
|
if (BKE_object_pose_armature_get(ob) != NULL) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
|
|
|
|
else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
|
|
|
|
const Paint *p = BKE_paint_get_active(scene);
|
|
|
|
|
|
|
|
if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
|
|
|
|
if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* no exception met? then don't draw cursor! */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
|
|
|
|
{
|
|
|
|
int co[2];
|
|
|
|
|
|
|
|
/* we don't want the clipping for cursor */
|
|
|
|
if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
|
|
|
|
const float f5 = 0.25f * U.widget_unit;
|
|
|
|
const float f10 = 0.5f * U.widget_unit;
|
|
|
|
const float f20 = U.widget_unit;
|
|
|
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned int pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
unsigned int color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
|
2016-12-05 02:50:28 -05:00
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
|
|
|
|
|
|
|
const int segments = 16;
|
|
|
|
|
|
|
|
immBegin(GL_LINE_LOOP, segments);
|
|
|
|
|
|
|
|
for (int i = 0; i < segments; ++i) {
|
|
|
|
float angle = 2 * M_PI * ((float)i / (float)segments);
|
|
|
|
float x = co[0] + f10 * cosf(angle);
|
|
|
|
float y = co[1] + f10 * sinf(angle);
|
|
|
|
|
|
|
|
if (i % 2 == 0)
|
|
|
|
immAttrib3ub(color, 255, 0, 0);
|
|
|
|
else
|
|
|
|
immAttrib3ub(color, 255, 255, 255);
|
|
|
|
|
|
|
|
immVertex2f(pos, x, y);
|
|
|
|
}
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
immUnbindProgram();
|
|
|
|
|
|
|
|
VertexFormat_clear(format);
|
|
|
|
pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
|
|
|
|
|
|
|
unsigned char crosshair_color[3];
|
|
|
|
UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
|
|
|
|
immUniformColor3ubv(crosshair_color);
|
|
|
|
|
|
|
|
immBegin(GL_LINES, 8);
|
|
|
|
immVertex2f(pos, co[0] - f20, co[1]);
|
|
|
|
immVertex2f(pos, co[0] - f5, co[1]);
|
|
|
|
immVertex2f(pos, co[0] + f5, co[1]);
|
|
|
|
immVertex2f(pos, co[0] + f20, co[1]);
|
|
|
|
immVertex2f(pos, co[0], co[1] - f20);
|
|
|
|
immVertex2f(pos, co[0], co[1] - f5);
|
|
|
|
immVertex2f(pos, co[0], co[1] + f5);
|
|
|
|
immVertex2f(pos, co[0], co[1] + f20);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
immUnbindProgram();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
|
|
|
|
{
|
|
|
|
const float k = U.rvisize * U.pixelsize; /* axis size */
|
|
|
|
const int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
|
|
|
|
|
|
|
|
const float startx = rect->xmin + k + 1.0f; /* axis center in screen coordinates, x=y */
|
|
|
|
const float starty = rect->ymin + k + 1.0f;
|
|
|
|
|
|
|
|
float axis_pos[3][2];
|
|
|
|
unsigned char axis_col[3][4];
|
|
|
|
|
|
|
|
int axis_order[3] = {0, 1, 2};
|
|
|
|
axis_sort_v3(rv3d->viewinv[2], axis_order);
|
|
|
|
|
|
|
|
for (int axis_i = 0; axis_i < 3; axis_i++) {
|
|
|
|
int i = axis_order[axis_i];
|
|
|
|
|
|
|
|
/* get position of each axis tip on screen */
|
|
|
|
float vec[3] = { 0.0f };
|
|
|
|
vec[i] = 1.0f;
|
|
|
|
mul_qt_v3(rv3d->viewquat, vec);
|
|
|
|
axis_pos[i][0] = startx + vec[0] * k;
|
|
|
|
axis_pos[i][1] = starty + vec[1] * k;
|
|
|
|
|
|
|
|
/* get color of each axis */
|
|
|
|
UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
|
|
|
|
axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw axis lines */
|
|
|
|
glLineWidth(2.0f);
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
|
|
|
unsigned col = add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
|
|
|
immBegin(GL_LINES, 6);
|
|
|
|
|
|
|
|
for (int axis_i = 0; axis_i < 3; axis_i++) {
|
|
|
|
int i = axis_order[axis_i];
|
|
|
|
|
|
|
|
immAttrib4ubv(col, axis_col[i]);
|
|
|
|
immVertex2f(pos, startx, starty);
|
|
|
|
immVertex2fv(pos, axis_pos[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
immEnd();
|
|
|
|
immUnbindProgram();
|
|
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
|
|
|
|
/* draw axis names */
|
|
|
|
for (int axis_i = 0; axis_i < 3; axis_i++) {
|
|
|
|
int i = axis_order[axis_i];
|
|
|
|
|
|
|
|
const char axis_text[2] = {'x' + i, '\0'};
|
2017-02-05 00:54:21 -05:00
|
|
|
BLF_color4ubv(BLF_default(), axis_col[i]);
|
2016-12-05 02:50:28 -05:00
|
|
|
BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WITH_INPUT_NDOF
|
|
|
|
/* draw center and axis of rotation for ongoing 3D mouse navigation */
|
|
|
|
static void draw_rotation_guide(RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
float o[3]; /* center of rotation */
|
|
|
|
float end[3]; /* endpoints for drawing */
|
|
|
|
|
|
|
|
GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
|
|
|
|
|
|
|
|
negate_v3_v3(o, rv3d->ofs);
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glDepthMask(GL_FALSE); /* don't overwrite zbuf */
|
|
|
|
|
|
|
|
VertexFormat *format = immVertexFormat();
|
|
|
|
unsigned pos = add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
|
|
|
unsigned col = add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
|
|
|
|
|
|
|
|
if (rv3d->rot_angle != 0.0f) {
|
|
|
|
/* -- draw rotation axis -- */
|
|
|
|
float scaled_axis[3];
|
|
|
|
const float scale = rv3d->dist;
|
|
|
|
mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
|
|
|
|
|
|
|
|
|
|
|
|
immBegin(GL_LINE_STRIP, 3);
|
|
|
|
color[3] = 0; /* more transparent toward the ends */
|
|
|
|
immAttrib4ubv(col, color);
|
|
|
|
add_v3_v3v3(end, o, scaled_axis);
|
|
|
|
immVertex3fv(pos, end);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
|
|
|
|
/* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
color[3] = 127; /* more opaque toward the center */
|
|
|
|
immAttrib4ubv(col, color);
|
|
|
|
immVertex3fv(pos, o);
|
|
|
|
|
|
|
|
color[3] = 0;
|
|
|
|
immAttrib4ubv(col, color);
|
|
|
|
sub_v3_v3v3(end, o, scaled_axis);
|
|
|
|
immVertex3fv(pos, end);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
/* -- draw ring around rotation center -- */
|
|
|
|
{
|
|
|
|
#define ROT_AXIS_DETAIL 13
|
|
|
|
|
|
|
|
const float s = 0.05f * scale;
|
|
|
|
const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
|
|
|
|
|
|
|
|
float q[4]; /* rotate ring so it's perpendicular to axis */
|
|
|
|
const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
|
|
|
|
if (!upright) {
|
|
|
|
const float up[3] = {0.0f, 0.0f, 1.0f};
|
|
|
|
float vis_angle, vis_axis[3];
|
|
|
|
|
|
|
|
cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
|
|
|
|
vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
|
|
|
|
axis_angle_to_quat(q, vis_axis, vis_angle);
|
|
|
|
}
|
|
|
|
|
|
|
|
immBegin(GL_LINE_LOOP, ROT_AXIS_DETAIL);
|
|
|
|
color[3] = 63; /* somewhat faint */
|
|
|
|
immAttrib4ubv(col, color);
|
|
|
|
float angle = 0.0f;
|
|
|
|
for (int i = 0; i < ROT_AXIS_DETAIL; ++i, angle += step) {
|
|
|
|
float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
|
|
|
|
|
|
|
|
if (!upright) {
|
|
|
|
mul_qt_v3(q, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
add_v3_v3(p, o);
|
|
|
|
immVertex3fv(pos, p);
|
|
|
|
}
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
#undef ROT_AXIS_DETAIL
|
|
|
|
}
|
|
|
|
|
|
|
|
color[3] = 255; /* solid dot */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
color[3] = 127; /* see-through dot */
|
|
|
|
|
2017-02-28 03:09:44 -05:00
|
|
|
immUnbindProgram();
|
|
|
|
|
2016-12-05 02:50:28 -05:00
|
|
|
/* -- draw rotation center -- */
|
2017-02-28 03:09:44 -05:00
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
|
|
|
|
glPointSize(5.0f);
|
2016-12-05 02:50:28 -05:00
|
|
|
immBegin(GL_POINTS, 1);
|
|
|
|
immAttrib4ubv(col, color);
|
|
|
|
immVertex3fv(pos, o);
|
|
|
|
immEnd();
|
|
|
|
immUnbindProgram();
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* find screen coordinates for rotation center, then draw pretty icon */
|
|
|
|
mul_m4_v3(rv3d->persinv, rot_center);
|
|
|
|
UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
|
|
|
|
/* ^^ just playing around, does not work */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
}
|
|
|
|
#endif /* WITH_INPUT_NDOF */
|
|
|
|
|
2016-10-14 05:17:06 +00:00
|
|
|
/* ******************** non-meshes ***************** */
|
|
|
|
|
|
|
|
static void view3d_draw_non_mesh(
|
2017-02-08 12:26:41 +01:00
|
|
|
Scene *scene, SceneLayer *sl, Object *ob, Base *base, View3D *v3d,
|
2016-10-21 17:26:42 +00:00
|
|
|
RegionView3D *rv3d, const bool is_boundingbox, const unsigned char color[4])
|
2016-10-14 05:17:06 +00:00
|
|
|
{
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
|
|
|
|
/* multiply view with object matrix.
|
|
|
|
* local viewmat and persmat, to calculate projections */
|
|
|
|
ED_view3d_init_mats_rv3d_gl(ob, rv3d);
|
|
|
|
|
|
|
|
switch (ob->type) {
|
2016-10-21 17:26:42 +00:00
|
|
|
case OB_MESH:
|
|
|
|
case OB_FONT:
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
|
|
|
case OB_MBALL:
|
|
|
|
if (is_boundingbox) {
|
2017-03-06 20:55:58 +01:00
|
|
|
draw_bounding_volume(ob, ob->boundtype, color);
|
2016-10-21 17:26:42 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-10-14 05:17:06 +00:00
|
|
|
case OB_EMPTY:
|
2016-10-19 04:01:15 -04:00
|
|
|
drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, color);
|
2016-10-14 05:17:06 +00:00
|
|
|
break;
|
|
|
|
case OB_LAMP:
|
2017-02-08 12:26:41 +01:00
|
|
|
drawlamp(v3d, rv3d, base, OB_SOLID, DRAW_CONSTCOLOR, color, ob == OBACT_NEW);
|
2016-10-21 17:26:42 +00:00
|
|
|
break;
|
|
|
|
case OB_CAMERA:
|
|
|
|
drawcamera(scene, v3d, rv3d, base, DRAW_CONSTCOLOR, color);
|
|
|
|
break;
|
|
|
|
case OB_SPEAKER:
|
|
|
|
drawspeaker(color);
|
|
|
|
break;
|
|
|
|
case OB_LATTICE:
|
|
|
|
/* TODO */
|
|
|
|
break;
|
|
|
|
case OB_ARMATURE:
|
|
|
|
/* TODO */
|
2016-10-14 05:17:06 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* TODO Viewport: handle the other cases*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-10-21 17:26:42 +00:00
|
|
|
if (ob->rigidbody_object) {
|
2017-03-06 20:55:58 +01:00
|
|
|
draw_rigidbody_shape(ob, color);
|
2016-10-21 17:26:42 +00:00
|
|
|
}
|
|
|
|
|
2016-10-14 05:17:06 +00:00
|
|
|
ED_view3d_clear_mats_rv3d(rv3d);
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
/* ******************** info ***************** */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render and camera border
|
|
|
|
*/
|
|
|
|
static void view3d_draw_border(const bContext *C, ARegion *ar)
|
|
|
|
{
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
drawviewborder(scene, ar, v3d);
|
|
|
|
}
|
|
|
|
else if (v3d->flag2 & V3D_RENDER_BORDER) {
|
|
|
|
drawrenderborder(ar, v3d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Grease Pencil
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
|
2016-10-14 01:38:04 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Viewport Name
|
|
|
|
*/
|
|
|
|
static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
const char *name = NULL;
|
|
|
|
|
|
|
|
switch (rv3d->view) {
|
|
|
|
case RV3D_VIEW_FRONT:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
|
|
|
|
else name = IFACE_("Front Persp");
|
|
|
|
break;
|
|
|
|
case RV3D_VIEW_BACK:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
|
|
|
|
else name = IFACE_("Back Persp");
|
|
|
|
break;
|
|
|
|
case RV3D_VIEW_TOP:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
|
|
|
|
else name = IFACE_("Top Persp");
|
|
|
|
break;
|
|
|
|
case RV3D_VIEW_BOTTOM:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
|
|
|
|
else name = IFACE_("Bottom Persp");
|
|
|
|
break;
|
|
|
|
case RV3D_VIEW_RIGHT:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
|
|
|
|
else name = IFACE_("Right Persp");
|
|
|
|
break;
|
|
|
|
case RV3D_VIEW_LEFT:
|
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
|
|
|
|
else name = IFACE_("Left Persp");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
|
|
|
|
Camera *cam;
|
|
|
|
cam = v3d->camera->data;
|
|
|
|
if (cam->type == CAM_PERSP) {
|
|
|
|
name = IFACE_("Camera Persp");
|
|
|
|
}
|
|
|
|
else if (cam->type == CAM_ORTHO) {
|
|
|
|
name = IFACE_("Camera Ortho");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_assert(cam->type == CAM_PANO);
|
|
|
|
name = IFACE_("Camera Pano");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = IFACE_("Object as Camera");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
|
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
const char *name = view3d_get_name(v3d, rv3d);
|
|
|
|
/* increase size for unicode languages (Chinese in utf-8...) */
|
|
|
|
#ifdef WITH_INTERNATIONAL
|
|
|
|
char tmpstr[96];
|
|
|
|
#else
|
|
|
|
char tmpstr[32];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (v3d->localvd) {
|
|
|
|
BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
|
|
|
|
name = tmpstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
|
|
|
|
#ifdef WITH_INTERNATIONAL
|
|
|
|
BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
|
|
|
|
#else
|
|
|
|
BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* draw info beside axes in bottom left-corner:
|
|
|
|
* framenum, object name, bone name (if available), marker name (if available)
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
|
|
|
|
{
|
|
|
|
const int cfra = CFRA;
|
|
|
|
const char *msg_pin = " (Pinned)";
|
|
|
|
const char *msg_sep = " : ";
|
|
|
|
|
|
|
|
const int font_id = BLF_default();
|
|
|
|
|
|
|
|
char info[300];
|
|
|
|
char *s = info;
|
|
|
|
short offset = 1.5f * UI_UNIT_X + rect->xmin;
|
|
|
|
|
|
|
|
s += sprintf(s, "(%d)", cfra);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* info can contain:
|
|
|
|
* - a frame (7 + 2)
|
|
|
|
* - 3 object names (MAX_NAME)
|
|
|
|
* - 2 BREAD_CRUMB_SEPARATORs (6)
|
|
|
|
* - a SHAPE_KEY_PINNED marker and a trailing '\0' (9+1) - translated, so give some room!
|
|
|
|
* - a marker name (MAX_NAME + 3)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* get name of marker on current frame (if available) */
|
|
|
|
const char *markern = BKE_scene_find_marker_name(scene, cfra);
|
|
|
|
|
|
|
|
/* check if there is an object */
|
|
|
|
if (ob) {
|
|
|
|
*s++ = ' ';
|
|
|
|
s += BLI_strcpy_rlen(s, ob->id.name + 2);
|
|
|
|
|
|
|
|
/* name(s) to display depends on type of object */
|
|
|
|
if (ob->type == OB_ARMATURE) {
|
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
|
|
|
/* show name of active bone too (if possible) */
|
|
|
|
if (arm->edbo) {
|
|
|
|
if (arm->act_edbone) {
|
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_edbone->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ob->mode & OB_MODE_POSE) {
|
|
|
|
if (arm->act_bone) {
|
|
|
|
|
|
|
|
if (arm->act_bone->layer & arm->layer) {
|
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_bone->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
|
|
|
|
/* try to display active bone and active shapekey too (if they exist) */
|
|
|
|
|
|
|
|
if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
|
|
|
|
Object *armobj = BKE_object_pose_armature_get(ob);
|
|
|
|
if (armobj && armobj->mode & OB_MODE_POSE) {
|
|
|
|
bArmature *arm = armobj->data;
|
|
|
|
if (arm->act_bone) {
|
|
|
|
if (arm->act_bone->layer & arm->layer) {
|
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_bone->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Key *key = BKE_key_from_object(ob);
|
|
|
|
if (key) {
|
|
|
|
KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
|
|
|
|
if (kb) {
|
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, kb->name);
|
|
|
|
if (ob->shapeflag & OB_SHAPE_LOCK) {
|
|
|
|
s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* color depends on whether there is a keyframe */
|
|
|
|
if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
|
|
|
|
UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
|
|
|
|
else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
|
|
|
|
UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
|
|
|
|
else
|
|
|
|
UI_FontThemeColor(font_id, TH_TEXT_HI);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* no object */
|
|
|
|
if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
|
|
|
|
UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
|
|
|
|
else
|
|
|
|
UI_FontThemeColor(font_id, TH_TEXT_HI);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (markern) {
|
|
|
|
s += sprintf(s, " <%s>", markern);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (U.uiflag & USER_SHOW_ROTVIEWICON)
|
|
|
|
offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
|
|
|
|
|
|
|
|
BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
|
|
|
|
}
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/* ******************** view loop ***************** */
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* Set the correct matrices
|
|
|
|
*/
|
|
|
|
static void view3d_draw_setup_view(const bContext *C, ARegion *ar)
|
|
|
|
{
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
/* setup the view matrix */
|
|
|
|
if (view3d_stereo3d_active(C, scene, v3d, rv3d))
|
|
|
|
view3d_stereo3d_setup(scene, v3d, ar);
|
|
|
|
else
|
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth)
|
|
|
|
{
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
Render Layers and Collections (merge from render-layers)
Design Documents
----------------
* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers
* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised
User Commit Log
---------------
* New Layer and Collection system to replace render layers and viewport layers.
* A layer is a set of collections of objects (and their drawing options) required for specific tasks.
* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.
* All Scenes have a master collection that all other collections are children of.
* New collection "context" tab (in Properties Editor)
* New temporary viewport "collections" panel to control per-collection
visibility
Missing User Features
---------------------
* Collection "Filter"
Option to add objects based on their names
* Collection Manager operators
The existing buttons are placeholders
* Collection Manager drawing
The editor main region is empty
* Collection Override
* Per-Collection engine settings
This will come as a separate commit, as part of the clay-engine branch
Dev Commit Log
--------------
* New DNA file (DNA_layer_types.h) with the new structs
We are replacing Base by a new extended Base while keeping it backward
compatible with some legacy settings (i.e., lay, flag_legacy).
Renamed all Base to BaseLegacy to make it clear the areas of code that
still need to be converted
Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp
* Unittesting for main syncronization requirements
- read, write, add/copy/remove objects, copy scene, collection
link/unlinking, context)
* New Editor: Collection Manager
Based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following changes:
- Renamed references of layer manager to collections manager
- I doesn't include the editors/space_collections/ draw and util files
- The drawing code itself will be implemented separately by Julian
* Base / Object:
A little note about them. Original Blender code would try to keep them
in sync through the code, juggling flags back and forth. This will now
be handled by Depsgraph, keeping Object and Bases more separated
throughout the non-rendering code.
Scene.base is being cleared in doversion, and the old viewport drawing
code was poorly converted to use the new bases while the new viewport
code doesn't get merged and replace the old one.
Python API Changes
------------------
```
- scene.layers
+ # no longer exists
- scene.objects
+ scene.scene_layers.active.objects
- scene.objects.active
+ scene.render_layers.active.objects.active
- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()
- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)
- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')
-AddObjectHelper.layers
+ # no longer exists
```
2017-02-07 10:18:38 +01:00
|
|
|
SceneLayer *sl = CTX_data_scene_layer(C);
|
2016-10-07 01:45:28 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
if (only_depth)
|
|
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
|
|
|
|
if (only_depth || use_depth) {
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2016-10-25 04:39:55 -04:00
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
glDepthMask(GL_TRUE);
|
2016-10-07 01:45:28 +00:00
|
|
|
v3d->zbuf = true;
|
|
|
|
}
|
|
|
|
|
Render Layers and Collections (merge from render-layers)
Design Documents
----------------
* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers
* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised
User Commit Log
---------------
* New Layer and Collection system to replace render layers and viewport layers.
* A layer is a set of collections of objects (and their drawing options) required for specific tasks.
* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.
* All Scenes have a master collection that all other collections are children of.
* New collection "context" tab (in Properties Editor)
* New temporary viewport "collections" panel to control per-collection
visibility
Missing User Features
---------------------
* Collection "Filter"
Option to add objects based on their names
* Collection Manager operators
The existing buttons are placeholders
* Collection Manager drawing
The editor main region is empty
* Collection Override
* Per-Collection engine settings
This will come as a separate commit, as part of the clay-engine branch
Dev Commit Log
--------------
* New DNA file (DNA_layer_types.h) with the new structs
We are replacing Base by a new extended Base while keeping it backward
compatible with some legacy settings (i.e., lay, flag_legacy).
Renamed all Base to BaseLegacy to make it clear the areas of code that
still need to be converted
Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp
* Unittesting for main syncronization requirements
- read, write, add/copy/remove objects, copy scene, collection
link/unlinking, context)
* New Editor: Collection Manager
Based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following changes:
- Renamed references of layer manager to collections manager
- I doesn't include the editors/space_collections/ draw and util files
- The drawing code itself will be implemented separately by Julian
* Base / Object:
A little note about them. Original Blender code would try to keep them
in sync through the code, juggling flags back and forth. This will now
be handled by Depsgraph, keeping Object and Bases more separated
throughout the non-rendering code.
Scene.base is being cleared in doversion, and the old viewport drawing
code was poorly converted to use the new bases while the new viewport
code doesn't get merged and replace the old one.
Python API Changes
------------------
```
- scene.layers
+ # no longer exists
- scene.objects
+ scene.scene_layers.active.objects
- scene.objects.active
+ scene.render_layers.active.objects.active
- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()
- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)
- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')
-AddObjectHelper.layers
+ # no longer exists
```
2017-02-07 10:18:38 +01:00
|
|
|
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
|
|
|
if ((base->flag & BASE_VISIBLED) != 0) {
|
2016-10-07 01:45:28 +00:00
|
|
|
/* dupli drawing */
|
|
|
|
if (base->object->transflag & OB_DUPLI)
|
2017-02-08 12:26:41 +01:00
|
|
|
draw_dupli_objects(scene, sl, ar, v3d, base);
|
2016-10-07 01:45:28 +00:00
|
|
|
|
2017-02-08 12:26:41 +01:00
|
|
|
draw_object(scene, sl, ar, v3d, base, 0);
|
2016-10-07 01:45:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (only_depth)
|
|
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
|
|
|
2016-10-13 02:50:42 +00:00
|
|
|
if (only_depth || use_depth) {
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
v3d->zbuf = false;
|
|
|
|
}
|
2016-10-07 01:45:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw only the scene depth buffer
|
|
|
|
*/
|
|
|
|
static void draw_depth_buffer(const bContext *C, ARegion *ar)
|
|
|
|
{
|
|
|
|
draw_all_objects(C, ar, true, true);
|
|
|
|
}
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
/**
|
|
|
|
* Required if the shaders need it or external engines
|
|
|
|
* (e.g., Cycles requires depth buffer handled separately).
|
|
|
|
*/
|
2016-10-07 01:45:28 +00:00
|
|
|
static void view3d_draw_prerender_buffers(const bContext *C, ARegion *ar, DrawData *draw_data)
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
2016-10-12 23:31:44 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/* TODO viewport */
|
2016-10-12 23:31:44 +00:00
|
|
|
if (draw_data->is_render && ((!draw_data->clip_border) || (v3d->drawtype <= OB_WIRE))) {
|
2016-10-07 01:45:28 +00:00
|
|
|
draw_depth_buffer(C, ar);
|
|
|
|
}
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw all the plates that will fill the RGBD buffer
|
|
|
|
*/
|
2016-10-07 01:45:28 +00:00
|
|
|
static void view3d_draw_solid_plates(const bContext *C, ARegion *ar, DrawData *draw_data)
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
2016-10-07 01:45:28 +00:00
|
|
|
/* realtime plates */
|
|
|
|
if ((!draw_data->is_render) || draw_data->clip_border) {
|
|
|
|
view3d_draw_background(C);
|
|
|
|
view3d_draw_render_solid_surfaces(C, ar, true);
|
|
|
|
view3d_draw_render_transparent_surfaces(C);
|
|
|
|
view3d_draw_post_draw(C);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* offline plates*/
|
|
|
|
if (draw_data->is_render) {
|
2016-12-04 20:11:12 -05:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
view3d_draw_render_draw(C, scene, ar, v3d, draw_data->clip_border, &draw_data->border_rect);
|
|
|
|
}
|
2016-10-21 20:50:00 +00:00
|
|
|
|
2016-10-25 04:46:07 -04:00
|
|
|
#if VIEW3D_DRAW_DEBUG
|
2016-10-21 20:50:00 +00:00
|
|
|
view3d_draw_debug_post_solid(C, ar, draw_data);
|
2016-10-25 04:46:07 -04:00
|
|
|
#endif
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wires, outline, ...
|
|
|
|
*/
|
|
|
|
static void view3d_draw_geometry_overlay(const bContext *C)
|
|
|
|
{
|
|
|
|
view3d_draw_wire_plates(C);
|
|
|
|
view3d_draw_outline_plates(C);
|
|
|
|
}
|
|
|
|
|
2016-10-14 05:17:06 +00:00
|
|
|
/* drawing cameras, lamps, ... */
|
|
|
|
static void view3d_draw_non_meshes(const bContext *C, ARegion *ar)
|
|
|
|
{
|
|
|
|
/* TODO viewport
|
|
|
|
* for now we draw them all, in the near future
|
|
|
|
* we filter them based on the plates/layers
|
|
|
|
*/
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
Render Layers and Collections (merge from render-layers)
Design Documents
----------------
* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers
* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised
User Commit Log
---------------
* New Layer and Collection system to replace render layers and viewport layers.
* A layer is a set of collections of objects (and their drawing options) required for specific tasks.
* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.
* All Scenes have a master collection that all other collections are children of.
* New collection "context" tab (in Properties Editor)
* New temporary viewport "collections" panel to control per-collection
visibility
Missing User Features
---------------------
* Collection "Filter"
Option to add objects based on their names
* Collection Manager operators
The existing buttons are placeholders
* Collection Manager drawing
The editor main region is empty
* Collection Override
* Per-Collection engine settings
This will come as a separate commit, as part of the clay-engine branch
Dev Commit Log
--------------
* New DNA file (DNA_layer_types.h) with the new structs
We are replacing Base by a new extended Base while keeping it backward
compatible with some legacy settings (i.e., lay, flag_legacy).
Renamed all Base to BaseLegacy to make it clear the areas of code that
still need to be converted
Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp
* Unittesting for main syncronization requirements
- read, write, add/copy/remove objects, copy scene, collection
link/unlinking, context)
* New Editor: Collection Manager
Based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following changes:
- Renamed references of layer manager to collections manager
- I doesn't include the editors/space_collections/ draw and util files
- The drawing code itself will be implemented separately by Julian
* Base / Object:
A little note about them. Original Blender code would try to keep them
in sync through the code, juggling flags back and forth. This will now
be handled by Depsgraph, keeping Object and Bases more separated
throughout the non-rendering code.
Scene.base is being cleared in doversion, and the old viewport drawing
code was poorly converted to use the new bases while the new viewport
code doesn't get merged and replace the old one.
Python API Changes
------------------
```
- scene.layers
+ # no longer exists
- scene.objects
+ scene.scene_layers.active.objects
- scene.objects.active
+ scene.render_layers.active.objects.active
- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()
- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)
- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')
-AddObjectHelper.layers
+ # no longer exists
```
2017-02-07 10:18:38 +01:00
|
|
|
SceneLayer *sl = CTX_data_scene_layer(C);
|
2016-10-14 05:17:06 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
2016-10-21 17:26:42 +00:00
|
|
|
bool is_boundingbox = ((v3d->drawtype == OB_BOUNDBOX) ||
|
|
|
|
((v3d->drawtype == OB_RENDER) && (v3d->prev_drawtype == OB_BOUNDBOX)));
|
2016-10-14 05:17:06 +00:00
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2016-10-24 12:58:23 +00:00
|
|
|
glDepthMask(GL_TRUE);
|
2016-10-14 05:17:06 +00:00
|
|
|
/* TODO Viewport
|
|
|
|
* we are already temporarily writing to zbuffer in draw_object()
|
|
|
|
* for now let's avoid writing again to zbuffer to prevent glitches
|
|
|
|
*/
|
|
|
|
|
Render Layers and Collections (merge from render-layers)
Design Documents
----------------
* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers
* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised
User Commit Log
---------------
* New Layer and Collection system to replace render layers and viewport layers.
* A layer is a set of collections of objects (and their drawing options) required for specific tasks.
* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.
* All Scenes have a master collection that all other collections are children of.
* New collection "context" tab (in Properties Editor)
* New temporary viewport "collections" panel to control per-collection
visibility
Missing User Features
---------------------
* Collection "Filter"
Option to add objects based on their names
* Collection Manager operators
The existing buttons are placeholders
* Collection Manager drawing
The editor main region is empty
* Collection Override
* Per-Collection engine settings
This will come as a separate commit, as part of the clay-engine branch
Dev Commit Log
--------------
* New DNA file (DNA_layer_types.h) with the new structs
We are replacing Base by a new extended Base while keeping it backward
compatible with some legacy settings (i.e., lay, flag_legacy).
Renamed all Base to BaseLegacy to make it clear the areas of code that
still need to be converted
Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp
* Unittesting for main syncronization requirements
- read, write, add/copy/remove objects, copy scene, collection
link/unlinking, context)
* New Editor: Collection Manager
Based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following changes:
- Renamed references of layer manager to collections manager
- I doesn't include the editors/space_collections/ draw and util files
- The drawing code itself will be implemented separately by Julian
* Base / Object:
A little note about them. Original Blender code would try to keep them
in sync through the code, juggling flags back and forth. This will now
be handled by Depsgraph, keeping Object and Bases more separated
throughout the non-rendering code.
Scene.base is being cleared in doversion, and the old viewport drawing
code was poorly converted to use the new bases while the new viewport
code doesn't get merged and replace the old one.
Python API Changes
------------------
```
- scene.layers
+ # no longer exists
- scene.objects
+ scene.scene_layers.active.objects
- scene.objects.active
+ scene.render_layers.active.objects.active
- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()
- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)
- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')
-AddObjectHelper.layers
+ # no longer exists
```
2017-02-07 10:18:38 +01:00
|
|
|
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
|
|
|
if ((base->flag & BASE_VISIBLED) != 0) {
|
2016-10-14 05:17:06 +00:00
|
|
|
Object *ob = base->object;
|
|
|
|
|
2016-12-04 20:11:12 -05:00
|
|
|
unsigned char ob_wire_col[4];
|
2017-02-08 12:26:41 +01:00
|
|
|
draw_object_wire_color(scene, sl, base, ob_wire_col);
|
|
|
|
view3d_draw_non_mesh(scene, sl, ob, base, v3d, rv3d, is_boundingbox, ob_wire_col);
|
2016-10-14 05:17:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 12:58:23 +00:00
|
|
|
glDepthMask(GL_FALSE);
|
2016-10-14 05:17:06 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/**
|
2016-10-14 05:17:06 +00:00
|
|
|
* Parent lines, grid, ...
|
2016-10-06 14:14:41 +00:00
|
|
|
*/
|
2016-10-06 19:55:06 +00:00
|
|
|
static void view3d_draw_other_elements(const bContext *C, ARegion *ar)
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
2016-10-06 19:55:06 +00:00
|
|
|
view3d_draw_grid(C, ar);
|
2016-12-05 02:50:28 -05:00
|
|
|
|
|
|
|
#ifdef WITH_INPUT_NDOF
|
2017-01-11 09:42:48 +01:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
2016-12-05 02:50:28 -05:00
|
|
|
if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) && (rv3d->persp != RV3D_CAMOB))
|
|
|
|
/* TODO: draw something else (but not this) during fly mode */
|
|
|
|
draw_rotation_guide(rv3d);
|
|
|
|
#endif
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* Paint brushes, armatures, ...
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_tool_ui(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* Blueprint images
|
|
|
|
*/
|
2017-01-10 18:17:29 +01:00
|
|
|
static void view3d_draw_reference_images(const bContext *UNUSED(C))
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO viewport */
|
|
|
|
}
|
|
|
|
|
2016-10-13 02:50:42 +00:00
|
|
|
/**
|
|
|
|
* 3D manipulators
|
|
|
|
*/
|
|
|
|
static void view3d_draw_manipulator(const bContext *C)
|
|
|
|
{
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
v3d->zbuf = false;
|
|
|
|
BIF_draw_manipulator(C);
|
|
|
|
}
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/**
|
2016-10-14 01:38:04 +00:00
|
|
|
* Information drawn on top of the solid plates and composed data
|
|
|
|
*/
|
2017-02-14 17:47:11 +01:00
|
|
|
void view3d_draw_region_info(const bContext *C, ARegion *ar)
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
2017-02-14 17:47:11 +01:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
/* correct projection matrix */
|
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
|
|
|
|
/* local coordinate visible rect inside region, to accomodate overlapping ui */
|
2016-12-05 02:50:28 -05:00
|
|
|
rcti rect;
|
2016-10-14 01:38:04 +00:00
|
|
|
ED_region_visible_rect(ar, &rect);
|
|
|
|
|
|
|
|
view3d_draw_border(C, ar);
|
|
|
|
view3d_draw_grease_pencil(C);
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
if (U.uiflag & USER_SHOW_ROTVIEWICON) {
|
|
|
|
draw_view_axis(rv3d, &rect);
|
|
|
|
}
|
2016-12-05 02:50:28 -05:00
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
|
|
|
|
ED_scene_draw_fps(scene, &rect);
|
|
|
|
}
|
|
|
|
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
|
|
|
|
draw_viewport_name(ar, v3d, &rect);
|
2016-12-05 02:50:28 -05:00
|
|
|
}
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
if (U.uiflag & USER_DRAWVIEWINFO) {
|
|
|
|
SceneLayer *sl = CTX_data_scene_layer(C);
|
|
|
|
Object *ob = OBACT_NEW;
|
|
|
|
draw_selected_name(scene, ob, &rect);
|
2016-12-05 02:50:28 -05:00
|
|
|
}
|
2017-02-14 17:47:11 +01:00
|
|
|
#if 0 /* TODO */
|
|
|
|
if (grid_unit) { /* draw below the viewport name */
|
|
|
|
char numstr[32] = "";
|
2016-12-05 02:50:28 -05:00
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
|
|
|
|
if (v3d->grid != 1.0f) {
|
|
|
|
BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLF_draw_default_ascii(rect.xmin + U.widget_unit,
|
|
|
|
rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
|
|
|
|
numstr[0] ? numstr : grid_unit, sizeof(numstr));
|
|
|
|
}
|
|
|
|
#endif
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-10-06 19:55:06 +00:00
|
|
|
* This could run once per view, or even in parallel
|
|
|
|
* for each of them. What is a "view"?
|
|
|
|
* - a viewport with the camera elsewhere
|
|
|
|
* - left/right stereo
|
|
|
|
* - panorama / fisheye individual cubemap faces
|
|
|
|
*/
|
2016-10-07 01:45:28 +00:00
|
|
|
static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data)
|
2016-10-06 14:14:41 +00:00
|
|
|
{
|
|
|
|
/* TODO - Technically this should be drawn to a few FBO, so we can handle
|
|
|
|
* compositing better, but for now this will get the ball rolling (dfelinto) */
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
view3d_draw_setup_view(C, ar);
|
2016-10-07 01:45:28 +00:00
|
|
|
view3d_draw_prerender_buffers(C, ar, draw_data);
|
|
|
|
view3d_draw_solid_plates(C, ar, draw_data);
|
2016-10-06 14:14:41 +00:00
|
|
|
view3d_draw_geometry_overlay(C);
|
2016-10-14 05:17:06 +00:00
|
|
|
view3d_draw_non_meshes(C, ar);
|
2016-10-06 19:55:06 +00:00
|
|
|
view3d_draw_other_elements(C, ar);
|
2016-10-06 14:14:41 +00:00
|
|
|
view3d_draw_tool_ui(C);
|
|
|
|
view3d_draw_reference_images(C);
|
2016-10-13 02:50:42 +00:00
|
|
|
view3d_draw_manipulator(C);
|
2016-10-14 01:38:04 +00:00
|
|
|
view3d_draw_region_info(C, ar);
|
2016-10-25 04:46:07 -04:00
|
|
|
|
|
|
|
#if VIEW3D_DRAW_DEBUG
|
2016-10-21 20:50:00 +00:00
|
|
|
view3d_draw_debug(C, ar, draw_data);
|
2016-10-25 04:46:07 -04:00
|
|
|
#endif
|
2016-10-06 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
static void view3d_draw_view_new(const bContext *C, ARegion *ar, DrawData *UNUSED(draw_data))
|
|
|
|
{
|
|
|
|
view3d_draw_setup_view(C, ar);
|
|
|
|
|
|
|
|
/* Only 100% compliant on new spec goes bellow */
|
2017-03-08 20:00:09 +01:00
|
|
|
DRW_draw_view(C);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
2016-10-04 20:00:46 +00:00
|
|
|
void view3d_main_region_draw(const bContext *C, ARegion *ar)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2017-02-07 11:20:15 +01:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2016-10-04 20:00:46 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2016-10-13 04:22:28 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2017-02-07 11:20:15 +01:00
|
|
|
/* TODO layers - In the future we should get RE from Layers */
|
|
|
|
RenderEngineType *type = RE_engines_find(scene->r.engine);
|
2013-02-20 08:39:31 +00:00
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
if (IS_VIEWPORT_LEGACY(v3d) && ((type->flag & RE_USE_OGL_PIPELINE) == 0)) {
|
2016-10-04 20:00:46 +00:00
|
|
|
view3d_main_region_draw_legacy(C, ar);
|
|
|
|
return;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2016-10-13 04:22:28 +00:00
|
|
|
if (!rv3d->viewport)
|
|
|
|
rv3d->viewport = GPU_viewport_create();
|
|
|
|
|
2016-10-06 14:14:41 +00:00
|
|
|
/* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
|
|
|
|
* before we even call the drawing routine, but let's move on for now (dfelinto)
|
|
|
|
* but this is a provisory way to start seeing things in the viewport */
|
2016-10-07 01:45:28 +00:00
|
|
|
DrawData draw_data;
|
2016-10-21 20:50:00 +00:00
|
|
|
view3d_draw_data_init(C, ar, rv3d, &draw_data);
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2017-03-08 20:00:09 +01:00
|
|
|
GPU_viewport_bind(rv3d->viewport, &ar->winrct);
|
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
if (type->flag & RE_USE_OGL_PIPELINE)
|
|
|
|
view3d_draw_view_new(C, ar, &draw_data);
|
|
|
|
else
|
|
|
|
view3d_draw_view(C, ar, &draw_data);
|
|
|
|
|
2016-10-07 01:45:28 +00:00
|
|
|
v3d->flag |= V3D_INVALID_BACKBUF;
|
2016-10-06 19:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** legacy interface ***************** */
|
|
|
|
/**
|
|
|
|
* This will be removed once the viewport gets replaced
|
|
|
|
* meanwhile it should keep the old viewport working.
|
|
|
|
*/
|
|
|
|
|
2017-03-02 15:03:02 +01:00
|
|
|
void VP_legacy_drawcursor(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
|
2016-12-05 02:50:28 -05:00
|
|
|
{
|
2017-03-02 15:03:02 +01:00
|
|
|
if (is_cursor_visible(scene, sl)) {
|
2016-12-05 02:50:28 -05:00
|
|
|
drawcursor(scene, ar, v3d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect)
|
|
|
|
{
|
|
|
|
draw_view_axis(rv3d, rect);
|
|
|
|
}
|
|
|
|
|
2017-02-14 17:47:11 +01:00
|
|
|
void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
|
|
|
|
{
|
|
|
|
draw_viewport_name(ar, v3d, rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect)
|
|
|
|
{
|
|
|
|
draw_selected_name(scene, ob, rect);
|
|
|
|
}
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
|
|
|
|
{
|
|
|
|
drawgrid(unit, ar, v3d, grid_unit);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2016-10-06 19:55:06 +00:00
|
|
|
void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
|
|
|
|
{
|
|
|
|
drawfloor(scene, v3d, grid_unit, write_depth);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
|
|
|
|
{
|
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
return view3d_stereo3d_active(C, scene, v3d, rv3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
|
|
|
|
{
|
|
|
|
view3d_stereo3d_setup(scene, v3d, ar);
|
|
|
|
}
|
2016-10-07 01:45:28 +00:00
|
|
|
|
|
|
|
bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
|
|
|
|
{
|
|
|
|
return use_depth_doit(scene, v3d);
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
2016-10-14 01:24:27 +00:00
|
|
|
|
2016-10-14 01:38:04 +00:00
|
|
|
void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
|
|
|
|
{
|
|
|
|
drawviewborder(scene, ar, v3d);
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:24:27 +00:00
|
|
|
void VP_drawrenderborder(ARegion *ar, View3D *v3d)
|
|
|
|
{
|
|
|
|
drawrenderborder(ar, v3d);
|
|
|
|
}
|
2016-10-24 18:58:12 +00:00
|
|
|
|
|
|
|
void VP_view3d_draw_background_none(void)
|
|
|
|
{
|
|
|
|
view3d_draw_background_none();
|
|
|
|
}
|
|
|
|
|
|
|
|
void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
|
|
|
|
{
|
|
|
|
view3d_draw_background_world(scene, v3d, rv3d);
|
|
|
|
}
|