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
|
|
|
|
*/
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "DNA_camera_types.h"
|
2009-01-07 14:46:50 +00:00
|
|
|
#include "DNA_customdata_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_object_types.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "DNA_group_types.h"
|
2014-06-19 04:01:19 +10:00
|
|
|
#include "DNA_mesh_types.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "DNA_key_types.h"
|
2009-06-08 20:08:19 +00:00
|
|
|
#include "DNA_lamp_types.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_world_types.h"
|
2015-02-17 03:26:03 +01:00
|
|
|
#include "DNA_brush_types.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2018-02-18 21:27:33 +11:00
|
|
|
#include "BLI_jitter_2d.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2012-09-03 07:37:38 +00:00
|
|
|
#include "BLI_endian_switch.h"
|
2015-04-06 10:40:12 -03:00
|
|
|
#include "BLI_threads.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
#include "BKE_anim.h"
|
2011-11-05 13:00:39 +00:00
|
|
|
#include "BKE_camera.h"
|
2.5
New: Custom region draw callbacks.
For Martin: an example is now in space_view3d/view3d_edit.c
On middlemouse rotate view, it draws a small square in center.
It works likes this:
#include "ED_space_api.h"
handle= ED_region_draw_cb_activate(region->type, drawfunc, type)
and to stop it:
ED_region_draw_cb_exit(region->type, handle)
drawfunc is of type (const bContext *C, ARegion *ar)
currently it gets called only as type REGION_DRAW_POST, later we
can add more (PRE, POST_XRAY, POST_2D, etc).
For correct usage, these calls should return leaving view transform
unaltered.
2009-01-09 15:04:52 +00:00
|
|
|
#include "BKE_context.h"
|
2009-01-07 14:46:50 +00:00
|
|
|
#include "BKE_customdata.h"
|
2015-04-02 17:13:24 +02:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "BKE_image.h"
|
|
|
|
#include "BKE_key.h"
|
2013-12-26 17:24:42 +06:00
|
|
|
#include "BKE_main.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "BKE_object.h"
|
|
|
|
#include "BKE_global.h"
|
2009-08-15 19:48:50 +00:00
|
|
|
#include "BKE_paint.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
#include "BKE_scene.h"
|
2011-05-20 04:14:29 +00:00
|
|
|
#include "BKE_screen.h"
|
2009-08-12 14:11:53 +00:00
|
|
|
#include "BKE_unit.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BKE_movieclip.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2011-11-02 18:20:53 +00:00
|
|
|
#include "RE_engine.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
#include "IMB_imbuf.h"
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
#include "IMB_colormanagement.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
#include "BIF_glutil.h"
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
2013-02-19 15:45:56 +00:00
|
|
|
|
2009-05-05 23:10:32 +00:00
|
|
|
#include "BLF_api.h"
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2009-01-07 14:46:50 +00:00
|
|
|
#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"
|
2.5
New: Custom region draw callbacks.
For Martin: an example is now in space_view3d/view3d_edit.c
On middlemouse rotate view, it draws a small square in center.
It works likes this:
#include "ED_space_api.h"
handle= ED_region_draw_cb_activate(region->type, drawfunc, type)
and to stop it:
ED_region_draw_cb_exit(region->type, handle)
drawfunc is of type (const bContext *C, ARegion *ar)
currently it gets called only as type REGION_DRAW_POST, later we
can add more (PRE, POST_XRAY, POST_2D, etc).
For correct usage, these calls should return leaving view transform
unaltered.
2009-01-09 15:04:52 +00:00
|
|
|
#include "ED_space_api.h"
|
2010-02-12 00:44:26 +00:00
|
|
|
#include "ED_screen_types.h"
|
2009-07-08 16:17:47 +00:00
|
|
|
#include "ED_transform.h"
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
#include "UI_interface_icons.h"
|
|
|
|
#include "UI_resources.h"
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "GPU_draw.h"
|
2015-12-06 21:20:19 +01:00
|
|
|
#include "GPU_framebuffer.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "GPU_material.h"
|
2015-02-12 18:54:41 +01:00
|
|
|
#include "GPU_compositing.h"
|
World textures displaying for viewport in BI.
This patch supports "Image or Movie" and "Environment map" types of world texture for the viewport.
It supports:
- "View", "AngMap" and "Equirectangular" types of mapping.
- Different types of texture blending (according to BI world render).
- Same color blending as when it lacked textures (but render via glsl).
{F207734}
{F207735}
Example: {F275180}
Original author: @valentin_b4w
Regards,
Alexander (Blend4Web Team).
Reviewers: sergey, valentin_b4w, brecht, merwin
Reviewed By: merwin
Subscribers: campbellbarton, merwin, blueprintrandom, youle, a.romanov, yurikovelenov, AlexKowel, Evgeny_Rodygin
Projects: #rendering, #opengl_gfx, #bf_blender:_next
Differential Revision: https://developer.blender.org/D1414
2016-01-27 12:06:57 +03:00
|
|
|
#include "GPU_extensions.h"
|
2017-03-10 03:15:58 +11:00
|
|
|
#include "GPU_select.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
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
/* prototypes */
|
2017-05-09 19:21:22 +02:00
|
|
|
static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
|
2017-05-10 16:54:01 +02:00
|
|
|
static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect);
|
2015-04-06 10:40:12 -03:00
|
|
|
static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
|
|
|
|
float winmat[4][4], const char *viewname);
|
|
|
|
|
2012-11-16 07:56:47 +00:00
|
|
|
/* handy utility for drawing shapes in the viewport for arbitrary code.
|
|
|
|
* could add lines and points too */
|
|
|
|
// #define DEBUG_DRAW
|
|
|
|
#ifdef DEBUG_DRAW
|
|
|
|
static void bl_debug_draw(void);
|
|
|
|
/* add these locally when using these functions for testing */
|
|
|
|
extern void bl_debug_draw_quad_clear(void);
|
|
|
|
extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
|
|
|
|
extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]);
|
2014-01-14 03:58:06 +11:00
|
|
|
extern void bl_debug_color_set(const unsigned int col);
|
2012-11-16 07:56:47 +00:00
|
|
|
#endif
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
void circf(float x, float y, float rad)
|
|
|
|
{
|
|
|
|
GLUquadricObj *qobj = gluNewQuadric();
|
|
|
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_FILL);
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
2012-04-11 08:15:13 +00:00
|
|
|
glTranslatef(x, y, 0.0);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
gluDisk(qobj, 0.0, rad, 32, 1);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
void circ(float x, float y, float rad)
|
|
|
|
{
|
|
|
|
GLUquadricObj *qobj = gluNewQuadric();
|
|
|
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
2012-04-11 08:15:13 +00:00
|
|
|
glTranslatef(x, y, 0.0);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
gluDisk(qobj, 0.0, rad, 32, 1);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ********* custom clipping *********** */
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
static void view3d_draw_clipping(RegionView3D *rv3d)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
BoundBox *bb = rv3d->clipbb;
|
2011-09-11 02:50:01 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bb) {
|
2014-04-27 07:50:08 +10:00
|
|
|
const unsigned int clipping_index[6][4] = {
|
2012-06-16 09:18:00 +00:00
|
|
|
{0, 1, 2, 3},
|
|
|
|
{0, 4, 5, 1},
|
|
|
|
{4, 7, 6, 5},
|
|
|
|
{7, 3, 2, 6},
|
|
|
|
{1, 5, 6, 2},
|
|
|
|
{7, 4, 0, 3}
|
|
|
|
};
|
2011-09-11 02:50:01 +00:00
|
|
|
|
2012-05-22 08:24:52 +00:00
|
|
|
/* fill in zero alpha for rendering & re-projection [#31530] */
|
|
|
|
unsigned char col[4];
|
2015-01-28 13:03:42 +01:00
|
|
|
UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
|
2012-05-22 08:24:52 +00:00
|
|
|
glColor4ubv(col);
|
2011-09-11 02:50:01 +00:00
|
|
|
|
2015-01-28 13:03:42 +01:00
|
|
|
glEnable(GL_BLEND);
|
2011-09-11 02:50:01 +00:00
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, bb->vec);
|
2012-03-25 23:54:33 +00:00
|
|
|
glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
|
2011-09-11 02:50:01 +00:00
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
2015-01-28 13:03:42 +01:00
|
|
|
glDisable(GL_BLEND);
|
2009-01-20 18:31:11 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-28 13:03:56 +00:00
|
|
|
void ED_view3d_clipping_set(RegionView3D *rv3d)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
|
|
|
double plane[4];
|
2013-05-08 13:01:05 +00:00
|
|
|
const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
|
2012-02-28 13:03:56 +00:00
|
|
|
unsigned int a;
|
|
|
|
|
|
|
|
for (a = 0; a < tot; a++) {
|
2012-03-09 06:04:17 +00:00
|
|
|
copy_v4db_v4fl(plane, rv3d->clip[a]);
|
2012-02-28 13:03:56 +00:00
|
|
|
glClipPlane(GL_CLIP_PLANE0 + a, plane);
|
|
|
|
glEnable(GL_CLIP_PLANE0 + a);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-28 13:03:56 +00:00
|
|
|
/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
|
|
|
|
void ED_view3d_clipping_disable(void)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-02-28 13:03:56 +00:00
|
|
|
unsigned int a;
|
|
|
|
|
|
|
|
for (a = 0; a < 6; a++) {
|
|
|
|
glDisable(GL_CLIP_PLANE0 + a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void ED_view3d_clipping_enable(void)
|
|
|
|
{
|
|
|
|
unsigned int a;
|
|
|
|
|
|
|
|
for (a = 0; a < 6; a++) {
|
|
|
|
glEnable(GL_CLIP_PLANE0 + a);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-21 22:34:20 +11:00
|
|
|
static bool view3d_clipping_test(const float co[3], const float clip[6][4])
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2013-08-22 15:30:24 +00:00
|
|
|
if (plane_point_side_v3(clip[0], co) > 0.0f)
|
|
|
|
if (plane_point_side_v3(clip[1], co) > 0.0f)
|
|
|
|
if (plane_point_side_v3(clip[2], co) > 0.0f)
|
|
|
|
if (plane_point_side_v3(clip[3], co) > 0.0f)
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2009-11-21 16:44:05 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-28 13:03:56 +00:00
|
|
|
/* for 'local' ED_view3d_clipping_local must run first
|
2009-11-21 16:44:05 +00:00
|
|
|
* then all comparisons can be done in localspace */
|
2015-03-21 22:34:20 +11:00
|
|
|
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
|
2009-11-21 16:44:05 +00:00
|
|
|
{
|
2013-03-04 07:15:09 +00:00
|
|
|
return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
|
2009-11-21 16:44:05 +00:00
|
|
|
}
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* ********* end custom clipping *********** */
|
|
|
|
|
|
|
|
|
2012-03-08 11:57:51 +00:00
|
|
|
static void drawgrid_draw(ARegion *ar, double wx, double wy, double x, double y, double dx)
|
2010-07-30 08:43:22 +00:00
|
|
|
{
|
2012-03-08 11:57:51 +00:00
|
|
|
double verts[2][2];
|
2010-07-30 08:43:22 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
x += (wx);
|
|
|
|
y += (wy);
|
2010-07-30 08:43:22 +00:00
|
|
|
|
2011-09-11 04:31:09 +00:00
|
|
|
/* set fixed 'Y' */
|
2012-03-25 23:54:33 +00:00
|
|
|
verts[0][1] = 0.0f;
|
|
|
|
verts[1][1] = (double)ar->winy;
|
2010-07-30 08:43:22 +00:00
|
|
|
|
2011-09-11 04:31:09 +00:00
|
|
|
/* iter over 'X' */
|
2012-09-30 06:12:47 +00:00
|
|
|
verts[0][0] = verts[1][0] = x - dx * floor(x / dx);
|
2011-09-11 04:31:09 +00:00
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
2012-03-08 11:57:51 +00:00
|
|
|
glVertexPointer(2, GL_DOUBLE, 0, verts);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (verts[0][0] < ar->winx) {
|
2011-09-11 04:31:09 +00:00
|
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
|
|
verts[0][0] = verts[1][0] = verts[0][0] + dx;
|
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2011-09-11 04:31:09 +00:00
|
|
|
/* set fixed 'X' */
|
2012-03-25 23:54:33 +00:00
|
|
|
verts[0][0] = 0.0f;
|
|
|
|
verts[1][0] = (double)ar->winx;
|
2010-07-30 08:43:22 +00:00
|
|
|
|
2011-09-11 04:31:09 +00:00
|
|
|
/* iter over 'Y' */
|
2012-09-30 06:12:47 +00:00
|
|
|
verts[0][1] = verts[1][1] = y - dx * floor(y / dx);
|
2012-02-22 16:52:06 +00:00
|
|
|
while (verts[0][1] < ar->winy) {
|
2011-09-11 04:31:09 +00:00
|
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
|
|
verts[0][1] = verts[1][1] = verts[0][1] + dx;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2011-09-11 04:31:09 +00:00
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2012-05-24 21:58:12 +00:00
|
|
|
#define GRID_MIN_PX_D 6.0
|
|
|
|
#define GRID_MIN_PX_F 6.0f
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2010-11-23 14:14:06 +00:00
|
|
|
static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
|
|
|
/* extern short bgpicmode; */
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2012-03-08 11:57:51 +00:00
|
|
|
double wx, wy, x, y, fw, fx, fy, dx;
|
|
|
|
double vec4[4];
|
2010-12-20 03:59:22 +00:00
|
|
|
unsigned char col[3], col2[3];
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
fx = rv3d->persmat[3][0];
|
|
|
|
fy = rv3d->persmat[3][1];
|
|
|
|
fw = rv3d->persmat[3][3];
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wx = (ar->winx / 2.0); /* because of rounding errors, grid at wrong location */
|
|
|
|
wy = (ar->winy / 2.0);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
x = (wx) * fx / fw;
|
|
|
|
y = (wy) * fy / fw;
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
vec4[0] = vec4[1] = v3d->grid;
|
2009-08-12 17:02:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
vec4[2] = 0.0;
|
|
|
|
vec4[3] = 1.0;
|
2012-03-08 11:57:51 +00:00
|
|
|
mul_m4_v4d(rv3d->persmat, vec4);
|
2012-03-25 23:54:33 +00:00
|
|
|
fx = vec4[0];
|
|
|
|
fy = vec4[1];
|
|
|
|
fw = vec4[3];
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
dx = fabs(x - (wx) * fx / fw);
|
|
|
|
if (dx == 0) dx = fabs(y - (wy) * fy / fw);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2016-01-24 20:30:41 +11:00
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
2015-02-13 11:52:27 +01:00
|
|
|
glDepthMask(GL_FALSE); /* disable write in zbuffer */
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
/* check zoom out */
|
|
|
|
UI_ThemeColor(TH_GRID);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (unit->system) {
|
2013-01-08 01:48:14 +00:00
|
|
|
/* Use GRID_MIN_PX * 2 for units because very very small grid
|
2009-08-12 17:02:03 +00:00
|
|
|
* items are less useful when dealing with units */
|
2016-05-03 13:52:07 +10:00
|
|
|
const void *usys;
|
2009-08-12 14:11:53 +00:00
|
|
|
int len, i;
|
2012-03-08 11:57:51 +00:00
|
|
|
double dx_scalar;
|
2009-08-12 14:11:53 +00:00
|
|
|
float blend_fac;
|
|
|
|
|
2016-05-03 13:52:07 +10:00
|
|
|
bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (usys) {
|
2012-03-25 23:54:33 +00:00
|
|
|
i = len;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (i--) {
|
2012-03-25 23:54:33 +00:00
|
|
|
double scalar = bUnit_GetScaler(usys, i);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2012-05-24 21:58:12 +00:00
|
|
|
dx_scalar = dx * scalar / (double)unit->scale_length;
|
|
|
|
if (dx_scalar < (GRID_MIN_PX_D * 2.0))
|
2009-08-12 14:11:53 +00:00
|
|
|
continue;
|
|
|
|
|
2009-08-12 17:02:03 +00:00
|
|
|
/* Store the smallest drawn grid size units name so users know how big each grid cell is */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (*grid_unit == NULL) {
|
|
|
|
*grid_unit = bUnit_GetNameDisplay(usys, i);
|
2012-05-24 21:58:12 +00:00
|
|
|
rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
|
2009-08-12 17:02:03 +00:00
|
|
|
}
|
2012-05-24 21:58:12 +00:00
|
|
|
blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
|
|
|
/* tweak to have the fade a bit nicer */
|
2012-03-25 23:54:33 +00:00
|
|
|
blend_fac = (blend_fac * blend_fac) * 2.0f;
|
2009-08-12 14:11:53 +00:00
|
|
|
CLAMP(blend_fac, 0.3f, 1.0f);
|
|
|
|
|
|
|
|
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2013-08-06 07:10:18 +00:00
|
|
|
const double sublines = v3d->gridsubdiv;
|
|
|
|
const float sublines_fl = v3d->gridsubdiv;
|
2009-08-12 17:02:03 +00:00
|
|
|
|
2012-05-24 21:58:12 +00:00
|
|
|
if (dx < GRID_MIN_PX_D) {
|
2013-08-06 07:10:18 +00:00
|
|
|
rv3d->gridview *= sublines_fl;
|
2012-03-25 23:54:33 +00:00
|
|
|
dx *= sublines;
|
|
|
|
|
2012-05-24 21:58:12 +00:00
|
|
|
if (dx < GRID_MIN_PX_D) {
|
2013-08-06 07:10:18 +00:00
|
|
|
rv3d->gridview *= sublines_fl;
|
2012-03-25 23:54:33 +00:00
|
|
|
dx *= sublines;
|
|
|
|
|
2012-05-24 21:58:12 +00:00
|
|
|
if (dx < GRID_MIN_PX_D) {
|
2013-08-06 07:10:18 +00:00
|
|
|
rv3d->gridview *= sublines_fl;
|
2012-03-25 23:54:33 +00:00
|
|
|
dx *= sublines;
|
2012-10-07 09:48:59 +00:00
|
|
|
if (dx < GRID_MIN_PX_D) {
|
|
|
|
/* pass */
|
|
|
|
}
|
2009-08-12 14:11:53 +00:00
|
|
|
else {
|
|
|
|
UI_ThemeColor(TH_GRID);
|
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
|
|
|
}
|
|
|
|
}
|
2012-07-08 20:36:00 +00:00
|
|
|
else { /* start blending out */
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
|
2008-12-18 17:38:21 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
|
|
|
UI_ThemeColor(TH_GRID);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-08 01:48:14 +00:00
|
|
|
else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
|
2008-12-18 17:38:21 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
UI_ThemeColor(TH_GRID);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-08-12 14:11:53 +00:00
|
|
|
else {
|
2012-07-08 20:36:00 +00:00
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
|
2013-08-06 07:10:18 +00:00
|
|
|
rv3d->gridview /= sublines_fl;
|
2012-03-25 23:54:33 +00:00
|
|
|
dx /= sublines;
|
2012-07-08 20:36:00 +00:00
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
|
2013-08-06 07:10:18 +00:00
|
|
|
rv3d->gridview /= sublines_fl;
|
2012-03-25 23:54:33 +00:00
|
|
|
dx /= sublines;
|
2012-05-24 21:58:12 +00:00
|
|
|
if (dx > (GRID_MIN_PX_D * 10.0)) {
|
2009-08-12 14:11:53 +00:00
|
|
|
UI_ThemeColor(TH_GRID);
|
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
|
|
|
}
|
|
|
|
else {
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
|
2009-08-12 14:11:53 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
|
|
|
UI_ThemeColor(TH_GRID);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
|
2009-08-12 14:11:53 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
|
2008-12-18 17:38:21 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
|
|
|
UI_ThemeColor(TH_GRID);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2013-02-18 13:43:18 +00:00
|
|
|
UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
|
2008-12-18 17:38:21 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx);
|
2009-08-12 14:11:53 +00:00
|
|
|
UI_ThemeColor(TH_GRID);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-12 14:11:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
x += (wx);
|
|
|
|
y += (wy);
|
2008-12-18 17:38:21 +00:00
|
|
|
UI_GetThemeColor3ubv(TH_GRID, col);
|
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
/* center cross */
|
2010-12-20 13:32:26 +00:00
|
|
|
/* horizontal line */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
|
2010-12-20 03:59:22 +00:00
|
|
|
UI_make_axis_color(col, col2, 'Y');
|
2010-12-20 13:32:26 +00:00
|
|
|
else UI_make_axis_color(col, col2, 'X');
|
2010-12-20 03:59:22 +00:00
|
|
|
glColor3ubv(col2);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
fdrawline(0.0, y, (float)ar->winx, y);
|
|
|
|
|
2010-12-20 13:32:26 +00:00
|
|
|
/* vertical line */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
|
2010-12-20 03:59:22 +00:00
|
|
|
UI_make_axis_color(col, col2, 'Y');
|
|
|
|
else UI_make_axis_color(col, col2, 'Z');
|
|
|
|
glColor3ubv(col2);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
fdrawline(x, 0.0, x, (float)ar->winy);
|
|
|
|
|
2015-02-13 11:52:27 +01:00
|
|
|
glDepthMask(GL_TRUE); /* enable write in zbuffer */
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2009-08-12 14:11:53 +00:00
|
|
|
#undef GRID_MIN_PX
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-12-09 10:48:18 +00:00
|
|
|
/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
|
|
|
|
float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2010-11-23 17:14:03 +00:00
|
|
|
/* apply units */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (scene->unit.system) {
|
2016-05-03 13:52:07 +10:00
|
|
|
const void *usys;
|
2010-11-23 17:14:03 +00:00
|
|
|
int len;
|
|
|
|
|
2016-05-03 13:52:07 +10:00
|
|
|
bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
|
2010-11-23 17:14:03 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (usys) {
|
2012-03-25 23:54:33 +00:00
|
|
|
int i = bUnit_GetBaseUnit(usys);
|
2012-05-31 16:04:03 +00:00
|
|
|
if (grid_unit)
|
|
|
|
*grid_unit = bUnit_GetNameDisplay(usys, i);
|
2012-12-09 10:48:18 +00:00
|
|
|
return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
|
2010-11-23 17:14:03 +00:00
|
|
|
}
|
|
|
|
}
|
2011-09-11 04:31:09 +00:00
|
|
|
|
2012-12-09 10:48:18 +00:00
|
|
|
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);
|
2012-05-31 16:04:03 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 15:41:44 +02:00
|
|
|
static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
|
2012-05-31 16:04:03 +00:00
|
|
|
{
|
|
|
|
float grid, grid_scale;
|
|
|
|
unsigned char col_grid[3];
|
|
|
|
const int gridlines = v3d->gridlines / 2;
|
|
|
|
|
|
|
|
if (v3d->gridlines < 3) return;
|
|
|
|
|
|
|
|
/* use 'grid_scale' instead of 'v3d->grid' from now on */
|
|
|
|
grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
|
2012-03-25 23:54:33 +00:00
|
|
|
grid = gridlines * grid_scale;
|
2010-11-23 17:14:03 +00:00
|
|
|
|
2015-04-28 15:41:44 +02:00
|
|
|
if (!write_depth)
|
|
|
|
glDepthMask(GL_FALSE);
|
2011-09-11 04:31:09 +00:00
|
|
|
|
|
|
|
UI_GetThemeColor3ubv(TH_GRID, col_grid);
|
|
|
|
|
2016-01-23 00:58:32 -05:00
|
|
|
glLineWidth(1);
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* draw the Y axis and/or grid lines */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->gridflag & V3D_SHOW_FLOOR) {
|
2013-08-06 07:10:18 +00:00
|
|
|
const int sublines = v3d->gridsubdiv;
|
2012-03-25 23:54:33 +00:00
|
|
|
float vert[4][3] = {{0.0f}};
|
2011-09-11 04:56:32 +00:00
|
|
|
unsigned char col_bg[3];
|
|
|
|
unsigned char col_grid_emphasise[3], col_grid_light[3];
|
2011-09-11 05:50:44 +00:00
|
|
|
int a;
|
2012-03-25 23:54:33 +00:00
|
|
|
int prev_emphasise = -1;
|
2011-09-11 04:56:32 +00:00
|
|
|
|
|
|
|
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_light, 10);
|
|
|
|
UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
|
2012-03-25 23:54:33 +00:00
|
|
|
(((col_grid[0] + col_grid[1] + col_grid[2]) + 30) >
|
|
|
|
(col_bg[0] + col_bg[1] + col_bg[2])) ? 20 : -10);
|
2011-09-11 04:56:32 +00:00
|
|
|
|
2011-09-11 05:50:44 +00:00
|
|
|
/* set fixed axis */
|
2012-03-25 23:54:33 +00:00
|
|
|
vert[0][0] = vert[2][1] = grid;
|
|
|
|
vert[1][0] = vert[3][1] = -grid;
|
2011-09-11 05:50:44 +00:00
|
|
|
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vert);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = -gridlines; a <= gridlines; a++) {
|
|
|
|
const float line = a * grid_scale;
|
2013-08-06 07:10:18 +00:00
|
|
|
const int is_emphasise = (a % sublines) == 0;
|
2011-09-11 05:10:27 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (is_emphasise != prev_emphasise) {
|
2011-09-11 05:50:44 +00:00
|
|
|
glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light);
|
2012-03-25 23:54:33 +00:00
|
|
|
prev_emphasise = is_emphasise;
|
2011-09-11 05:50:44 +00:00
|
|
|
}
|
2011-09-11 04:56:32 +00:00
|
|
|
|
2011-09-11 05:50:44 +00:00
|
|
|
/* set variable axis */
|
2012-06-06 14:38:47 +00:00
|
|
|
vert[0][1] = vert[1][1] = vert[2][0] = vert[3][0] = line;
|
2011-09-11 05:10:27 +00:00
|
|
|
|
2011-09-11 05:50:44 +00:00
|
|
|
glDrawArrays(GL_LINES, 0, 4);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2011-09-11 05:50:44 +00:00
|
|
|
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
/* draw the Z axis line */
|
2008-12-18 17:38:21 +00:00
|
|
|
/* check for the 'show Z axis' preference */
|
2011-09-11 04:56:32 +00:00
|
|
|
if (v3d->gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
|
2016-01-22 01:03:15 -05:00
|
|
|
glBegin(GL_LINES);
|
2011-09-11 04:56:32 +00:00
|
|
|
int axis;
|
2012-03-25 23:54:33 +00:00
|
|
|
for (axis = 0; axis < 3; axis++) {
|
|
|
|
if (v3d->gridflag & (V3D_SHOW_X << axis)) {
|
|
|
|
float vert[3];
|
|
|
|
unsigned char tcol[3];
|
|
|
|
|
|
|
|
UI_make_axis_color(col_grid, tcol, 'X' + axis);
|
|
|
|
glColor3ubv(tcol);
|
|
|
|
|
|
|
|
zero_v3(vert);
|
|
|
|
vert[axis] = grid;
|
|
|
|
glVertex3fv(vert);
|
|
|
|
vert[axis] = -grid;
|
|
|
|
glVertex3fv(vert);
|
|
|
|
}
|
2011-09-11 04:56:32 +00:00
|
|
|
}
|
2016-01-22 01:03:15 -05:00
|
|
|
glEnd();
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2015-02-13 11:52:27 +01:00
|
|
|
glDepthMask(GL_TRUE);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
|
|
|
|
{
|
2012-10-04 17:52:12 +00:00
|
|
|
int co[2];
|
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* we don't want the clipping for cursor */
|
2013-10-26 04:07:18 +00:00
|
|
|
if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
|
2012-12-13 10:37:04 +00:00
|
|
|
const float f5 = 0.25f * U.widget_unit;
|
|
|
|
const float f10 = 0.5f * U.widget_unit;
|
|
|
|
const float f20 = U.widget_unit;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
|
2016-01-23 00:58:32 -05:00
|
|
|
glLineWidth(1);
|
2008-12-18 17:38:21 +00:00
|
|
|
setlinestyle(0);
|
|
|
|
cpack(0xFF);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
circ((float)co[0], (float)co[1], f10);
|
|
|
|
setlinestyle(4);
|
2008-12-18 17:38:21 +00:00
|
|
|
cpack(0xFFFFFF);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
circ((float)co[0], (float)co[1], f10);
|
2008-12-18 17:38:21 +00:00
|
|
|
setlinestyle(0);
|
2014-03-18 05:34:43 +11:00
|
|
|
|
|
|
|
UI_ThemeColor(TH_VIEW_OVERLAY);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]);
|
|
|
|
sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]);
|
|
|
|
sdrawline(co[0], co[1] - f20, co[0], co[1] - f5);
|
|
|
|
sdrawline(co[0], co[1] + f5, co[0], co[1] + f20);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-19 13:04:40 +00:00
|
|
|
/* Draw a live substitute of the view icon, which is always shown
|
|
|
|
* colors copied from transform_manipulator.c, we should keep these matching. */
|
2012-12-18 13:59:47 +00:00
|
|
|
static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2013-06-30 21:41:06 +00:00
|
|
|
const float k = U.rvisize * U.pixelsize; /* axis size */
|
2008-12-18 17:38:21 +00:00
|
|
|
const float toll = 0.5; /* used to see when view is quasi-orthogonal */
|
2012-12-18 13:59:47 +00:00
|
|
|
float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
|
|
|
|
float starty = k + 1.0f;
|
2008-12-18 17:38:21 +00:00
|
|
|
float ydisp = 0.0; /* vertical displacement to allow obj info text */
|
2013-01-07 15:29:15 +00:00
|
|
|
int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
|
2010-10-19 13:04:40 +00:00
|
|
|
float vec[3];
|
2008-12-18 17:38:21 +00:00
|
|
|
float dx, dy;
|
2015-01-20 16:37:07 +11:00
|
|
|
|
|
|
|
int axis_order[3] = {0, 1, 2};
|
|
|
|
int axis_i;
|
|
|
|
|
2012-12-18 13:59:47 +00:00
|
|
|
startx += rect->xmin;
|
|
|
|
starty += rect->ymin;
|
2015-01-20 16:37:07 +11:00
|
|
|
|
|
|
|
axis_sort_v3(rv3d->viewinv[2], axis_order);
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* thickness of lines is proportional to k */
|
2010-10-19 13:04:40 +00:00
|
|
|
glLineWidth(2);
|
|
|
|
|
2010-10-30 17:13:03 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
2015-01-20 16:37:07 +11:00
|
|
|
for (axis_i = 0; axis_i < 3; axis_i++) {
|
|
|
|
int i = axis_order[axis_i];
|
|
|
|
const char axis_text[2] = {'x' + i, '\0'};
|
|
|
|
|
2013-11-24 21:25:05 +11:00
|
|
|
zero_v3(vec);
|
|
|
|
vec[i] = 1.0f;
|
|
|
|
mul_qt_v3(rv3d->viewquat, vec);
|
|
|
|
dx = vec[0] * k;
|
|
|
|
dy = vec[1] * k;
|
|
|
|
|
|
|
|
UI_ThemeColorShadeAlpha(TH_AXIS_X + i, 0, bright);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2f(startx, starty + ydisp);
|
|
|
|
glVertex2f(startx + dx, starty + dy + ydisp);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
if (fabsf(dx) > toll || fabsf(dy) > toll) {
|
|
|
|
BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, axis_text, 1);
|
2010-10-30 17:13:03 +00:00
|
|
|
|
2016-01-23 01:13:36 -05:00
|
|
|
/* BLF_draw_default disables blending */
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2010-10-19 13:04:40 +00:00
|
|
|
|
2010-10-30 17:13:03 +00:00
|
|
|
glDisable(GL_BLEND);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 00:21:55 -04:00
|
|
|
#ifdef WITH_INPUT_NDOF
|
2011-07-26 02:35:46 +00:00
|
|
|
/* draw center and axis of rotation for ongoing 3D mouse navigation */
|
|
|
|
static void draw_rotation_guide(RegionView3D *rv3d)
|
|
|
|
{
|
2012-07-08 20:36:00 +00:00
|
|
|
float o[3]; /* center of rotation */
|
|
|
|
float end[3]; /* endpoints for drawing */
|
2011-07-26 02:35:46 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
float color[4] = {0.0f, 0.4235f, 1.0f, 1.0f}; /* bright blue so it matches device LEDs */
|
2011-07-26 02:35:46 +00:00
|
|
|
|
|
|
|
negate_v3_v3(o, rv3d->ofs);
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glPointSize(5);
|
|
|
|
glEnable(GL_POINT_SMOOTH);
|
2012-07-08 20:36:00 +00:00
|
|
|
glDepthMask(0); /* don't overwrite zbuf */
|
2011-07-26 02:35:46 +00:00
|
|
|
|
2015-04-13 16:56:43 -04:00
|
|
|
if (rv3d->rot_angle != 0.0f) {
|
2012-07-08 20:36:00 +00:00
|
|
|
/* -- draw rotation axis -- */
|
2011-07-26 02:35:46 +00:00
|
|
|
float scaled_axis[3];
|
2011-07-26 16:17:00 +00:00
|
|
|
const float scale = rv3d->dist;
|
|
|
|
mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
|
2011-09-11 05:50:44 +00:00
|
|
|
|
|
|
|
|
2011-07-26 02:35:46 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
2015-04-13 16:56:43 -04:00
|
|
|
color[3] = 0.0f; /* more transparent toward the ends */
|
2011-09-11 05:50:44 +00:00
|
|
|
glColor4fv(color);
|
|
|
|
add_v3_v3v3(end, o, scaled_axis);
|
|
|
|
glVertex3fv(end);
|
2011-07-26 16:17:00 +00:00
|
|
|
|
2015-04-13 16:56:43 -04:00
|
|
|
#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
|
2011-09-11 05:50:44 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
color[3] = 0.5f; /* more opaque toward the center */
|
2011-09-11 05:50:44 +00:00
|
|
|
glColor4fv(color);
|
|
|
|
glVertex3fv(o);
|
|
|
|
|
2015-04-13 16:56:43 -04:00
|
|
|
color[3] = 0.0f;
|
2011-09-11 05:50:44 +00:00
|
|
|
glColor4fv(color);
|
|
|
|
sub_v3_v3v3(end, o, scaled_axis);
|
|
|
|
glVertex3fv(end);
|
2011-07-26 02:35:46 +00:00
|
|
|
glEnd();
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
/* -- draw ring around rotation center -- */
|
2011-07-30 05:23:10 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
#define ROT_AXIS_DETAIL 13
|
2011-09-11 05:50:44 +00:00
|
|
|
|
|
|
|
const float s = 0.05f * scale;
|
2015-04-13 16:56:43 -04:00
|
|
|
const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
|
2011-09-11 05:50:44 +00:00
|
|
|
float angle;
|
|
|
|
int i;
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
float q[4]; /* rotate ring so it's perpendicular to axis */
|
2011-09-11 05:50:44 +00:00
|
|
|
const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
|
|
|
|
if (!upright) {
|
2015-04-13 16:56:43 -04:00
|
|
|
const float up[3] = {0.0f, 0.0f, 1.0f};
|
2011-09-11 05:50:44 +00:00
|
|
|
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);
|
2011-07-30 05:23:10 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
color[3] = 0.25f; /* somewhat faint */
|
2011-09-11 05:50:44 +00:00
|
|
|
glColor4fv(color);
|
|
|
|
glBegin(GL_LINE_LOOP);
|
2015-04-13 16:56:43 -04:00
|
|
|
for (i = 0, angle = 0.0f; i < ROT_AXIS_DETAIL; ++i, angle += step) {
|
2012-09-30 06:12:47 +00:00
|
|
|
float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
|
2011-07-30 05:23:10 +00:00
|
|
|
|
2011-09-11 05:50:44 +00:00
|
|
|
if (!upright) {
|
|
|
|
mul_qt_v3(q, p);
|
|
|
|
}
|
2011-07-30 05:23:10 +00:00
|
|
|
|
2011-09-11 05:50:44 +00:00
|
|
|
add_v3_v3(p, o);
|
|
|
|
glVertex3fv(p);
|
2011-07-30 05:23:10 +00:00
|
|
|
}
|
2011-09-11 05:50:44 +00:00
|
|
|
glEnd();
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
#undef ROT_AXIS_DETAIL
|
2011-07-30 05:23:10 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
color[3] = 1.0f; /* solid dot */
|
2011-07-26 02:35:46 +00:00
|
|
|
}
|
|
|
|
else
|
2012-07-08 20:36:00 +00:00
|
|
|
color[3] = 0.5f; /* see-through dot */
|
2011-07-26 02:35:46 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
/* -- draw rotation center -- */
|
2011-07-26 02:35:46 +00:00
|
|
|
glColor4fv(color);
|
|
|
|
glBegin(GL_POINTS);
|
2012-03-25 23:54:33 +00:00
|
|
|
glVertex3fv(o);
|
2011-07-26 02:35:46 +00:00
|
|
|
glEnd();
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
#if 0
|
2015-04-13 16:56:43 -04:00
|
|
|
/* find screen coordinates for rotation center, then draw pretty icon */
|
2012-07-08 20:36:00 +00:00
|
|
|
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 */
|
2015-04-13 16:56:43 -04:00
|
|
|
#endif
|
2011-07-26 02:35:46 +00:00
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_POINT_SMOOTH);
|
2011-07-26 16:17:00 +00:00
|
|
|
glDepthMask(1);
|
2011-07-26 02:35:46 +00:00
|
|
|
}
|
2016-08-18 00:21:55 -04:00
|
|
|
#endif /* WITH_INPUT_NDOF */
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2012-12-18 13:59:47 +00:00
|
|
|
static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
|
|
|
BIFIconID icon;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
|
|
|
|
icon = ICON_AXIS_TOP;
|
|
|
|
else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK))
|
|
|
|
icon = ICON_AXIS_FRONT;
|
|
|
|
else if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
|
|
|
|
icon = ICON_AXIS_SIDE;
|
2012-02-27 10:35:39 +00:00
|
|
|
else return;
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
2012-12-18 13:59:47 +00:00
|
|
|
UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
}
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2010-12-03 17:05:21 +00:00
|
|
|
const char *name = NULL;
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
switch (rv3d->view) {
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_FRONT:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
|
|
|
|
else name = IFACE_("Front Persp");
|
2008-12-18 17:38:21 +00:00
|
|
|
break;
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_BACK:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
|
|
|
|
else name = IFACE_("Back Persp");
|
2008-12-18 17:38:21 +00:00
|
|
|
break;
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_TOP:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
|
|
|
|
else name = IFACE_("Top Persp");
|
2008-12-18 17:38:21 +00:00
|
|
|
break;
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_BOTTOM:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
|
|
|
|
else name = IFACE_("Bottom Persp");
|
2009-01-20 14:23:32 +00:00
|
|
|
break;
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_RIGHT:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
|
|
|
|
else name = IFACE_("Right Persp");
|
2009-01-20 14:23:32 +00:00
|
|
|
break;
|
2009-10-27 02:54:25 +00:00
|
|
|
case RV3D_VIEW_LEFT:
|
2013-02-19 15:45:56 +00:00
|
|
|
if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
|
|
|
|
else name = IFACE_("Left Persp");
|
2009-01-20 14:23:32 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
default:
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2008-12-18 17:38:21 +00:00
|
|
|
if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
|
|
|
|
Camera *cam;
|
|
|
|
cam = v3d->camera->data;
|
2014-12-24 19:35:12 +01:00
|
|
|
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");
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-02-19 15:45:56 +00:00
|
|
|
name = IFACE_("Object as Camera");
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-02-19 15:45:56 +00:00
|
|
|
name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2012-12-18 13:59:47 +00:00
|
|
|
static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
const char *name = view3d_get_name(v3d, rv3d);
|
2014-02-27 11:30:12 +11:00
|
|
|
/* increase size for unicode languages (Chinese in utf-8...) */
|
2013-02-20 08:39:31 +00:00
|
|
|
#ifdef WITH_INTERNATIONAL
|
2014-02-27 11:30:12 +11:00
|
|
|
char tmpstr[96];
|
2013-02-20 08:39:31 +00:00
|
|
|
#else
|
2014-02-27 11:30:12 +11:00
|
|
|
char tmpstr[32];
|
2013-02-20 08:39:31 +00:00
|
|
|
#endif
|
|
|
|
|
2009-09-22 04:40:16 +00:00
|
|
|
if (v3d->localvd) {
|
2013-02-19 15:45:56 +00:00
|
|
|
BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
|
2012-03-25 23:54:33 +00:00
|
|
|
name = tmpstr;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2013-05-08 12:53:14 +00:00
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
2013-02-20 08:39:31 +00:00
|
|
|
#ifdef WITH_INTERNATIONAL
|
2013-05-08 12:53:14 +00:00
|
|
|
BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
|
2013-02-20 08:39:31 +00:00
|
|
|
#else
|
2013-05-08 12:53:14 +00:00
|
|
|
BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
|
2013-02-20 08:39:31 +00:00
|
|
|
#endif
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* draw info beside axes in bottom left-corner:
|
2012-03-03 16:31:46 +00:00
|
|
|
* framenum, object name, bone name (if available), marker name (if available)
|
|
|
|
*/
|
2013-05-23 20:02:53 +00:00
|
|
|
|
2018-02-28 11:46:02 +11:00
|
|
|
static void draw_selected_name(Scene *scene, Object *ob, const rcti *rect)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2013-06-16 09:14:24 +00:00
|
|
|
const int cfra = CFRA;
|
|
|
|
const char *msg_pin = " (Pinned)";
|
|
|
|
const char *msg_sep = " : ";
|
|
|
|
|
|
|
|
char info[300];
|
2014-04-27 00:22:49 +10:00
|
|
|
const char *markern;
|
2013-06-16 09:14:24 +00:00
|
|
|
char *s = info;
|
2013-02-14 23:49:30 +00:00
|
|
|
short offset = 1.5f * UI_UNIT_X + rect->xmin;
|
2013-05-23 20:02:53 +00:00
|
|
|
|
2013-06-16 09:14:24 +00:00
|
|
|
s += sprintf(s, "(%d)", cfra);
|
|
|
|
|
2013-05-23 20:02:53 +00:00
|
|
|
/*
|
2013-06-16 09:14:24 +00:00
|
|
|
* 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)
|
2013-06-06 06:02:46 +00:00
|
|
|
*/
|
2013-06-16 09:14:24 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* get name of marker on current frame (if available) */
|
2013-06-16 09:14:24 +00:00
|
|
|
markern = BKE_scene_find_marker_name(scene, cfra);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
/* check if there is an object */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob) {
|
2013-06-16 09:14:24 +00:00
|
|
|
*s++ = ' ';
|
|
|
|
s += BLI_strcpy_rlen(s, ob->id.name + 2);
|
2013-05-23 20:02:53 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* name(s) to display depends on type of object */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob->type == OB_ARMATURE) {
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
/* show name of active bone too (if possible) */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (arm->edbo) {
|
2013-05-23 20:02:53 +00:00
|
|
|
if (arm->act_edbone) {
|
2013-06-16 09:14:24 +00:00
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_edbone->name);
|
2013-05-23 20:02:53 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ob->mode & OB_MODE_POSE) {
|
|
|
|
if (arm->act_bone) {
|
2009-11-09 21:03:54 +00:00
|
|
|
|
2013-05-23 20:02:53 +00:00
|
|
|
if (arm->act_bone->layer & arm->layer) {
|
2013-06-16 09:14:24 +00:00
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_bone->name);
|
2013-05-23 20:02:53 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-20 01:30:29 +10:00
|
|
|
else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
Key *key = NULL;
|
2008-12-18 17:38:21 +00:00
|
|
|
KeyBlock *kb = NULL;
|
2013-05-23 16:24:36 +00:00
|
|
|
|
2013-05-23 20:02:53 +00:00
|
|
|
/* try to display active bone and active shapekey too (if they exist) */
|
|
|
|
|
|
|
|
if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
|
2013-05-23 16:24:36 +00:00
|
|
|
Object *armobj = BKE_object_pose_armature_get(ob);
|
|
|
|
if (armobj && armobj->mode & OB_MODE_POSE) {
|
|
|
|
bArmature *arm = armobj->data;
|
|
|
|
if (arm->act_bone) {
|
2013-05-23 20:02:53 +00:00
|
|
|
if (arm->act_bone->layer & arm->layer) {
|
2013-06-16 09:14:24 +00:00
|
|
|
s += BLI_strcpy_rlen(s, msg_sep);
|
|
|
|
s += BLI_strcpy_rlen(s, arm->act_bone->name);
|
2013-05-23 20:02:53 +00:00
|
|
|
}
|
2013-05-23 16:24:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-23 20:02:53 +00:00
|
|
|
key = BKE_key_from_object(ob);
|
|
|
|
if (key) {
|
|
|
|
kb = BLI_findlink(&key->block, ob->shapenr - 1);
|
|
|
|
if (kb) {
|
2013-06-16 09:14:24 +00:00
|
|
|
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));
|
2013-05-23 20:02:53 +00:00
|
|
|
}
|
|
|
|
}
|
2013-05-23 16:24:36 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2010-12-03 12:30:59 +00:00
|
|
|
/* color depends on whether there is a keyframe */
|
2013-06-16 09:14:24 +00:00
|
|
|
if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
|
2016-02-01 14:01:02 +01:00
|
|
|
UI_ThemeColor(TH_TIME_KEYFRAME);
|
2015-12-13 21:03:13 +13:00
|
|
|
else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
|
2016-02-01 14:01:02 +01:00
|
|
|
UI_ThemeColor(TH_TIME_GP_KEYFRAME);
|
2008-12-21 10:33:24 +00:00
|
|
|
else
|
2008-12-18 17:38:21 +00:00
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
|
|
|
}
|
|
|
|
else {
|
2016-08-26 16:07:25 +12:00
|
|
|
/* no object */
|
|
|
|
if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
|
|
|
|
UI_ThemeColor(TH_TIME_GP_KEYFRAME);
|
|
|
|
else
|
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2013-05-23 20:02:53 +00:00
|
|
|
|
2013-06-16 09:14:24 +00:00
|
|
|
if (markern) {
|
|
|
|
s += sprintf(s, " <%s>", markern);
|
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
if (U.uiflag & USER_SHOW_ROTVIEWICON)
|
2012-12-18 13:59:47 +00:00
|
|
|
offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
|
2009-05-05 23:10:32 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2015-03-21 22:34:20 +11:00
|
|
|
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)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2011-11-19 18:35:42 +00:00
|
|
|
CameraParams params;
|
|
|
|
rctf rect_view, rect_camera;
|
|
|
|
|
|
|
|
/* get viewport viewplane */
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_init(¶ms);
|
|
|
|
BKE_camera_params_from_view3d(¶ms, v3d, rv3d);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (no_zoom)
|
2012-03-25 23:54:33 +00:00
|
|
|
params.zoom = 1.0f;
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_compute_viewplane(¶ms, ar->winx, ar->winy, 1.0f, 1.0f);
|
2012-03-25 23:54:33 +00:00
|
|
|
rect_view = params.viewplane;
|
2011-11-19 18:35:42 +00:00
|
|
|
|
|
|
|
/* get camera viewplane */
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_init(¶ms);
|
2014-03-01 21:41:07 +11:00
|
|
|
/* fallback for non camera objects */
|
|
|
|
params.clipsta = v3d->near;
|
|
|
|
params.clipend = v3d->far;
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_from_object(¶ms, v3d->camera);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (no_shift) {
|
2012-03-25 23:54:33 +00:00
|
|
|
params.shiftx = 0.0f;
|
|
|
|
params.shifty = 0.0f;
|
2011-11-19 18:35:42 +00:00
|
|
|
}
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_compute_viewplane(¶ms, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
|
2012-03-25 23:54:33 +00:00
|
|
|
rect_camera = params.viewplane;
|
2011-11-19 18:35:42 +00:00
|
|
|
|
|
|
|
/* get camera border within viewport */
|
2013-03-14 07:56:40 +00:00
|
|
|
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;
|
2011-11-19 18:35:42 +00:00
|
|
|
}
|
2011-11-04 14:36:06 +00:00
|
|
|
|
2015-03-21 22:34:20 +11:00
|
|
|
void ED_view3d_calc_camera_border_size(
|
|
|
|
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
|
|
|
|
float r_size[2])
|
2011-11-19 18:35:42 +00:00
|
|
|
{
|
|
|
|
rctf viewborder;
|
2011-11-04 14:36:06 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, true, true);
|
2013-03-14 07:56:40 +00:00
|
|
|
r_size[0] = BLI_rctf_size_x(&viewborder);
|
|
|
|
r_size[1] = BLI_rctf_size_y(&viewborder);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2015-03-21 22:34:20 +11:00
|
|
|
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)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2013-03-17 19:55:10 +00:00
|
|
|
view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
|
2011-05-10 03:03:53 +00:00
|
|
|
{
|
|
|
|
float x3, y3, x4, y4;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
x3 = x1 + fac * (x2 - x1);
|
|
|
|
y3 = y1 + fac * (y2 - y1);
|
|
|
|
x4 = x1 + (1.0f - fac) * (x2 - x1);
|
|
|
|
y4 = y1 + (1.0f - fac) * (y2 - y1);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1, y3);
|
|
|
|
glVertex2f(x2, y3);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1, y4);
|
|
|
|
glVertex2f(x2, y4);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x3, y1);
|
|
|
|
glVertex2f(x3, y2);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x4, y1);
|
|
|
|
glVertex2f(x4, y2);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* harmonious triangle */
|
|
|
|
static void drawviewborder_triangle(float x1, float x2, float y1, float y2, const char golden, const char dir)
|
|
|
|
{
|
|
|
|
float ofs;
|
2012-03-25 23:54:33 +00:00
|
|
|
float w = x2 - x1;
|
|
|
|
float h = y2 - y1;
|
2011-05-15 05:43:59 +00:00
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (w > h) {
|
|
|
|
if (golden) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ofs = w * (1.0f - (1.0f / 1.61803399f));
|
2011-05-15 05:43:59 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
ofs = h * (h / w);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (dir == 'B') SWAP(float, y1, y2);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1, y1);
|
2011-05-10 03:03:53 +00:00
|
|
|
glVertex2f(x2, y2);
|
|
|
|
|
|
|
|
glVertex2f(x2, y1);
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1 + (w - ofs), y2);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
|
|
|
glVertex2f(x1, y2);
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1 + ofs, y1);
|
|
|
|
}
|
|
|
|
else {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (golden) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ofs = h * (1.0f - (1.0f / 1.61803399f));
|
2011-05-15 05:43:59 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
ofs = w * (w / h);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (dir == 'B') SWAP(float, x1, x2);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1, y1);
|
2011-05-10 03:03:53 +00:00
|
|
|
glVertex2f(x2, y2);
|
|
|
|
|
|
|
|
glVertex2f(x2, y1);
|
2011-05-15 05:43:59 +00:00
|
|
|
glVertex2f(x1, y1 + ofs);
|
|
|
|
|
|
|
|
glVertex2f(x1, y2);
|
|
|
|
glVertex2f(x2, y1 + (h - ofs));
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
|
|
|
|
{
|
|
|
|
float x1, x2, y1, y2;
|
2010-07-26 21:35:24 +00:00
|
|
|
float x1i, x2i, y1i, y2i;
|
2014-03-18 05:34:43 +11:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
rctf viewborder;
|
2012-03-25 23:54:33 +00:00
|
|
|
Camera *ca = NULL;
|
2014-04-12 15:34:59 +10:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2015-01-19 16:30:35 +11:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->camera == NULL)
|
2008-12-18 17:38:21 +00:00
|
|
|
return;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->camera->type == OB_CAMERA)
|
2008-12-18 17:38:21 +00:00
|
|
|
ca = v3d->camera->data;
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
|
2010-07-26 21:35:24 +00:00
|
|
|
/* the offsets */
|
2012-03-25 23:54:33 +00:00
|
|
|
x1 = viewborder.xmin;
|
|
|
|
y1 = viewborder.ymin;
|
|
|
|
x2 = viewborder.xmax;
|
|
|
|
y2 = viewborder.ymax;
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2016-04-06 14:27:37 +10:00
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
2010-07-26 21:35:24 +00:00
|
|
|
/* apply offsets so the real 3D camera shows through */
|
2011-05-11 00:59:22 +00:00
|
|
|
|
|
|
|
/* note: quite un-scientific but without this bit extra
|
|
|
|
* 0.0001 on the lower left the 2D border sometimes
|
|
|
|
* obscures the 3D camera border */
|
2012-03-01 12:20:18 +00:00
|
|
|
/* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
|
2012-03-09 00:41:09 +00:00
|
|
|
* but keep it here in case we need to remove the workaround */
|
2012-03-25 23:54:33 +00:00
|
|
|
x1i = (int)(x1 - 1.0001f);
|
|
|
|
y1i = (int)(y1 - 1.0001f);
|
|
|
|
x2i = (int)(x2 + (1.0f - 0.0001f));
|
|
|
|
y2i = (int)(y2 + (1.0f - 0.0001f));
|
2010-07-26 21:35:24 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* passepartout, specified in camera edit buttons */
|
2011-03-27 15:57:27 +00:00
|
|
|
if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
|
2014-10-04 15:40:41 +02:00
|
|
|
const float winx = (ar->winx + 1);
|
|
|
|
const float winy = (ar->winy + 1);
|
|
|
|
|
2011-03-27 15:57:27 +00:00
|
|
|
if (ca->passepartalpha == 1.0f) {
|
2008-12-18 17:38:21 +00:00
|
|
|
glColor3f(0, 0, 0);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
2008-12-18 17:38:21 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glColor4f(0, 0, 0, ca->passepartalpha);
|
|
|
|
}
|
2016-02-10 23:14:29 +01:00
|
|
|
|
2011-03-27 15:57:27 +00:00
|
|
|
if (x1i > 0.0f)
|
2014-10-04 15:40:41 +02:00
|
|
|
glRectf(0.0, winy, x1i, 0.0);
|
|
|
|
if (x2i < winx)
|
|
|
|
glRectf(x2i, winy, winx, 0.0);
|
|
|
|
if (y2i < winy)
|
|
|
|
glRectf(x1i, winy, x2i, y2i);
|
2011-03-27 15:57:27 +00:00
|
|
|
if (y2i > 0.0f)
|
2010-07-26 21:35:24 +00:00
|
|
|
glRectf(x1i, y1i, x2i, 0.0);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
}
|
2010-07-26 21:35:24 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
setlinestyle(0);
|
2012-01-18 11:10:02 +00:00
|
|
|
|
|
|
|
UI_ThemeColor(TH_BACK);
|
2012-01-18 10:41:38 +00:00
|
|
|
|
2016-01-22 01:45:39 -05:00
|
|
|
fdrawbox(x1i, y1i, x2i, y2i);
|
2011-07-21 01:30:26 +00:00
|
|
|
|
|
|
|
#ifdef VIEW3D_CAMERA_BORDER_HACK
|
2013-03-20 23:14:18 +00:00
|
|
|
if (view3d_camera_border_hack_test == true) {
|
2012-06-06 18:00:08 +00:00
|
|
|
glColor3ubv(view3d_camera_border_hack_col);
|
2016-01-22 01:45:39 -05:00
|
|
|
fdrawbox(x1i + 1, y1i + 1, x2i - 1, y2i - 1);
|
2013-03-20 23:14:18 +00:00
|
|
|
view3d_camera_border_hack_test = false;
|
2011-07-21 01:30:26 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
setlinestyle(3);
|
2012-01-18 11:10:02 +00:00
|
|
|
|
|
|
|
/* outer line not to confuse with object selecton */
|
|
|
|
if (v3d->flag2 & V3D_LOCK_CAMERA) {
|
|
|
|
UI_ThemeColor(TH_REDALERT);
|
2016-01-22 01:45:39 -05:00
|
|
|
fdrawbox(x1i - 1, y1i - 1, x2i + 1, y2i + 1);
|
2012-01-18 11:10:02 +00:00
|
|
|
}
|
|
|
|
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColor(TH_VIEW_OVERLAY);
|
2016-01-22 01:45:39 -05:00
|
|
|
fdrawbox(x1i, y1i, x2i, y2i);
|
2010-07-26 21:35:24 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* border */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (scene->r.mode & R_BORDER) {
|
2014-03-18 05:34:43 +11:00
|
|
|
float x3, y3, x4, y4;
|
|
|
|
|
2016-06-02 12:51:36 +10:00
|
|
|
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);
|
2014-03-18 05:34:43 +11:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
cpack(0x4040FF);
|
2016-01-22 01:45:39 -05:00
|
|
|
sdrawbox(x3, y3, x4, y4);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2011-04-21 13:11:51 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* safety border */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ca) {
|
2011-05-10 03:03:53 +00:00
|
|
|
if (ca->dtx & CAM_DTX_CENTER) {
|
2014-03-18 05:34:43 +11:00
|
|
|
float x3, y3;
|
|
|
|
|
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
x3 = x1 + 0.5f * (x2 - x1);
|
|
|
|
y3 = y1 + 0.5f * (y2 - y1);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2f(x1, y3);
|
|
|
|
glVertex2f(x2, y3);
|
|
|
|
|
|
|
|
glVertex2f(x3, y1);
|
|
|
|
glVertex2f(x3, y2);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_CENTER_DIAG) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-10 03:03:53 +00:00
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2f(x1, y1);
|
|
|
|
glVertex2f(x2, y2);
|
|
|
|
|
|
|
|
glVertex2f(x1, y2);
|
|
|
|
glVertex2f(x2, y1);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_THIRDS) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawviewborder_grid3(x1, x2, y1, y2, 1.0f / 3.0f);
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawviewborder_grid3(x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
|
2011-05-15 05:43:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-15 05:43:59 +00:00
|
|
|
drawviewborder_triangle(x1, x2, y1, y2, 0, 'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-15 05:43:59 +00:00
|
|
|
drawviewborder_triangle(x1, x2, y1, y2, 0, 'B');
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-15 05:43:59 +00:00
|
|
|
drawviewborder_triangle(x1, x2, y1, y2, 1, 'A');
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 05:43:59 +00:00
|
|
|
if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
|
2011-05-15 05:43:59 +00:00
|
|
|
drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
|
|
|
|
2015-01-19 16:30:35 +11:00
|
|
|
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
|
|
|
|
UI_draw_safe_areas(
|
|
|
|
x1, x2, y1, y2,
|
|
|
|
scene->safe_areas.title,
|
|
|
|
scene->safe_areas.action);
|
|
|
|
|
|
|
|
if (ca->flag & CAM_SHOW_SAFE_CENTER) {
|
|
|
|
UI_draw_safe_areas(
|
|
|
|
x1, x2, y1, y2,
|
|
|
|
scene->safe_areas.title_center,
|
|
|
|
scene->safe_areas.action_center);
|
|
|
|
}
|
2011-05-10 03:03:53 +00:00
|
|
|
}
|
2015-01-19 16:30:35 +11:00
|
|
|
|
2014-03-01 20:14:20 +11:00
|
|
|
if (ca->flag & CAM_SHOWSENSOR) {
|
2011-11-18 23:15:11 +00:00
|
|
|
/* determine sensor fit, and get sensor x/y, for auto fit we
|
2012-03-03 16:31:46 +00:00
|
|
|
* assume and square sensor and only use sensor_x */
|
2012-03-25 23:54:33 +00:00
|
|
|
float sizex = scene->r.xsch * scene->r.xasp;
|
|
|
|
float sizey = scene->r.ysch * scene->r.yasp;
|
2012-05-05 00:58:22 +00:00
|
|
|
int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
|
2012-03-25 23:54:33 +00:00
|
|
|
float sensor_x = ca->sensor_x;
|
|
|
|
float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
|
2011-11-18 23:15:11 +00:00
|
|
|
|
|
|
|
/* determine sensor plane */
|
|
|
|
rctf rect;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
|
2012-03-25 23:54:33 +00:00
|
|
|
float sensor_scale = (x2i - x1i) / sensor_x;
|
2011-11-18 23:15:11 +00:00
|
|
|
float sensor_height = sensor_scale * sensor_y;
|
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
rect.xmin = x1i;
|
|
|
|
rect.xmax = x2i;
|
2012-03-25 23:54:33 +00:00
|
|
|
rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
|
2012-03-24 02:51:46 +00:00
|
|
|
rect.ymax = rect.ymin + sensor_height;
|
2011-11-18 23:15:11 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
float sensor_scale = (y2i - y1i) / sensor_y;
|
2011-11-18 23:15:11 +00:00
|
|
|
float sensor_width = sensor_scale * sensor_x;
|
2011-11-04 14:36:06 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
|
2012-03-24 02:51:46 +00:00
|
|
|
rect.xmax = rect.xmin + sensor_width;
|
|
|
|
rect.ymin = y1i;
|
|
|
|
rect.ymax = y2i;
|
2011-11-18 23:15:11 +00:00
|
|
|
}
|
2011-11-04 14:36:06 +00:00
|
|
|
|
2011-11-18 23:15:11 +00:00
|
|
|
/* draw */
|
2014-03-18 05:34:43 +11:00
|
|
|
UI_ThemeColorShade(TH_VIEW_OVERLAY, 100);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
|
2011-11-04 14:36:06 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2010-07-26 21:35:24 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
setlinestyle(0);
|
2010-07-26 21:35:24 +00:00
|
|
|
|
2010-01-08 14:45:26 +00:00
|
|
|
/* camera name - draw in highlighted text color */
|
|
|
|
if (ca && (ca->flag & CAM_SHOWNAME)) {
|
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
2015-01-20 15:48:40 +11:00
|
|
|
BLF_draw_default(
|
|
|
|
x1i, y1i - (0.7f * U.widget_unit), 0.0f,
|
|
|
|
v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
|
2010-01-08 14:45:26 +00:00
|
|
|
}
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2009-01-01 19:18:03 +00:00
|
|
|
/* *********************** backdraw for selection *************** */
|
|
|
|
|
2018-03-08 17:26:02 +11:00
|
|
|
static void backdrawview3d(Scene *scene, wmWindow *win, ARegion *ar, View3D *v3d, Object *obact, Object *obedit)
|
2009-01-01 19:18:03 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2011-10-31 14:08:14 +00:00
|
|
|
int multisample_enabled;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2011-05-25 10:07:59 +00:00
|
|
|
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
|
|
|
|
|
2018-03-08 17:26:02 +11:00
|
|
|
if (obact && (obact->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
|
|
|
|
BKE_paint_select_face_test(obact)))
|
2011-11-11 13:09:14 +00:00
|
|
|
{
|
|
|
|
/* do nothing */
|
|
|
|
}
|
2014-07-21 12:02:05 +02:00
|
|
|
/* texture paint mode sampling */
|
2018-03-08 17:26:02 +11:00
|
|
|
else if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT) &&
|
2014-07-21 12:02:05 +02:00
|
|
|
(v3d->drawtype > OB_WIRE))
|
|
|
|
{
|
|
|
|
/* do nothing */
|
|
|
|
}
|
2018-03-08 17:26:02 +11:00
|
|
|
else if ((obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) &&
|
2015-04-20 23:39:54 +10:00
|
|
|
V3D_IS_ZBUF(v3d))
|
2011-11-11 13:09:14 +00:00
|
|
|
{
|
|
|
|
/* do nothing */
|
|
|
|
}
|
2018-03-08 17:26:02 +11:00
|
|
|
else if (obedit &&
|
2015-04-20 23:39:54 +10:00
|
|
|
V3D_IS_ZBUF(v3d))
|
2012-05-20 19:49:27 +00:00
|
|
|
{
|
2011-11-11 13:09:14 +00:00
|
|
|
/* do nothing */
|
|
|
|
}
|
2009-01-01 19:18:03 +00:00
|
|
|
else {
|
2009-12-17 14:38:30 +00:00
|
|
|
v3d->flag &= ~V3D_INVALID_BACKBUF;
|
2009-01-01 19:18:03 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-16 19:15:53 +11:00
|
|
|
if (!(v3d->flag & V3D_INVALID_BACKBUF))
|
|
|
|
return;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
#if 0
|
|
|
|
if (test) {
|
|
|
|
if (qtest()) {
|
|
|
|
addafterqueue(ar->win, BACKBUFDRAW, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2011-10-31 14:08:14 +00:00
|
|
|
/* dithering and AA break color coding, so disable */
|
2009-01-01 19:18:03 +00:00
|
|
|
glDisable(GL_DITHER);
|
|
|
|
|
2015-11-24 02:20:38 -05:00
|
|
|
multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (multisample_enabled)
|
2015-11-24 02:20:38 -05:00
|
|
|
glDisable(GL_MULTISAMPLE);
|
2011-10-31 14:08:14 +00:00
|
|
|
|
2016-02-04 22:26:46 +01:00
|
|
|
if (win->multisamples != USER_MULTISAMPLE_NONE) {
|
2013-03-15 19:56:33 +00:00
|
|
|
/* for multisample we use an offscreen FBO. multisample drawing can fail
|
|
|
|
* with color coded selection drawing, and reading back depths from such
|
|
|
|
* a buffer can also cause a few seconds freeze on OS X / NVidia. */
|
|
|
|
int w = BLI_rcti_size_x(&ar->winrct);
|
|
|
|
int h = BLI_rcti_size_y(&ar->winrct);
|
|
|
|
char error[256];
|
|
|
|
|
|
|
|
if (rv3d->gpuoffscreen) {
|
2013-03-16 14:42:05 +00:00
|
|
|
if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
|
|
|
|
GPU_offscreen_height(rv3d->gpuoffscreen) != h)
|
|
|
|
{
|
2013-03-15 19:56:33 +00:00
|
|
|
GPU_offscreen_free(rv3d->gpuoffscreen);
|
|
|
|
rv3d->gpuoffscreen = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rv3d->gpuoffscreen) {
|
2015-10-14 10:33:30 +11:00
|
|
|
rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, error);
|
2013-03-15 19:56:33 +00:00
|
|
|
|
|
|
|
if (!rv3d->gpuoffscreen)
|
|
|
|
fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv3d->gpuoffscreen)
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_bind(rv3d->gpuoffscreen, true);
|
2013-03-15 19:56:33 +00:00
|
|
|
else
|
|
|
|
glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
|
2009-08-20 19:46:53 +00:00
|
|
|
|
2014-11-18 12:45:33 +01:00
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->zbuf) {
|
2009-01-01 19:18:03 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING)
|
2012-02-28 13:03:56 +00:00
|
|
|
ED_view3d_clipping_set(rv3d);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
|
|
|
G.f |= G_BACKBUFSEL;
|
2018-03-08 17:26:02 +11:00
|
|
|
|
|
|
|
if (obact && (obact->lay & v3d->lay)) {
|
|
|
|
draw_object_backbufsel(scene, v3d, rv3d, obact);
|
|
|
|
}
|
|
|
|
|
2013-03-15 19:56:33 +00:00
|
|
|
if (rv3d->gpuoffscreen)
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
|
2013-03-15 19:56:33 +00:00
|
|
|
else
|
|
|
|
ar->swap = 0; /* mark invalid backbuf for wm draw */
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2009-12-17 14:38:30 +00:00
|
|
|
v3d->flag &= ~V3D_INVALID_BACKBUF;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
|
|
|
G.f &= ~G_BACKBUFSEL;
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->zbuf = false;
|
2009-01-01 19:18:03 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_DITHER);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (multisample_enabled)
|
2015-11-24 02:20:38 -05:00
|
|
|
glEnable(GL_MULTISAMPLE);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING)
|
2012-02-28 13:03:56 +00:00
|
|
|
ED_view3d_clipping_disable();
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
|
|
|
|
2013-03-15 19:56:33 +00:00
|
|
|
void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
|
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
if (rv3d->gpuoffscreen) {
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_bind(rv3d->gpuoffscreen, true);
|
2013-03-15 19:56:33 +00:00
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
|
|
|
glReadPixels(x, y, w, h, format, type, data);
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
|
2013-03-15 19:56:33 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 11:48:13 +00:00
|
|
|
/* XXX depth reading exception, for code not using gpu offscreen */
|
|
|
|
static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
|
|
|
|
{
|
|
|
|
|
|
|
|
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
|
|
|
|
}
|
|
|
|
|
2015-04-21 03:19:27 +10:00
|
|
|
void ED_view3d_backbuf_validate(ViewContext *vc)
|
2009-01-01 19:18:03 +00:00
|
|
|
{
|
2018-03-08 17:26:02 +11:00
|
|
|
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
|
|
|
|
backdrawview3d(vc->scene, vc->win, vc->ar, vc->v3d, vc->obact, vc->obedit);
|
|
|
|
}
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
|
|
|
|
2015-04-21 02:06:20 +10:00
|
|
|
/**
|
|
|
|
* allow for small values [0.5 - 2.5],
|
|
|
|
* and large values, FLT_MAX by clamping by the area size
|
|
|
|
*/
|
2015-04-21 03:19:27 +10:00
|
|
|
int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
|
2015-04-21 02:06:20 +10:00
|
|
|
{
|
|
|
|
return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
|
|
|
|
}
|
|
|
|
|
2009-01-01 19:18:03 +00:00
|
|
|
/* samples a single pixel (copied from vpaint) */
|
2015-04-21 03:19:27 +10:00
|
|
|
unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y)
|
2009-01-01 19:18:03 +00:00
|
|
|
{
|
|
|
|
unsigned int col;
|
|
|
|
|
2012-09-06 23:41:03 +00:00
|
|
|
if (x >= vc->ar->winx || y >= vc->ar->winy) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-21 03:19:27 +10:00
|
|
|
ED_view3d_backbuf_validate(vc);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2013-03-15 19:56:33 +00:00
|
|
|
view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
2012-09-06 23:41:03 +00:00
|
|
|
glReadBuffer(GL_BACK);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-09-03 07:37:38 +00:00
|
|
|
if (ENDIAN_ORDER == B_ENDIAN) {
|
|
|
|
BLI_endian_switch_uint32(&col);
|
|
|
|
}
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2016-06-25 20:16:33 +10:00
|
|
|
return GPU_select_to_index(col);
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* reads full rect, converts indices */
|
2015-07-11 21:09:22 +10:00
|
|
|
ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
|
2009-01-01 19:18:03 +00:00
|
|
|
{
|
2015-07-11 21:09:22 +10:00
|
|
|
struct ImBuf *ibuf_clip;
|
2009-01-01 19:18:03 +00:00
|
|
|
/* clip */
|
2015-07-11 21:09:22 +10:00
|
|
|
const rcti clip = {
|
|
|
|
max_ii(xmin, 0), min_ii(xmax, vc->ar->winx - 1),
|
|
|
|
max_ii(ymin, 0), min_ii(ymax, vc->ar->winy - 1)};
|
|
|
|
const int size_clip[2] = {
|
|
|
|
BLI_rcti_size_x(&clip) + 1,
|
|
|
|
BLI_rcti_size_y(&clip) + 1};
|
|
|
|
|
|
|
|
if (UNLIKELY((clip.xmin > clip.xmax) ||
|
|
|
|
(clip.ymin > clip.ymax)))
|
|
|
|
{
|
2015-04-06 16:40:26 +10:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2015-07-11 21:09:22 +10:00
|
|
|
ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2015-04-21 03:19:27 +10:00
|
|
|
ED_view3d_backbuf_validate(vc);
|
2012-11-19 20:40:08 +00:00
|
|
|
|
2015-07-11 21:09:22 +10:00
|
|
|
view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
|
2012-01-19 16:04:44 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
glReadBuffer(GL_BACK);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2015-07-11 21:09:22 +10:00
|
|
|
if (ENDIAN_ORDER == B_ENDIAN) {
|
|
|
|
IMB_convert_rgba_to_abgr(ibuf_clip);
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
2015-07-11 21:09:22 +10:00
|
|
|
|
2016-06-25 20:16:33 +10:00
|
|
|
GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2015-07-11 21:09:22 +10:00
|
|
|
if ((clip.xmin == xmin) &&
|
|
|
|
(clip.xmax == xmax) &&
|
|
|
|
(clip.ymin == ymin) &&
|
|
|
|
(clip.ymax == ymax))
|
|
|
|
{
|
|
|
|
return ibuf_clip;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* put clipped result into a non-clipped buffer */
|
|
|
|
struct ImBuf *ibuf_full;
|
|
|
|
const int size[2] = {
|
|
|
|
(xmax - xmin + 1),
|
|
|
|
(ymax - ymin + 1)};
|
|
|
|
|
|
|
|
ibuf_full = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
|
|
|
|
|
|
|
|
IMB_rectcpy(
|
|
|
|
ibuf_full, ibuf_clip,
|
|
|
|
clip.xmin - xmin, clip.ymin - ymin,
|
|
|
|
0, 0,
|
|
|
|
size_clip[0], size_clip[1]);
|
|
|
|
IMB_freeImBuf(ibuf_clip);
|
|
|
|
return ibuf_full;
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-27 22:02:18 +11:00
|
|
|
/**
|
|
|
|
* Smart function to sample a rectangle spiral ling outside, nice for backbuf selection
|
|
|
|
*/
|
|
|
|
uint ED_view3d_backbuf_sample_rect(
|
2015-04-21 03:19:27 +10:00
|
|
|
ViewContext *vc, const int mval[2], int size,
|
2015-04-21 04:45:26 +10:00
|
|
|
unsigned int min, unsigned int max, float *r_dist)
|
2009-01-01 19:18:03 +00:00
|
|
|
{
|
|
|
|
struct ImBuf *buf;
|
2015-04-21 04:45:26 +10:00
|
|
|
const unsigned int *bufmin, *bufmax, *tbuf;
|
2009-01-01 19:18:03 +00:00
|
|
|
int minx, miny;
|
|
|
|
int a, b, rc, nr, amount, dirvec[4][2];
|
|
|
|
unsigned int index = 0;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
amount = (size - 1) / 2;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
minx = mval[0] - (amount + 1);
|
|
|
|
miny = mval[1] - (amount + 1);
|
2015-04-21 03:19:27 +10:00
|
|
|
buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1);
|
2009-01-01 19:18:03 +00:00
|
|
|
if (!buf) return 0;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rc = 0;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
dirvec[0][0] = 1; dirvec[0][1] = 0;
|
|
|
|
dirvec[1][0] = 0; dirvec[1][1] = -size;
|
|
|
|
dirvec[2][0] = -1; dirvec[2][1] = 0;
|
|
|
|
dirvec[3][0] = 0; dirvec[3][1] = size;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
|
|
|
bufmin = buf->rect;
|
|
|
|
tbuf = buf->rect;
|
2012-03-25 23:54:33 +00:00
|
|
|
bufmax = buf->rect + size * size;
|
|
|
|
tbuf += amount * size + amount;
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (nr = 1; nr <= size; nr++) {
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = 0; a < 2; a++) {
|
2015-04-22 00:13:33 +10:00
|
|
|
for (b = 0; b < nr; b++) {
|
2015-04-21 04:45:26 +10:00
|
|
|
if (*tbuf && *tbuf >= min && *tbuf < max) {
|
|
|
|
/* we got a hit */
|
|
|
|
|
2015-04-21 21:16:19 +10:00
|
|
|
/* get x,y pixel coords from the offset
|
|
|
|
* (manhatten distance in keeping with other screen-based selection) */
|
|
|
|
*r_dist = (float)(
|
2015-04-23 16:09:30 +10:00
|
|
|
abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
|
|
|
|
abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
|
2015-04-21 04:45:26 +10:00
|
|
|
|
|
|
|
/* indices start at 1 here */
|
|
|
|
index = (*tbuf - min) + 1;
|
|
|
|
goto exit;
|
2009-01-01 19:18:03 +00:00
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tbuf += (dirvec[rc][0] + dirvec[rc][1]);
|
2009-01-01 19:18:03 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (tbuf < bufmin || tbuf >= bufmax) {
|
2009-01-01 19:18:03 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rc++;
|
|
|
|
rc &= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
IMB_freeImBuf(buf);
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************* */
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
|
|
|
|
{
|
2015-10-11 01:14:02 +02:00
|
|
|
if (BKE_image_is_stereo(ima)) {
|
2015-04-06 10:40:12 -03:00
|
|
|
iuser->flag |= IMA_SHOW_STEREO;
|
|
|
|
|
2015-04-22 00:13:33 +10:00
|
|
|
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
|
2015-04-06 10:40:12 -03:00
|
|
|
iuser->multiview_eye = STEREO_LEFT_ID;
|
2015-04-22 00:13:33 +10:00
|
|
|
}
|
|
|
|
else if (v3d->stereo3d_camera != STEREO_3D_ID) {
|
|
|
|
/* show only left or right camera */
|
2015-04-06 10:40:12 -03:00
|
|
|
iuser->multiview_eye = v3d->stereo3d_camera;
|
2015-04-22 00:13:33 +10:00
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
|
|
|
|
BKE_image_multiview_index(ima, iuser);
|
|
|
|
}
|
2015-04-22 00:13:33 +10:00
|
|
|
else {
|
2015-04-06 10:40:12 -03:00
|
|
|
iuser->flag &= ~IMA_SHOW_STEREO;
|
2015-04-22 00:13:33 +10:00
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
|
2012-06-06 11:40:01 +00:00
|
|
|
static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
|
2013-03-20 23:14:18 +00:00
|
|
|
const bool do_foreground, const bool do_camera_frame)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2008-12-18 17:38:21 +00:00
|
|
|
BGpic *bgpic;
|
2012-08-08 18:21:54 +00:00
|
|
|
int fg_flag = do_foreground ? V3D_BGPIC_FOREGROUND : 0;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
|
2014-09-28 18:29:10 +02:00
|
|
|
bgpic->iuser.scene = scene; /* Needed for render results. */
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-04-10 14:59:06 +00:00
|
|
|
if ((bgpic->flag & V3D_BGPIC_FOREGROUND) != fg_flag)
|
|
|
|
continue;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((bgpic->view == 0) || /* zero for any */
|
|
|
|
(bgpic->view & (1 << rv3d->view)) || /* check agaist flags */
|
|
|
|
(rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA)))
|
|
|
|
{
|
2012-06-13 12:58:01 +00:00
|
|
|
float image_aspect[2];
|
2012-09-20 05:09:35 +00:00
|
|
|
float fac, asp, zoomx, zoomy;
|
2015-02-04 15:05:22 +01:00
|
|
|
float x1, y1, x2, y2, centx, centy;
|
2012-09-20 05:09:35 +00:00
|
|
|
|
2013-03-09 11:18:01 +00:00
|
|
|
ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
|
2014-09-28 18:29:10 +02:00
|
|
|
void *lock;
|
2015-03-25 19:46:07 +11:00
|
|
|
rctf clip_rect;
|
2012-09-20 05:09:35 +00:00
|
|
|
|
2014-09-28 18:29:10 +02:00
|
|
|
Image *ima = NULL;
|
|
|
|
MovieClip *clip = NULL;
|
2012-06-13 12:58:01 +00:00
|
|
|
|
2011-11-29 21:05:18 +00:00
|
|
|
/* disable individual images */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((bgpic->flag & V3D_BGPIC_DISABLED))
|
2011-11-29 21:05:18 +00:00
|
|
|
continue;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
freeibuf = NULL;
|
2013-03-09 11:18:01 +00:00
|
|
|
releaseibuf = NULL;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (bgpic->source == V3D_BGPIC_IMAGE) {
|
|
|
|
ima = bgpic->ima;
|
|
|
|
if (ima == NULL)
|
2011-11-07 12:55:18 +00:00
|
|
|
continue;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0);
|
2012-07-03 14:04:39 +00:00
|
|
|
if (ima->source == IMA_SRC_SEQUENCE && !(bgpic->iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
|
|
|
|
ibuf = NULL; /* frame is out of range, dont show */
|
|
|
|
}
|
|
|
|
else {
|
2015-04-06 10:40:12 -03:00
|
|
|
view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
|
2014-09-28 18:29:10 +02:00
|
|
|
ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
|
2013-03-09 11:18:01 +00:00
|
|
|
releaseibuf = ibuf;
|
2012-07-03 14:04:39 +00:00
|
|
|
}
|
2012-06-13 12:58:01 +00:00
|
|
|
|
|
|
|
image_aspect[0] = ima->aspx;
|
2014-09-27 01:32:25 +10:00
|
|
|
image_aspect[1] = ima->aspy;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
2012-06-06 11:40:01 +00:00
|
|
|
else if (bgpic->source == V3D_BGPIC_MOVIE) {
|
2012-07-06 22:48:28 +00:00
|
|
|
/* TODO: skip drawing when out of frame range (as image sequences do above) */
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (bgpic->flag & V3D_BGPIC_CAMERACLIP) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (scene->camera)
|
2013-09-09 11:37:37 +00:00
|
|
|
clip = BKE_object_movieclip_get(scene, scene->camera, true);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
2013-03-09 03:46:30 +00:00
|
|
|
else {
|
|
|
|
clip = bgpic->clip;
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (clip == NULL)
|
2011-11-07 12:55:18 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
|
2012-03-25 23:54:33 +00:00
|
|
|
ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-13 12:58:01 +00:00
|
|
|
image_aspect[0] = clip->aspx;
|
2012-08-09 16:56:42 +00:00
|
|
|
image_aspect[1] = clip->aspy;
|
2012-06-13 12:58:01 +00:00
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
/* working with ibuf from image and clip has got different workflow now.
|
2012-03-03 16:31:46 +00:00
|
|
|
* ibuf acquired from clip is referenced by cache system and should
|
|
|
|
* be dereferenced after usage. */
|
2012-03-25 23:54:33 +00:00
|
|
|
freeibuf = ibuf;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
2012-06-20 18:46:18 +00:00
|
|
|
else {
|
|
|
|
/* perhaps when loading future files... */
|
|
|
|
BLI_assert(0);
|
|
|
|
copy_v2_fl(image_aspect, 1.0f);
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ibuf == NULL)
|
2010-01-19 22:44:43 +00:00
|
|
|
continue;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (freeibuf)
|
2011-11-07 12:55:18 +00:00
|
|
|
IMB_freeImBuf(freeibuf);
|
2013-03-09 11:18:01 +00:00
|
|
|
if (releaseibuf)
|
2014-09-28 18:29:10 +02:00
|
|
|
BKE_image_release_ibuf(ima, releaseibuf, lock);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2010-01-19 22:44:43 +00:00
|
|
|
continue;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ibuf->rect == NULL)
|
2010-01-19 22:44:43 +00:00
|
|
|
IMB_rect_from_float(ibuf);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-06-06 11:40:01 +00:00
|
|
|
if (do_camera_frame) {
|
|
|
|
rctf vb;
|
2013-03-20 23:14:18 +00:00
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
|
2012-06-06 11:40:01 +00:00
|
|
|
x1 = vb.xmin;
|
|
|
|
y1 = vb.ymin;
|
|
|
|
x2 = vb.xmax;
|
|
|
|
y2 = vb.ymax;
|
|
|
|
}
|
|
|
|
else {
|
2012-06-06 14:38:47 +00:00
|
|
|
x1 = ar->winrct.xmin;
|
|
|
|
y1 = ar->winrct.ymin;
|
|
|
|
x2 = ar->winrct.xmax;
|
|
|
|
y2 = ar->winrct.ymax;
|
2012-06-06 11:40:01 +00:00
|
|
|
}
|
2012-06-13 12:58:01 +00:00
|
|
|
|
2012-06-13 13:23:48 +00:00
|
|
|
/* apply offset last - camera offset is different to offset in blender units */
|
|
|
|
/* so this has some sane way of working - this matches camera's shift _exactly_ */
|
|
|
|
{
|
2012-10-23 13:28:22 +00:00
|
|
|
const float max_dim = max_ff(x2 - x1, y2 - y1);
|
2012-06-13 13:23:48 +00:00
|
|
|
const float xof_scale = bgpic->xof * max_dim;
|
|
|
|
const float yof_scale = bgpic->yof * max_dim;
|
|
|
|
|
|
|
|
x1 += xof_scale;
|
|
|
|
y1 += yof_scale;
|
|
|
|
x2 += xof_scale;
|
|
|
|
y2 += yof_scale;
|
|
|
|
}
|
|
|
|
|
2015-02-04 15:05:22 +01:00
|
|
|
centx = (x1 + x2) / 2.0f;
|
|
|
|
centy = (y1 + y2) / 2.0f;
|
|
|
|
|
2012-06-13 12:58:01 +00:00
|
|
|
/* aspect correction */
|
2012-06-14 16:55:55 +00:00
|
|
|
if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) {
|
2012-06-13 12:58:01 +00:00
|
|
|
/* apply aspect from clip */
|
|
|
|
const float w_src = ibuf->x * image_aspect[0];
|
|
|
|
const float h_src = ibuf->y * image_aspect[1];
|
|
|
|
|
|
|
|
/* destination aspect is already applied from the camera frame */
|
|
|
|
const float w_dst = x1 - x2;
|
|
|
|
const float h_dst = y1 - y2;
|
|
|
|
|
|
|
|
const float asp_src = w_src / h_src;
|
|
|
|
const float asp_dst = w_dst / h_dst;
|
|
|
|
|
|
|
|
if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
|
|
|
|
if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) {
|
|
|
|
/* fit X */
|
|
|
|
const float div = asp_src / asp_dst;
|
2015-02-04 15:05:22 +01:00
|
|
|
x1 = ((x1 - centx) * div) + centx;
|
|
|
|
x2 = ((x2 - centx) * div) + centx;
|
2012-06-13 12:58:01 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* fit Y */
|
|
|
|
const float div = asp_dst / asp_src;
|
2015-02-04 15:05:22 +01:00
|
|
|
y1 = ((y1 - centy) * div) + centy;
|
|
|
|
y2 = ((y2 - centy) * div) + centy;
|
2012-06-13 12:58:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-09-20 05:09:35 +00:00
|
|
|
float tvec[3];
|
2010-01-19 22:44:43 +00:00
|
|
|
float sco[2];
|
2012-03-25 23:54:33 +00:00
|
|
|
const float mval_f[2] = {1.0f, 0.0f};
|
2013-03-09 11:40:42 +00:00
|
|
|
const float co_zero[3] = {0};
|
|
|
|
float zfac;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
/* calc window coord */
|
2013-03-09 11:40:42 +00:00
|
|
|
zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
|
|
|
|
ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
|
2012-10-23 13:28:22 +00:00
|
|
|
fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
|
2012-03-25 23:54:33 +00:00
|
|
|
fac = 1.0f / fac;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-09-20 05:09:35 +00:00
|
|
|
asp = (float)ibuf->y / (float)ibuf->x;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-09-20 05:09:35 +00:00
|
|
|
zero_v3(tvec);
|
|
|
|
ED_view3d_project_float_v2_m4(ar, tvec, sco, rv3d->persmat);
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-09-20 05:09:35 +00:00
|
|
|
x1 = sco[0] + fac * (bgpic->xof - bgpic->size);
|
|
|
|
y1 = sco[1] + asp * fac * (bgpic->yof - bgpic->size);
|
|
|
|
x2 = sco[0] + fac * (bgpic->xof + bgpic->size);
|
|
|
|
y2 = sco[1] + asp * fac * (bgpic->yof + bgpic->size);
|
2015-02-04 15:05:22 +01:00
|
|
|
|
|
|
|
centx = (x1 + x2) / 2.0f;
|
|
|
|
centy = (y1 + y2) / 2.0f;
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* complete clip? */
|
2015-03-25 19:46:07 +11:00
|
|
|
BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
|
|
|
|
if (bgpic->rotation) {
|
|
|
|
BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
|
|
|
|
}
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2015-03-25 19:46:07 +11:00
|
|
|
if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (freeibuf)
|
2011-11-07 12:55:18 +00:00
|
|
|
IMB_freeImBuf(freeibuf);
|
2013-03-09 11:18:01 +00:00
|
|
|
if (releaseibuf)
|
2014-09-28 18:29:10 +02:00
|
|
|
BKE_image_release_ibuf(ima, releaseibuf, lock);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
zoomx = (x2 - x1) / ibuf->x;
|
|
|
|
zoomy = (y2 - y1) / ibuf->y;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
/* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (zoomx < 1.0f || zoomy < 1.0f) {
|
2012-10-23 13:28:22 +00:00
|
|
|
float tzoom = min_ff(zoomx, zoomy);
|
2012-03-25 23:54:33 +00:00
|
|
|
int mip = 0;
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
|
2011-05-08 20:21:31 +00:00
|
|
|
IMB_remakemipmap(ibuf, 0);
|
2012-03-25 23:54:33 +00:00
|
|
|
ibuf->userflags &= ~IB_MIPMAP_INVALID;
|
2011-05-08 20:21:31 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (ibuf->mipmap[0] == NULL)
|
2010-03-14 18:22:04 +00:00
|
|
|
IMB_makemipmap(ibuf, 0);
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
|
|
|
|
tzoom *= 2.0f;
|
|
|
|
zoomx *= 2.0f;
|
|
|
|
zoomy *= 2.0f;
|
2010-01-19 22:44:43 +00:00
|
|
|
mip++;
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
if (mip > 0)
|
|
|
|
ibuf = ibuf->mipmap[mip - 1];
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
2010-01-19 22:44:43 +00:00
|
|
|
glDepthMask(0);
|
|
|
|
|
2010-02-01 15:32:55 +00:00
|
|
|
glEnable(GL_BLEND);
|
2010-01-19 22:44:43 +00:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
2010-02-01 15:32:55 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
2010-01-19 22:44:43 +00:00
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
|
2015-02-04 15:05:22 +01:00
|
|
|
glTranslatef(centx, centy, 0.0);
|
2015-03-24 00:02:09 +11:00
|
|
|
glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
|
2015-02-04 15:05:22 +01:00
|
|
|
|
2015-02-06 13:54:38 +11:00
|
|
|
if (bgpic->flag & V3D_BGPIC_FLIP_X) {
|
2015-02-04 15:05:22 +01:00
|
|
|
zoomx *= -1.0f;
|
|
|
|
x1 = x2;
|
|
|
|
}
|
2015-02-06 13:54:38 +11:00
|
|
|
if (bgpic->flag & V3D_BGPIC_FLIP_Y) {
|
2015-02-05 03:54:32 +11:00
|
|
|
zoomy *= -1.0f;
|
|
|
|
y1 = y2;
|
|
|
|
}
|
2010-01-19 22:44:43 +00:00
|
|
|
glPixelZoom(zoomx, zoomy);
|
2012-03-25 23:54:33 +00:00
|
|
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
|
2013-03-19 13:38:43 +00:00
|
|
|
|
|
|
|
/* could not use glaDrawPixelsAuto because it could fallback to
|
2014-05-08 04:53:05 +10:00
|
|
|
* glaDrawPixelsSafe in some cases, which will end up in missing
|
2013-03-19 13:38:43 +00:00
|
|
|
* alpha transparency for the background image (sergey)
|
|
|
|
*/
|
2015-02-04 15:05:22 +01:00
|
|
|
glaDrawPixelsTex(x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
glPixelZoom(1.0, 1.0);
|
|
|
|
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
|
|
|
|
|
2010-02-01 15:32:55 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
|
|
|
glDepthMask(1);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2013-03-09 11:18:01 +00:00
|
|
|
if (freeibuf)
|
2013-03-10 05:46:24 +00:00
|
|
|
IMB_freeImBuf(freeibuf);
|
2013-03-09 11:18:01 +00:00
|
|
|
if (releaseibuf)
|
2014-09-28 18:29:10 +02:00
|
|
|
BKE_image_release_ibuf(ima, releaseibuf, lock);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-06 11:40:01 +00:00
|
|
|
static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
|
2013-03-20 23:14:18 +00:00
|
|
|
const bool do_foreground, const bool do_camera_frame)
|
2012-04-10 14:59:06 +00:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
if ((v3d->flag & V3D_DISPBGPICS) == 0)
|
|
|
|
return;
|
|
|
|
|
2012-07-23 16:41:04 +00:00
|
|
|
/* disabled - mango request, since footage /w only render is quite useful
|
|
|
|
* and this option is easy to disable all background images at once */
|
|
|
|
#if 0
|
2012-04-10 14:59:06 +00:00
|
|
|
if (v3d->flag2 & V3D_RENDER_OVERRIDE)
|
|
|
|
return;
|
2012-07-23 16:41:04 +00:00
|
|
|
#endif
|
2012-04-10 14:59:06 +00:00
|
|
|
|
|
|
|
if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2012-08-08 18:21:54 +00:00
|
|
|
view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
|
2012-04-10 14:59:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2012-08-08 18:21:54 +00:00
|
|
|
view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
|
2012-04-10 14:59:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
/* ****************** View3d afterdraw *************** */
|
|
|
|
|
|
|
|
typedef struct View3DAfter {
|
|
|
|
struct View3DAfter *next, *prev;
|
|
|
|
struct Base *base;
|
2012-06-10 10:15:49 +00:00
|
|
|
short dflag;
|
2008-12-19 12:14:58 +00:00
|
|
|
} View3DAfter;
|
|
|
|
|
|
|
|
/* temp storage of Objects that need to be drawn as last */
|
2012-06-10 10:15:49 +00:00
|
|
|
void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
|
2012-05-16 08:42:50 +00:00
|
|
|
BLI_assert((base->flag & OB_FROMDUPLI) == 0);
|
2010-08-25 14:23:02 +00:00
|
|
|
BLI_addtail(lb, v3da);
|
2012-03-25 23:54:33 +00:00
|
|
|
v3da->base = base;
|
2012-06-10 10:15:49 +00:00
|
|
|
v3da->dflag = dflag;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* disables write in zbuffer and draws it over */
|
2008-12-19 14:14:43 +00:00
|
|
|
static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
2015-10-09 21:23:14 +02:00
|
|
|
View3DAfter *v3da;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
glDepthMask(GL_FALSE);
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->transp = true;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
|
2012-06-10 10:15:49 +00:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
|
2010-08-25 14:23:02 +00:00
|
|
|
MEM_freeN(v3da);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->transp = false;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
glDepthMask(GL_TRUE);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-08-25 14:23:02 +00:00
|
|
|
/* clears zbuffer and draws it over */
|
2015-02-13 14:38:26 +01:00
|
|
|
static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
|
2010-08-25 14:23:02 +00:00
|
|
|
{
|
2015-10-09 21:23:14 +02:00
|
|
|
View3DAfter *v3da;
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
if (*clear && v3d->zbuf) {
|
2010-08-25 14:23:02 +00:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
2015-02-13 14:38:26 +01:00
|
|
|
*clear = false;
|
|
|
|
}
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = true;
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
|
2012-06-10 10:15:49 +00:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
|
2010-08-25 14:23:02 +00:00
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = false;
|
2010-08-25 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* clears zbuffer and draws it over */
|
2014-04-12 15:34:59 +10:00
|
|
|
static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
|
2010-08-25 14:23:02 +00:00
|
|
|
{
|
2015-10-09 21:23:14 +02:00
|
|
|
View3DAfter *v3da;
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (clear && v3d->zbuf)
|
2010-08-25 14:23:02 +00:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = true;
|
|
|
|
v3d->transp = true;
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
|
2012-06-10 10:15:49 +00:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
|
2010-08-25 14:23:02 +00:00
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->transp = false;
|
|
|
|
v3d->xray = false;
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
glDepthMask(GL_TRUE);
|
2010-08-25 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
2017-03-10 03:15:58 +11:00
|
|
|
/* clears zbuffer and draws it over,
|
|
|
|
* note that in the select version we don't care about transparent flag as with regular drawing */
|
|
|
|
static void view3d_draw_xray_select(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
|
|
|
|
{
|
|
|
|
/* Not ideal, but we need to read from the previous depths before clearing
|
|
|
|
* otherwise we could have a function to load the depths after drawing.
|
|
|
|
*
|
|
|
|
* Clearing the depth buffer isn't all that common between drawing objects so accept this for now.
|
|
|
|
*/
|
|
|
|
if (U.gpu_select_pick_deph) {
|
|
|
|
GPU_select_load_id(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
View3DAfter *v3da;
|
|
|
|
if (*clear && v3d->zbuf) {
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
*clear = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
v3d->xray = true;
|
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
|
|
|
|
if (GPU_select_load_id(v3da->base->selcol)) {
|
|
|
|
draw_object_select(scene, ar, v3d, v3da->base, v3da->dflag);
|
|
|
|
}
|
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
|
|
|
v3d->xray = false;
|
|
|
|
}
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
/* *********************** */
|
|
|
|
|
|
|
|
/*
|
2012-03-03 16:31:46 +00:00
|
|
|
* In most cases call draw_dupli_objects,
|
|
|
|
* draw_dupli_objects_color was added because when drawing set dupli's
|
|
|
|
* we need to force the color
|
2008-12-19 12:14:58 +00:00
|
|
|
*/
|
2010-03-01 17:53:33 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
int dupli_ob_sort(void *arg1, void *arg2)
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
void *p1 = ((DupliObject *)arg1)->ob;
|
|
|
|
void *p2 = ((DupliObject *)arg2)->ob;
|
2010-03-01 17:53:33 +00:00
|
|
|
int val = 0;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (p1 < p2) val = -1;
|
|
|
|
else if (p1 > p2) val = 1;
|
2010-03-01 17:53:33 +00:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-03-04 15:58:27 +00:00
|
|
|
|
2010-03-05 08:53:16 +00:00
|
|
|
static DupliObject *dupli_step(DupliObject *dob)
|
2010-03-04 15:58:27 +00:00
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
while (dob && dob->no_draw)
|
2012-03-25 23:54:33 +00:00
|
|
|
dob = dob->next;
|
2010-03-05 08:53:16 +00:00
|
|
|
return dob;
|
2010-03-04 15:58:27 +00:00
|
|
|
}
|
|
|
|
|
2014-06-04 14:22:29 +10:00
|
|
|
static void draw_dupli_objects_color(
|
|
|
|
Scene *scene, ARegion *ar, View3D *v3d, Base *base,
|
|
|
|
const short dflag, const int color)
|
2010-03-04 15:58:27 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2008-12-19 12:14:58 +00:00
|
|
|
ListBase *lb;
|
2013-12-17 14:42:47 -08:00
|
|
|
LodLevel *savedlod;
|
2012-03-25 23:54:33 +00:00
|
|
|
DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
|
2012-05-17 02:50:07 +00:00
|
|
|
Base tbase = {NULL};
|
2010-02-06 14:32:50 +00:00
|
|
|
BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
|
2012-03-25 23:54:33 +00:00
|
|
|
GLuint displist = 0;
|
2014-06-04 14:22:29 +10:00
|
|
|
unsigned char color_rgb[3];
|
|
|
|
const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
|
2014-09-19 18:04:12 +02:00
|
|
|
short transflag;
|
|
|
|
bool use_displist = false; /* -1 is initialize */
|
2013-01-18 19:01:26 +00:00
|
|
|
char dt;
|
|
|
|
short dtx;
|
2014-04-29 17:38:39 +06:00
|
|
|
DupliApplyData *apply_data;
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
|
2014-07-17 23:49:08 +02:00
|
|
|
if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
|
2014-06-04 14:22:29 +10:00
|
|
|
|
|
|
|
if (dflag & DRAW_CONSTCOLOR) {
|
|
|
|
BLI_assert(color == TH_UNDEFINED);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
|
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tbase.flag = OB_FROMDUPLI | base->flag;
|
2013-12-26 17:24:42 +06:00
|
|
|
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
|
2014-11-16 13:57:58 +01:00
|
|
|
// BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
|
2010-03-04 15:58:27 +00:00
|
|
|
|
2015-04-02 17:13:24 +02:00
|
|
|
apply_data = duplilist_apply(base->object, scene, lb);
|
2014-04-29 17:38:39 +06:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
dob = dupli_step(lb->first);
|
|
|
|
if (dob) dob_next = dupli_step(dob->next);
|
2010-03-05 08:53:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
|
2016-03-04 12:32:35 +01:00
|
|
|
bool testbb = false;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tbase.object = dob->ob;
|
2010-03-04 15:58:27 +00:00
|
|
|
|
2013-12-17 14:42:47 -08:00
|
|
|
/* Make sure lod is updated from dupli's position */
|
|
|
|
savedlod = dob->ob->currentlod;
|
2014-04-09 11:48:04 +10:00
|
|
|
|
|
|
|
#ifdef WITH_GAMEENGINE
|
|
|
|
if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
|
|
|
|
BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
|
|
|
|
}
|
|
|
|
#endif
|
2013-12-17 14:42:47 -08:00
|
|
|
|
2012-11-25 16:12:07 +00:00
|
|
|
/* extra service: draw the duplicator in drawtype of parent, minimum taken
|
|
|
|
* to allow e.g. boundbox box objects in groups for LOD */
|
|
|
|
dt = tbase.object->dt;
|
|
|
|
tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
|
|
|
|
|
|
|
|
/* inherit draw extra, but not if a boundbox under the assumption that this
|
|
|
|
* is intended to speed up drawing, and drawing extra (especially wire) can
|
|
|
|
* slow it down too much */
|
|
|
|
dtx = tbase.object->dtx;
|
2012-11-26 11:03:14 +00:00
|
|
|
if (tbase.object->dt != OB_BOUNDBOX)
|
2012-11-25 16:12:07 +00:00
|
|
|
tbase.object->dtx = base->object->dtx;
|
2010-03-04 15:58:27 +00:00
|
|
|
|
|
|
|
/* negative scale flag has to propagate */
|
2012-03-25 23:54:33 +00:00
|
|
|
transflag = tbase.object->transflag;
|
2013-11-19 03:27:47 +11:00
|
|
|
|
|
|
|
if (is_negative_m4(dob->mat))
|
|
|
|
tbase.object->transflag |= OB_NEG_SCALE;
|
|
|
|
else
|
|
|
|
tbase.object->transflag &= ~OB_NEG_SCALE;
|
2014-09-19 18:04:12 +02:00
|
|
|
|
2014-06-04 14:22:29 +10:00
|
|
|
/* should move outside the loop but possible color is set in draw_object still */
|
|
|
|
if ((dflag & DRAW_CONSTCOLOR) == 0) {
|
|
|
|
glColor3ubv(color_rgb);
|
|
|
|
}
|
2014-09-19 18:04:12 +02:00
|
|
|
|
2010-03-04 15:58:27 +00:00
|
|
|
/* generate displist, test for new object */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (dob_prev && dob_prev->ob != dob->ob) {
|
2013-03-20 23:14:18 +00:00
|
|
|
if (use_displist == true)
|
2008-12-19 12:14:58 +00:00
|
|
|
glDeleteLists(displist, 1);
|
2014-09-19 18:04:12 +02:00
|
|
|
|
|
|
|
use_displist = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
|
|
|
|
bb = *bb_tmp; /* must make a copy */
|
|
|
|
testbb = true;
|
2010-03-04 15:58:27 +00:00
|
|
|
}
|
|
|
|
|
2014-09-19 18:04:12 +02:00
|
|
|
if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
|
|
|
|
/* generate displist */
|
|
|
|
if (use_displist == false) {
|
|
|
|
|
|
|
|
/* note, since this was added, its checked (dob->type == OB_DUPLIGROUP)
|
|
|
|
* however this is very slow, it was probably needed for the NLA
|
|
|
|
* offset feature (used in group-duplicate.blend but no longer works in 2.5)
|
|
|
|
* so for now it should be ok to - campbell */
|
|
|
|
|
|
|
|
if ( /* if this is the last no need to make a displist */
|
2014-09-27 00:57:54 +10:00
|
|
|
(dob_next == NULL || dob_next->ob != dob->ob) ||
|
|
|
|
/* lamp drawing messes with matrices, could be handled smarter... but this works */
|
|
|
|
(dob->ob->type == OB_LAMP) ||
|
|
|
|
(dob->type == OB_DUPLIGROUP && dob->animated) ||
|
|
|
|
!bb_tmp ||
|
|
|
|
draw_glsl_material(scene, dob->ob, v3d, dt) ||
|
|
|
|
check_object_draw_texture(scene, v3d, dt) ||
|
2014-10-02 18:17:33 +02:00
|
|
|
(v3d->flag2 & V3D_SOLID_MATCAP) != 0)
|
2014-09-19 18:04:12 +02:00
|
|
|
{
|
|
|
|
// printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2);
|
|
|
|
use_displist = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name + 2);
|
|
|
|
|
|
|
|
/* disable boundbox check for list creation */
|
|
|
|
BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 1);
|
|
|
|
/* need this for next part of code */
|
|
|
|
unit_m4(dob->ob->obmat); /* obmat gets restored */
|
|
|
|
|
|
|
|
displist = glGenLists(1);
|
|
|
|
glNewList(displist, GL_COMPILE);
|
|
|
|
draw_object(scene, ar, v3d, &tbase, dflag_dupli);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
use_displist = true;
|
|
|
|
BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 0);
|
|
|
|
}
|
2010-03-04 15:58:27 +00:00
|
|
|
}
|
2014-09-19 18:04:12 +02:00
|
|
|
|
|
|
|
if (use_displist) {
|
|
|
|
glPushMatrix();
|
2014-03-20 12:17:44 +11:00
|
|
|
glMultMatrixf(dob->mat);
|
2010-03-04 15:58:27 +00:00
|
|
|
glCallList(displist);
|
2014-09-19 18:04:12 +02:00
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_m4_m4(dob->ob->obmat, dob->mat);
|
2015-07-14 18:48:54 +02:00
|
|
|
GPU_begin_dupli_object(dob);
|
2014-09-19 18:04:12 +02:00
|
|
|
draw_object(scene, ar, v3d, &tbase, dflag_dupli);
|
2015-07-14 18:48:54 +02:00
|
|
|
GPU_end_dupli_object();
|
2014-03-20 12:17:44 +11:00
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2014-09-19 18:04:12 +02:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tbase.object->dt = dt;
|
|
|
|
tbase.object->dtx = dtx;
|
|
|
|
tbase.object->transflag = transflag;
|
2013-12-17 14:42:47 -08:00
|
|
|
tbase.object->currentlod = savedlod;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2014-04-29 17:38:39 +06:00
|
|
|
|
|
|
|
if (apply_data) {
|
2014-07-09 12:17:05 +02:00
|
|
|
duplilist_restore(lb, apply_data);
|
2014-04-29 17:38:39 +06:00
|
|
|
duplilist_free_apply_data(apply_data);
|
|
|
|
}
|
|
|
|
|
2014-01-23 10:20:42 +01:00
|
|
|
free_object_duplilist(lb);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (use_displist)
|
2008-12-19 12:14:58 +00:00
|
|
|
glDeleteLists(displist, 1);
|
|
|
|
}
|
|
|
|
|
2008-12-19 14:14:43 +00:00
|
|
|
static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
|
|
|
/* define the color here so draw_dupli_objects_color can be called
|
2012-03-03 16:31:46 +00:00
|
|
|
* from the set loop */
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
int color = (base->flag & SELECT) ? TH_SELECT : TH_WIRE;
|
2008-12-19 12:14:58 +00:00
|
|
|
/* debug */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (base->object->dup_group && base->object->dup_group->id.us < 1)
|
|
|
|
color = TH_REDALERT;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_dupli_objects_color(scene, ar, v3d, base, 0, color);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
2013-03-21 11:48:13 +00:00
|
|
|
/* XXX warning, not using gpu offscreen here */
|
2010-10-21 07:38:09 +00:00
|
|
|
void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
|
|
|
|
{
|
2012-10-21 05:46:41 +00:00
|
|
|
int x, y, w, h;
|
2010-11-03 06:31:53 +00:00
|
|
|
rcti r;
|
2015-11-28 17:14:45 +01:00
|
|
|
/* clamp rect by region */
|
2010-10-27 08:55:13 +00:00
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
r.xmin = 0;
|
2012-03-25 23:54:33 +00:00
|
|
|
r.xmax = ar->winx - 1;
|
2012-03-24 02:51:46 +00:00
|
|
|
r.ymin = 0;
|
2012-03-25 23:54:33 +00:00
|
|
|
r.ymax = ar->winy - 1;
|
2010-11-03 06:31:53 +00:00
|
|
|
|
2010-10-21 07:38:09 +00:00
|
|
|
/* Constrain rect to depth bounds */
|
2012-07-15 00:29:56 +00:00
|
|
|
BLI_rcti_isect(&r, rect, rect);
|
2010-10-21 07:38:09 +00:00
|
|
|
|
|
|
|
/* assign values to compare with the ViewDepths */
|
2012-03-25 23:54:33 +00:00
|
|
|
x = rect->xmin;
|
|
|
|
y = rect->ymin;
|
2010-10-21 07:38:09 +00:00
|
|
|
|
2012-09-15 11:48:20 +00:00
|
|
|
w = BLI_rcti_size_x(rect);
|
|
|
|
h = BLI_rcti_size_y(rect);
|
2010-10-21 07:38:09 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (w <= 0 || h <= 0) {
|
|
|
|
if (d->depths)
|
2010-10-27 08:55:13 +00:00
|
|
|
MEM_freeN(d->depths);
|
2012-03-25 23:54:33 +00:00
|
|
|
d->depths = NULL;
|
2010-10-27 08:55:13 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
d->damaged = false;
|
2010-10-27 08:55:13 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (d->w != w ||
|
|
|
|
d->h != h ||
|
|
|
|
d->x != x ||
|
|
|
|
d->y != y ||
|
|
|
|
d->depths == NULL
|
|
|
|
)
|
|
|
|
{
|
|
|
|
d->x = x;
|
|
|
|
d->y = y;
|
|
|
|
d->w = w;
|
|
|
|
d->h = h;
|
2010-10-21 07:38:09 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d->depths)
|
2010-10-21 07:38:09 +00:00
|
|
|
MEM_freeN(d->depths);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
|
2010-10-21 07:38:09 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
d->damaged = true;
|
2010-10-21 07:38:09 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d->damaged) {
|
2013-03-21 11:48:13 +00:00
|
|
|
/* XXX using special function here, it doesn't use the gpu offscreen system */
|
|
|
|
view3d_opengl_read_Z_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
|
2012-03-25 23:54:33 +00:00
|
|
|
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
|
2013-03-20 23:14:18 +00:00
|
|
|
d->damaged = false;
|
2010-10-21 07:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2010-10-21 07:38:09 +00:00
|
|
|
/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
|
2011-05-21 08:56:37 +00:00
|
|
|
void ED_view3d_depth_update(ARegion *ar)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
|
2008-12-18 17:38:21 +00:00
|
|
|
/* Create storage for, and, if necessary, copy depth buffer */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (!rv3d->depths) rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->depths) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewDepths *d = rv3d->depths;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d->w != ar->winx ||
|
2012-03-25 23:54:33 +00:00
|
|
|
d->h != ar->winy ||
|
|
|
|
!d->depths)
|
|
|
|
{
|
|
|
|
d->w = ar->winx;
|
|
|
|
d->h = ar->winy;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d->depths)
|
2008-12-18 17:38:21 +00:00
|
|
|
MEM_freeN(d->depths);
|
2012-03-25 23:54:33 +00:00
|
|
|
d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
|
2013-03-20 23:14:18 +00:00
|
|
|
d->damaged = true;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d->damaged) {
|
2013-03-15 19:56:33 +00:00
|
|
|
view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
|
2012-03-25 23:54:33 +00:00
|
|
|
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
d->damaged = false;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-21 07:38:09 +00:00
|
|
|
/* utility function to find the closest Z value, use for autodepth */
|
|
|
|
float view3d_depth_near(ViewDepths *d)
|
|
|
|
{
|
|
|
|
/* convert to float for comparisons */
|
2012-03-25 23:54:33 +00:00
|
|
|
const float near = (float)d->depth_range[0];
|
|
|
|
const float far_real = (float)d->depth_range[1];
|
|
|
|
float far = far_real;
|
2010-10-21 07:38:09 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
const float *depths = d->depths;
|
|
|
|
float depth = FLT_MAX;
|
|
|
|
int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
|
2010-10-21 07:38:09 +00:00
|
|
|
|
|
|
|
/* far is both the starting 'far' value
|
2012-10-21 05:46:41 +00:00
|
|
|
* and the closest value found. */
|
2012-02-22 16:52:06 +00:00
|
|
|
while (i--) {
|
2012-03-25 23:54:33 +00:00
|
|
|
depth = *depths++;
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((depth < far) && (depth > near)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
far = depth;
|
2010-10-21 07:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return far == far_real ? FLT_MAX : far;
|
|
|
|
}
|
|
|
|
|
2014-06-19 17:35:23 +10:00
|
|
|
void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
|
2010-01-01 16:46:27 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
short zbuf = v3d->zbuf;
|
2017-05-10 13:13:55 +02:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2010-01-01 16:46:27 +00:00
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
/* Setup view matrix. */
|
2017-05-26 16:16:33 +10:00
|
|
|
ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
|
2010-01-01 16:46:27 +00:00
|
|
|
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->zbuf = true;
|
2010-01-01 16:46:27 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
2012-12-17 02:34:53 +00:00
|
|
|
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
|
2015-12-13 21:03:13 +13:00
|
|
|
ED_gpencil_draw_view3d(NULL, scene, v3d, ar, true);
|
2012-12-17 02:34:53 +00:00
|
|
|
}
|
2010-01-03 01:55:20 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d->zbuf = zbuf;
|
2010-01-01 16:46:27 +00:00
|
|
|
}
|
|
|
|
|
2017-04-27 00:01:23 +10:00
|
|
|
static void view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
|
|
|
Base *base;
|
2017-04-27 00:01:23 +10:00
|
|
|
|
2014-06-04 14:22:29 +10:00
|
|
|
/* no need for color when drawing depth buffer */
|
|
|
|
const short dflag_depth = DRAW_CONSTCOLOR;
|
2015-07-21 11:12:39 +10:00
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
/* draw set first */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (scene->set) {
|
2010-12-17 15:37:59 +00:00
|
|
|
Scene *sce_iter;
|
2012-02-22 16:52:06 +00:00
|
|
|
for (SETLOOPER(scene->set, sce_iter, base)) {
|
|
|
|
if (v3d->lay & base->lay) {
|
2014-06-19 17:35:23 +10:00
|
|
|
draw_object(scene, ar, v3d, base, 0);
|
|
|
|
if (base->object->transflag & OB_DUPLI) {
|
|
|
|
draw_dupli_objects_color(scene, ar, v3d, base, dflag_depth, TH_UNDEFINED);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->lay & base->lay) {
|
2014-06-19 17:35:23 +10:00
|
|
|
/* dupli drawing */
|
|
|
|
if (base->object->transflag & OB_DUPLI) {
|
|
|
|
draw_dupli_objects_color(scene, ar, v3d, base, dflag_depth, TH_UNDEFINED);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2014-06-19 17:35:23 +10:00
|
|
|
draw_object(scene, ar, v3d, base, dflag_depth);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* this isn't that nice, draw xray objects as if they are normal */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->afterdraw_transp.first ||
|
|
|
|
v3d->afterdraw_xray.first ||
|
|
|
|
v3d->afterdraw_xraytransp.first)
|
|
|
|
{
|
2015-10-09 21:23:14 +02:00
|
|
|
View3DAfter *v3da;
|
2010-07-26 01:59:50 +00:00
|
|
|
int mask_orig;
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = true;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2010-07-26 01:59:50 +00:00
|
|
|
/* transp materials can change the depth mask, see #21388 */
|
|
|
|
glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
|
|
|
|
|
2010-08-25 14:23:02 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
|
2010-08-25 14:23:02 +00:00
|
|
|
glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
|
2015-10-09 21:23:14 +02:00
|
|
|
for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, dflag_depth);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2010-08-25 14:23:02 +00:00
|
|
|
glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2010-08-25 14:23:02 +00:00
|
|
|
|
|
|
|
/* draw 3 passes, transp/xray/xraytransp */
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = false;
|
|
|
|
v3d->transp = true;
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, dflag_depth);
|
2010-08-25 14:23:02 +00:00
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = true;
|
|
|
|
v3d->transp = false;
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, dflag_depth);
|
2010-08-25 14:23:02 +00:00
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = true;
|
|
|
|
v3d->transp = true;
|
2015-10-09 21:23:14 +02:00
|
|
|
while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_object(scene, ar, v3d, v3da->base, dflag_depth);
|
2008-12-19 12:14:58 +00:00
|
|
|
MEM_freeN(v3da);
|
|
|
|
}
|
2010-08-25 14:23:02 +00:00
|
|
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
v3d->xray = false;
|
|
|
|
v3d->transp = false;
|
2010-07-26 01:59:50 +00:00
|
|
|
|
|
|
|
glDepthMask(mask_orig);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2017-04-27 00:01:23 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
|
|
|
|
{
|
2017-08-24 23:19:27 +10:00
|
|
|
struct bThemeState theme_state;
|
2017-04-27 00:01:23 +10:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
short zbuf = v3d->zbuf;
|
|
|
|
short flag = v3d->flag;
|
|
|
|
float glalphaclip = U.glalphaclip;
|
|
|
|
int obcenter_dia = U.obcenter_dia;
|
|
|
|
/* temp set drawtype to solid */
|
|
|
|
|
|
|
|
/* Setting these temporarily is not nice */
|
|
|
|
v3d->flag &= ~V3D_SELECT_OUTLINE;
|
|
|
|
U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
|
|
|
|
U.obcenter_dia = 0;
|
|
|
|
|
2017-08-24 23:19:27 +10:00
|
|
|
/* Tools may request depth outside of regular drawing code. */
|
|
|
|
UI_Theme_Store(&theme_state);
|
|
|
|
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
/* Setup view matrix. */
|
2017-05-10 16:54:01 +02:00
|
|
|
ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
|
2017-04-27 00:01:23 +10:00
|
|
|
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2017-04-27 00:01:23 +10:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
|
|
|
ED_view3d_clipping_set(rv3d);
|
|
|
|
}
|
|
|
|
/* get surface depth without bias */
|
|
|
|
rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
|
|
|
|
|
|
|
|
v3d->zbuf = true;
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
view3d_draw_depth_loop(scene, ar, v3d);
|
|
|
|
|
2015-07-21 11:12:39 +10:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
2012-02-28 13:03:56 +00:00
|
|
|
ED_view3d_clipping_disable();
|
2015-07-21 11:12:39 +10:00
|
|
|
}
|
|
|
|
rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
|
2010-02-12 11:03:41 +00:00
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
v3d->zbuf = zbuf;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
2010-02-12 11:03:41 +00:00
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
U.glalphaclip = glalphaclip;
|
|
|
|
v3d->flag = flag;
|
2012-03-25 23:54:33 +00:00
|
|
|
U.obcenter_dia = obcenter_dia;
|
2017-08-24 23:19:27 +10:00
|
|
|
|
|
|
|
UI_Theme_Restore(&theme_state);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
2017-03-10 03:15:58 +11:00
|
|
|
void ED_view3d_draw_select_loop(
|
|
|
|
ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
|
|
|
|
bool use_obedit_skip, bool use_nearest)
|
|
|
|
{
|
|
|
|
short code = 1;
|
|
|
|
const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
|
|
|
|
|
|
|
|
if (vc->obedit && vc->obedit->type == OB_MBALL) {
|
|
|
|
draw_object(scene, ar, v3d, BASACT, dflag);
|
|
|
|
}
|
|
|
|
else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
|
|
|
|
/* if not drawing sketch, draw bones */
|
|
|
|
if (!BDR_drawSketchNames(vc)) {
|
|
|
|
draw_object(scene, ar, v3d, BASACT, dflag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Base *base;
|
|
|
|
|
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
|
|
|
if (base->lay & v3d->lay) {
|
|
|
|
|
|
|
|
if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
|
|
|
|
(use_obedit_skip && (scene->obedit->data == base->object->data)))
|
|
|
|
{
|
|
|
|
base->selcol = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
base->selcol = code;
|
|
|
|
|
|
|
|
if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) {
|
|
|
|
ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (GPU_select_load_id(code)) {
|
|
|
|
draw_object_select(scene, ar, v3d, base, dflag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
code++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (use_nearest) {
|
|
|
|
bool xrayclear = true;
|
|
|
|
if (v3d->afterdraw_xray.first) {
|
|
|
|
view3d_draw_xray_select(scene, ar, v3d, &xrayclear);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
typedef struct View3DShadow {
|
|
|
|
struct View3DShadow *next, *prev;
|
|
|
|
GPULamp *lamp;
|
|
|
|
} View3DShadow;
|
|
|
|
|
2015-08-24 22:02:41 +02:00
|
|
|
static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
|
|
|
|
Object *ob, Object *par,
|
2015-08-24 23:11:11 +02:00
|
|
|
float obmat[4][4], unsigned int lay,
|
2015-08-24 22:02:41 +02:00
|
|
|
ListBase *shadows, SceneRenderLayer *srl)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
|
|
|
GPULamp *lamp;
|
2012-03-25 23:54:33 +00:00
|
|
|
Lamp *la = (Lamp *)ob->data;
|
2008-12-19 12:14:58 +00:00
|
|
|
View3DShadow *shadow;
|
2014-04-28 01:08:10 +09:00
|
|
|
unsigned int layers;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
lamp = GPU_lamp_from_blender(scene, ob, par);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lamp) {
|
2015-08-24 22:02:41 +02:00
|
|
|
GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
|
2009-06-08 20:08:19 +00:00
|
|
|
GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2015-08-24 22:02:41 +02:00
|
|
|
layers = lay & v3d->lay;
|
2014-04-28 01:08:10 +09:00
|
|
|
if (srl)
|
|
|
|
layers &= srl->lay;
|
|
|
|
|
2016-03-21 16:06:04 +11:00
|
|
|
if (layers &&
|
|
|
|
GPU_lamp_has_shadow_buffer(lamp) &&
|
|
|
|
/* keep last, may do string lookup */
|
2017-08-12 13:22:26 +02:00
|
|
|
GPU_lamp_visible(lamp, srl, NULL))
|
2016-03-21 16:06:04 +11:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
|
2008-12-19 12:14:58 +00:00
|
|
|
shadow->lamp = lamp;
|
|
|
|
BLI_addtail(shadows, shadow);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-23 22:32:49 +01:00
|
|
|
static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
|
|
|
ListBase shadows;
|
|
|
|
View3DShadow *shadow;
|
2010-12-17 15:37:59 +00:00
|
|
|
Scene *sce_iter;
|
2008-12-19 12:14:58 +00:00
|
|
|
Base *base;
|
|
|
|
Object *ob;
|
2015-03-23 22:32:49 +01:00
|
|
|
World *world = scene->world;
|
2014-05-29 14:53:33 +09:00
|
|
|
SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&shadows);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
/* update lamp transform and gather shadow lamps */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (SETLOOPER(scene, sce_iter, base)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ob = base->object;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->type == OB_LAMP)
|
2015-08-24 22:02:41 +02:00
|
|
|
gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows, srl);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
if (ob->transflag & OB_DUPLI) {
|
|
|
|
DupliObject *dob;
|
2013-12-26 17:24:42 +06:00
|
|
|
ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (dob = lb->first; dob; dob = dob->next)
|
|
|
|
if (dob->ob->type == OB_LAMP)
|
2015-08-24 22:02:41 +02:00
|
|
|
gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows, srl);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
free_object_duplilist(lb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* render shadows after updating all lamps, nested object_duplilist
|
2012-03-03 11:45:08 +00:00
|
|
|
* don't work correct since it's replacing object matrices */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (shadow = shadows.first; shadow; shadow = shadow->next) {
|
2008-12-19 12:14:58 +00:00
|
|
|
/* this needs to be done better .. */
|
|
|
|
float viewmat[4][4], winmat[4][4];
|
2012-03-25 23:54:33 +00:00
|
|
|
int drawtype, lay, winsize, flag2 = v3d->flag2;
|
|
|
|
ARegion ar = {NULL};
|
|
|
|
RegionView3D rv3d = {{{0}}};
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
drawtype = v3d->drawtype;
|
|
|
|
lay = v3d->lay;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
v3d->drawtype = OB_SOLID;
|
|
|
|
v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
|
2014-10-02 18:19:54 +02:00
|
|
|
v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
|
2011-08-24 20:28:54 +00:00
|
|
|
v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
|
2010-04-06 01:34:55 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ar.regiondata = &rv3d;
|
|
|
|
ar.regiontype = RGN_TYPE_WINDOW;
|
|
|
|
rv3d.persp = RV3D_CAMOB;
|
2010-04-06 01:34:55 +00:00
|
|
|
copy_m4_m4(rv3d.winmat, winmat);
|
|
|
|
copy_m4_m4(rv3d.viewmat, viewmat);
|
|
|
|
invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
|
2010-04-06 01:34:55 +00:00
|
|
|
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
|
|
|
|
|
2012-10-23 12:25:08 +00:00
|
|
|
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
|
2015-02-12 18:54:41 +01:00
|
|
|
ED_view3d_draw_offscreen(
|
|
|
|
scene, v3d, &ar, winsize, winsize, viewmat, winmat,
|
|
|
|
false, false, true,
|
2015-04-06 10:40:12 -03:00
|
|
|
NULL, NULL, NULL, NULL);
|
2008-12-19 12:14:58 +00:00
|
|
|
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d->drawtype = drawtype;
|
|
|
|
v3d->lay = lay;
|
2010-07-04 17:22:24 +00:00
|
|
|
v3d->flag2 = flag2;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BLI_freelistN(&shadows);
|
2015-03-23 22:32:49 +01:00
|
|
|
|
|
|
|
/* update world values */
|
|
|
|
if (world) {
|
|
|
|
GPU_mist_update_enable(world->mode & WO_MIST);
|
|
|
|
GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr);
|
|
|
|
GPU_horizon_update_color(&world->horr);
|
|
|
|
GPU_ambient_update_color(&world->ambr);
|
Environment lighting for the GLSL mode
Environment lighting (aka ambient) is a key component of any renderer.
It's implemented like the Environment lighting of BI render for Approximate Gather mode. It support "Sky Color" and "White" Environment lighting modes.
It would be great if the user could see actual lighting conditions right in the Blender viewport instead of waiting for the renderer to complete the final image, exporting for external renderer or for a game engine.
Before:
{F113921}
After:
{F113922}
Example file: {F319013}
Original author: valentin_b4w
Alexander (Blend4Web Team)
Reviewers: valentin_b4w, campbellbarton, merwin, brecht
Reviewed By: brecht
Subscribers: panzergame, youle, duarteframos, AlexKowel, yurikovelenov, dingto, Evgeny_Rodygin
Projects: #rendering, #opengl_gfx
Differential Revision: https://developer.blender.org/D810
2016-07-04 11:01:32 +03:00
|
|
|
GPU_zenith_update_color(&world->zenr);
|
2015-03-23 22:32:49 +01:00
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
2009-01-07 14:46:50 +00:00
|
|
|
/* *********************** customdata **************** */
|
|
|
|
|
2015-03-21 22:34:20 +11:00
|
|
|
CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
|
2011-03-13 02:44:25 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
CustomDataMask mask = 0;
|
2016-05-22 16:23:26 +02:00
|
|
|
const int drawtype = view3d_effective_drawtype(v3d);
|
2011-10-23 13:00:41 +00:00
|
|
|
|
2016-05-22 16:23:26 +02:00
|
|
|
if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL) ||
|
|
|
|
((drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX)))
|
2012-01-19 16:04:44 +00:00
|
|
|
{
|
2015-07-27 20:59:10 +10:00
|
|
|
mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
|
2011-03-13 02:44:25 +00:00
|
|
|
|
2012-05-05 14:33:36 +00:00
|
|
|
if (BKE_scene_use_new_shading_nodes(scene)) {
|
2016-05-22 16:23:26 +02:00
|
|
|
if (drawtype == OB_MATERIAL)
|
2011-11-08 13:07:16 +00:00
|
|
|
mask |= CD_MASK_ORCO;
|
|
|
|
}
|
|
|
|
else {
|
2016-05-22 16:23:26 +02:00
|
|
|
if ((scene->gm.matmode == GAME_MAT_GLSL && drawtype == OB_TEXTURE) ||
|
|
|
|
(drawtype == OB_MATERIAL))
|
2014-09-27 00:57:54 +10:00
|
|
|
{
|
2011-11-08 13:07:16 +00:00
|
|
|
mask |= CD_MASK_ORCO;
|
2014-09-27 00:57:54 +10:00
|
|
|
}
|
2011-11-08 13:07:16 +00:00
|
|
|
}
|
2011-03-13 02:44:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
2012-01-09 02:50:09 +00:00
|
|
|
|
2009-01-07 14:46:50 +00:00
|
|
|
/* goes over all modes and view3d settings */
|
2015-03-21 22:34:20 +11:00
|
|
|
CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
|
2009-01-07 14:46:50 +00:00
|
|
|
{
|
2015-03-21 22:34:20 +11:00
|
|
|
const Scene *scene = screen->scene;
|
2009-01-07 14:46:50 +00:00
|
|
|
CustomDataMask mask = CD_MASK_BAREMESH;
|
2015-03-21 22:34:20 +11:00
|
|
|
const ScrArea *sa;
|
2009-01-07 14:46:50 +00:00
|
|
|
|
|
|
|
/* check if we need tfaces & mcols due to view mode */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
|
|
|
if (sa->spacetype == SPACE_VIEW3D) {
|
2015-03-21 22:34:20 +11:00
|
|
|
mask |= ED_view3d_datamask(scene, sa->spacedata.first);
|
2009-01-07 14:46:50 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-09 02:50:09 +00:00
|
|
|
|
2009-01-07 14:46:50 +00:00
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
2015-10-27 11:27:26 -02:00
|
|
|
/**
|
|
|
|
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
|
|
|
|
*/
|
2017-05-10 16:54:01 +02:00
|
|
|
void ED_view3d_update_viewmat(
|
|
|
|
Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2012-03-05 13:02:45 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-10-28 18:03:04 +00:00
|
|
|
|
|
|
|
/* setup window matrices */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (winmat)
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m4(rv3d->winmat, winmat);
|
2009-10-28 18:03:04 +00:00
|
|
|
else
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_winmatrix_set(ar, v3d, rect);
|
2012-03-05 13:02:45 +00:00
|
|
|
|
2009-10-28 18:03:04 +00:00
|
|
|
/* setup view matrix */
|
2018-01-22 20:11:34 +11:00
|
|
|
if (viewmat) {
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m4(rv3d->viewmat, viewmat);
|
2018-01-22 20:11:34 +11:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
float rect_scale[2];
|
|
|
|
if (rect) {
|
|
|
|
rect_scale[0] = (float)BLI_rcti_size_x(rect) / (float)ar->winx;
|
|
|
|
rect_scale[1] = (float)BLI_rcti_size_y(rect) / (float)ar->winy;
|
|
|
|
}
|
|
|
|
view3d_viewmatrix_set(scene, v3d, rv3d, rect ? rect_scale : NULL); /* note: calls BKE_object_where_is_calc for camera... */
|
|
|
|
}
|
2012-03-05 13:02:45 +00:00
|
|
|
|
2016-11-29 13:12:26 +11:00
|
|
|
/* update utility matrices */
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m4_m4(rv3d->persinv, rv3d->persmat);
|
|
|
|
invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
|
2015-02-02 14:25:44 +01:00
|
|
|
|
|
|
|
/* calculate GLSL view dependent values */
|
2010-09-28 04:25:16 +00:00
|
|
|
|
2015-02-02 14:25:44 +01:00
|
|
|
/* store window coordinates scaling/offset */
|
|
|
|
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
|
2016-11-29 13:12:26 +11:00
|
|
|
rctf cameraborder;
|
2015-02-02 14:25:44 +01: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;
|
|
|
|
}
|
2016-11-29 13:12:26 +11: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.
|
|
|
|
*/
|
2008-12-18 17:38:21 +00:00
|
|
|
{
|
2010-09-28 04:25:16 +00:00
|
|
|
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
|
2011-01-21 02:32:58 +00:00
|
|
|
* because of float point precision problems at large values [#23908] */
|
2010-11-03 06:31:53 +00:00
|
|
|
float v1[3], v2[3];
|
2012-10-25 22:47:54 +00:00
|
|
|
float len_px, len_sc;
|
2010-11-03 06:31:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v1[0] = rv3d->persmat[0][0];
|
|
|
|
v1[1] = rv3d->persmat[1][0];
|
|
|
|
v1[2] = rv3d->persmat[2][0];
|
2010-11-03 06:31:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v2[0] = rv3d->persmat[0][1];
|
|
|
|
v2[1] = rv3d->persmat[1][1];
|
|
|
|
v2[2] = rv3d->persmat[2][1];
|
2012-03-05 13:02:45 +00:00
|
|
|
|
2012-10-25 22:47:54 +00:00
|
|
|
len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
|
|
|
|
len_sc = (float)MAX2(ar->winx, ar->winy);
|
2010-09-28 04:25:16 +00:00
|
|
|
|
2012-10-25 22:47:54 +00:00
|
|
|
rv3d->pixsize = len_px / len_sc;
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2012-03-05 13:02:45 +00:00
|
|
|
}
|
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/**
|
2015-11-28 17:14:45 +01:00
|
|
|
* Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects
|
2014-04-12 15:34:59 +10:00
|
|
|
*
|
|
|
|
* \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set.
|
|
|
|
* \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here.
|
|
|
|
*/
|
|
|
|
static void view3d_draw_objects(
|
|
|
|
const bContext *C,
|
|
|
|
Scene *scene, View3D *v3d, ARegion *ar,
|
|
|
|
const char **grid_unit,
|
2015-02-17 18:35:56 +01:00
|
|
|
const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
|
2014-04-12 15:34:59 +10:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
Base *base;
|
|
|
|
const bool do_camera_frame = !draw_offscreen;
|
2015-02-13 11:52:27 +01:00
|
|
|
const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
|
2015-02-17 11:37:20 +01:00
|
|
|
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
|
|
|
|
/* only draw grids after in solid modes, else it hovers over mesh wires */
|
2015-04-28 15:41:44 +02:00
|
|
|
const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
|
2015-02-17 18:08:28 +01:00
|
|
|
bool do_composite_xray = false;
|
2015-02-13 14:38:26 +01:00
|
|
|
bool xrayclear = true;
|
2014-04-12 15:34:59 +10:00
|
|
|
|
|
|
|
if (!draw_offscreen) {
|
|
|
|
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv3d->rflag & RV3D_CLIPPING)
|
|
|
|
view3d_draw_clipping(rv3d);
|
|
|
|
|
|
|
|
/* set zbuffer after we draw clipping region */
|
|
|
|
if (v3d->drawtype > OB_WIRE) {
|
|
|
|
v3d->zbuf = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
v3d->zbuf = false;
|
|
|
|
}
|
|
|
|
|
2014-06-19 04:01:19 +10:00
|
|
|
/* 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) {
|
|
|
|
v3d->zbuf = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v3d->zbuf) {
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
2015-02-13 11:52:27 +01:00
|
|
|
/* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
|
|
|
|
* objects if done last */
|
|
|
|
if (draw_grids) {
|
2014-04-12 15:34:59 +10:00
|
|
|
/* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
|
2014-12-19 10:07:02 +01:00
|
|
|
rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
|
2014-04-12 15:34:59 +10:00
|
|
|
|
2015-02-13 11:52:27 +01: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);
|
|
|
|
/* XXX make function? replaces persp(1) */
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadMatrixf(rv3d->winmat);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadMatrixf(rv3d->viewmat);
|
2014-04-12 15:34:59 +10:00
|
|
|
}
|
2015-04-30 08:07:15 +10:00
|
|
|
else if (!draw_grids_after) {
|
2015-04-28 15:41:44 +02:00
|
|
|
drawfloor(scene, v3d, grid_unit, true);
|
2015-02-17 11:37:20 +01:00
|
|
|
}
|
2014-04-12 15:34:59 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/* important to do before clipping */
|
|
|
|
if (do_bgpic) {
|
|
|
|
view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
|
|
|
ED_view3d_clipping_set(rv3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw set first */
|
|
|
|
if (scene->set) {
|
2014-06-04 14:22:29 +10:00
|
|
|
const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET;
|
2014-04-12 15:34:59 +10:00
|
|
|
Scene *sce_iter;
|
|
|
|
for (SETLOOPER(scene->set, sce_iter, base)) {
|
|
|
|
if (v3d->lay & base->lay) {
|
|
|
|
UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_object(scene, ar, v3d, base, dflag);
|
2014-04-12 15:34:59 +10:00
|
|
|
|
|
|
|
if (base->object->transflag & OB_DUPLI) {
|
2014-06-04 14:22:29 +10:00
|
|
|
draw_dupli_objects_color(scene, ar, v3d, base, dflag, TH_UNDEFINED);
|
2014-04-12 15:34:59 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transp and X-ray afterdraw stuff for sets is done later */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (draw_offscreen) {
|
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
|
|
|
if (v3d->lay & base->lay) {
|
|
|
|
/* dupli drawing */
|
|
|
|
if (base->object->transflag & OB_DUPLI)
|
|
|
|
draw_dupli_objects(scene, ar, v3d, base);
|
|
|
|
|
|
|
|
draw_object(scene, ar, v3d, base, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unsigned int lay_used = 0;
|
|
|
|
|
|
|
|
/* then draw not selected and the duplis, but skip editmode object */
|
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
2014-04-17 20:38:21 +10:00
|
|
|
lay_used |= base->lay;
|
2014-04-12 15:34:59 +10:00
|
|
|
|
|
|
|
if (v3d->lay & base->lay) {
|
|
|
|
|
|
|
|
/* dupli drawing */
|
|
|
|
if (base->object->transflag & OB_DUPLI) {
|
|
|
|
draw_dupli_objects(scene, ar, v3d, base);
|
|
|
|
}
|
|
|
|
if ((base->flag & SELECT) == 0) {
|
|
|
|
if (base->object != scene->obedit)
|
|
|
|
draw_object(scene, ar, v3d, base, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-17 20:38:21 +10:00
|
|
|
/* mask out localview */
|
|
|
|
v3d->lay_used = lay_used & ((1 << 20) - 1);
|
2014-04-12 15:34:59 +10:00
|
|
|
|
|
|
|
/* draw selected and editmode */
|
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
|
|
|
if (v3d->lay & base->lay) {
|
|
|
|
if (base->object == scene->obedit || (base->flag & SELECT)) {
|
|
|
|
draw_object(scene, ar, v3d, base, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-17 11:37:20 +01:00
|
|
|
/* perspective floor goes last to use scene depth and avoid writing to depth buffer */
|
|
|
|
if (draw_grids_after) {
|
2015-04-28 15:41:44 +02:00
|
|
|
drawfloor(scene, v3d, grid_unit, false);
|
2015-02-17 11:37:20 +01:00
|
|
|
}
|
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* must be before xray draw which clears the depth buffer */
|
|
|
|
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
|
2015-12-13 21:03:13 +13:00
|
|
|
wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL;
|
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* must be before xray draw which clears the depth buffer */
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
2015-12-13 21:03:13 +13:00
|
|
|
ED_gpencil_draw_view3d(wm, scene, v3d, ar, true);
|
2014-04-12 15:34:59 +10:00
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
/* transp and X-ray afterdraw stuff */
|
|
|
|
if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
|
2015-02-17 18:08:28 +01:00
|
|
|
|
|
|
|
/* always do that here to cleanup depth buffers if none needed */
|
2015-02-17 18:35:56 +01:00
|
|
|
if (fx) {
|
2015-02-17 18:08:28 +01:00
|
|
|
do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
|
2015-02-17 18:35:56 +01:00
|
|
|
GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
|
2015-02-17 18:08:28 +01:00
|
|
|
}
|
|
|
|
|
2015-02-13 14:38:26 +01:00
|
|
|
if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
|
|
|
|
if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
|
|
|
|
|
2015-02-17 18:35:56 +01:00
|
|
|
if (fx && do_composite_xray) {
|
|
|
|
GPU_fx_compositor_XRay_resolve(fx);
|
2015-02-17 18:08:28 +01:00
|
|
|
}
|
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
if (!draw_offscreen) {
|
|
|
|
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv3d->rflag & RV3D_CLIPPING)
|
|
|
|
ED_view3d_clipping_disable();
|
|
|
|
|
|
|
|
/* important to do after clipping */
|
|
|
|
if (do_bgpic) {
|
|
|
|
view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!draw_offscreen) {
|
|
|
|
BIF_draw_manipulator(C);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
if (v3d->zbuf) {
|
|
|
|
v3d->zbuf = false;
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
}
|
2014-05-22 11:58:07 +10:00
|
|
|
|
|
|
|
if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
|
|
|
|
GPU_free_images_old();
|
|
|
|
}
|
2014-04-12 15:34:59 +10:00
|
|
|
}
|
|
|
|
|
2017-05-10 16:54:01 +02:00
|
|
|
static void view3d_main_region_setup_view(
|
|
|
|
Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
|
2012-03-05 13:02:45 +00:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
2017-05-10 16:54:01 +02:00
|
|
|
ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect);
|
2010-09-19 06:41:44 +00:00
|
|
|
|
2009-10-28 18:03:04 +00:00
|
|
|
/* set for opengl */
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
2010-02-01 15:32:55 +00:00
|
|
|
glLoadMatrixf(rv3d->winmat);
|
2009-10-28 18:03:04 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
2010-02-01 15:32:55 +00:00
|
|
|
glLoadMatrixf(rv3d->viewmat);
|
2009-10-28 18:03:04 +00:00
|
|
|
}
|
|
|
|
|
2015-10-27 11:27:26 -02:00
|
|
|
/**
|
|
|
|
* Store values from #RegionView3D, set when drawing.
|
|
|
|
* This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example).
|
|
|
|
*
|
|
|
|
* Values set by #ED_view3d_update_viewmat should be handled here.
|
|
|
|
*/
|
|
|
|
struct RV3DMatrixStore {
|
|
|
|
float winmat[4][4];
|
|
|
|
float viewmat[4][4];
|
|
|
|
float viewinv[4][4];
|
|
|
|
float persmat[4][4];
|
|
|
|
float persinv[4][4];
|
|
|
|
float viewcamtexcofac[4];
|
|
|
|
float pixsize;
|
|
|
|
};
|
|
|
|
|
2017-03-04 13:32:40 +11:00
|
|
|
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
|
2015-10-27 11:27:26 -02:00
|
|
|
{
|
|
|
|
struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
|
|
|
|
copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
|
|
|
|
copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
|
|
|
|
copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
|
|
|
|
copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
|
|
|
|
copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
|
|
|
|
copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
|
|
|
|
rv3dmat->pixsize = rv3d->pixsize;
|
|
|
|
return (void *)rv3dmat;
|
|
|
|
}
|
|
|
|
|
2017-03-04 13:32:40 +11:00
|
|
|
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat)
|
2015-10-27 11:27:26 -02:00
|
|
|
{
|
|
|
|
copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
|
|
|
|
copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
|
|
|
|
copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
|
|
|
|
copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
|
|
|
|
copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
|
|
|
|
copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac);
|
|
|
|
rv3d->pixsize = rv3dmat->pixsize;
|
|
|
|
}
|
|
|
|
|
2012-10-23 12:25:08 +00:00
|
|
|
void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
|
|
|
|
{
|
|
|
|
/* shadow buffers, before we setup matrices */
|
|
|
|
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
|
2015-03-23 22:32:49 +01:00
|
|
|
gpu_update_lamps_shadows_world(scene, v3d);
|
2012-10-23 12:25:08 +00:00
|
|
|
}
|
|
|
|
|
2014-11-24 23:03:48 +01:00
|
|
|
/*
|
|
|
|
* Function to clear the view
|
|
|
|
*/
|
2015-11-28 17:14:45 +01:00
|
|
|
static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
|
2014-11-24 23:03:48 +01:00
|
|
|
{
|
2015-03-10 16:34:40 +01:00
|
|
|
if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
|
2016-10-10 01:28:02 -04:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
|
2015-02-02 14:25:44 +01:00
|
|
|
|
2016-10-10 01:28:02 -04:00
|
|
|
/* calculate full shader for background */
|
|
|
|
GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
|
|
|
|
|
|
|
|
bool material_not_bound = !GPU_material_bound(gpumat);
|
2014-11-24 23:03:48 +01:00
|
|
|
|
2016-10-10 01:28:02 -04:00
|
|
|
if (material_not_bound) {
|
2014-11-24 23:03:48 +01:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
2016-10-10 01:28:02 -04:00
|
|
|
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
}
|
2014-11-24 23:03:48 +01:00
|
|
|
|
2016-10-10 01:28:02 -04:00
|
|
|
/* Draw world */
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
|
|
glVertex3f(-1.0, -1.0, 1.0);
|
|
|
|
glVertex3f(1.0, -1.0, 1.0);
|
|
|
|
glVertex3f(-1.0, 1.0, 1.0);
|
|
|
|
glVertex3f(1.0, 1.0, 1.0);
|
|
|
|
glEnd();
|
2014-11-24 23:03:48 +01:00
|
|
|
|
2016-10-10 01:28:02 -04:00
|
|
|
if (material_not_bound) {
|
2014-11-24 23:03:48 +01:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
|
2016-10-10 01:28:02 -04:00
|
|
|
GPU_material_unbind(gpumat);
|
|
|
|
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
2014-11-24 23:03:48 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
UI_ThemeColor(TH_LOW_GRAD);
|
|
|
|
glVertex3f(-1.0, -1.0, 1.0);
|
|
|
|
glVertex3f(1.0, -1.0, 1.0);
|
|
|
|
UI_ThemeColor(TH_HIGH_GRAD);
|
|
|
|
glVertex3f(1.0, 1.0, 1.0);
|
|
|
|
glVertex3f(-1.0, 1.0, 1.0);
|
|
|
|
glEnd();
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
else {
|
2015-03-10 16:34:40 +01:00
|
|
|
UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
|
2014-11-24 23:03:48 +01:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-23 12:25:08 +00:00
|
|
|
/* ED_view3d_draw_offscreen_init should be called before this to initialize
|
|
|
|
* stuff like shadow buffers
|
|
|
|
*/
|
2015-02-12 18:54:41 +01:00
|
|
|
void ED_view3d_draw_offscreen(
|
|
|
|
Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
|
|
|
|
float viewmat[4][4], float winmat[4][4],
|
2015-10-14 12:39:52 +11:00
|
|
|
bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
|
2015-04-06 10:40:12 -03:00
|
|
|
GPUFX *fx, GPUFXSettings *fx_settings,
|
2015-10-14 12:39:52 +11:00
|
|
|
GPUOffScreen *ofs)
|
2009-10-28 18:03:04 +00:00
|
|
|
{
|
2015-01-04 23:20:56 +11:00
|
|
|
struct bThemeState theme_state;
|
2009-10-28 18:03:04 +00:00
|
|
|
int bwinx, bwiny;
|
2010-08-25 08:31:52 +00:00
|
|
|
rcti brect;
|
2015-02-12 18:54:41 +01:00
|
|
|
bool do_compositing = false;
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-10-28 18:03:04 +00:00
|
|
|
|
2009-12-08 19:27:30 +00:00
|
|
|
glPushMatrix();
|
2009-10-28 18:03:04 +00:00
|
|
|
|
|
|
|
/* set temporary new size */
|
2012-03-25 23:54:33 +00:00
|
|
|
bwinx = ar->winx;
|
|
|
|
bwiny = ar->winy;
|
|
|
|
brect = ar->winrct;
|
2014-04-12 15:34:59 +10:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ar->winx = winx;
|
|
|
|
ar->winy = winy;
|
2012-03-24 02:51:46 +00:00
|
|
|
ar->winrct.xmin = 0;
|
|
|
|
ar->winrct.ymin = 0;
|
|
|
|
ar->winrct.xmax = winx;
|
|
|
|
ar->winrct.ymax = winy;
|
2012-05-18 14:05:59 +00:00
|
|
|
|
2015-01-04 23:20:56 +11:00
|
|
|
UI_Theme_Store(&theme_state);
|
2012-05-18 14:05:59 +00:00
|
|
|
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
2014-04-12 15:34:59 +10:00
|
|
|
|
2009-10-28 18:03:04 +00:00
|
|
|
/* set flags */
|
|
|
|
G.f |= G_RENDER_OGL;
|
2010-05-20 16:08:06 +00:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
|
|
|
|
/* free images which can have changed on frame-change
|
|
|
|
* warning! can be slow so only free animated images - campbell */
|
|
|
|
GPU_free_images_anim();
|
|
|
|
}
|
2015-02-12 18:54:41 +01:00
|
|
|
|
|
|
|
/* setup view matrices before fx or unbinding the offscreen buffers will cause issues */
|
2015-04-30 15:06:10 +02:00
|
|
|
if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
|
2015-04-06 10:40:12 -03:00
|
|
|
view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
|
|
|
|
else
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
|
2015-02-12 18:54:41 +01:00
|
|
|
|
|
|
|
/* framebuffer fx needed, we need to draw offscreen first */
|
|
|
|
if (v3d->fx_settings.fx_flag && fx) {
|
2015-03-23 18:54:56 +01:00
|
|
|
GPUSSAOSettings *ssao = NULL;
|
|
|
|
|
|
|
|
if (v3d->drawtype < OB_SOLID) {
|
|
|
|
ssao = v3d->fx_settings.ssao;
|
|
|
|
v3d->fx_settings.ssao = NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
|
2015-03-23 18:54:56 +01:00
|
|
|
|
|
|
|
if (ssao)
|
|
|
|
v3d->fx_settings.ssao = ssao;
|
2015-02-12 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
2013-04-11 15:15:06 +00:00
|
|
|
/* clear opengl buffers */
|
|
|
|
if (do_sky) {
|
2015-11-28 17:14:45 +01:00
|
|
|
view3d_main_region_clear(scene, v3d, ar);
|
2013-04-11 15:15:06 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
2015-02-17 18:08:28 +01:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2013-04-11 15:15:06 +00:00
|
|
|
}
|
2012-03-07 17:45:40 +00:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* main drawing call */
|
2015-02-17 23:38:28 +01:00
|
|
|
view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
|
2009-10-28 18:03:04 +00:00
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
/* post process */
|
|
|
|
if (do_compositing) {
|
|
|
|
if (!winmat)
|
|
|
|
is_persp = rv3d->is_persp;
|
|
|
|
GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
|
|
|
|
}
|
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
|
|
|
|
/* draw grease-pencil stuff */
|
|
|
|
ED_region_pixelspace(ar);
|
2012-06-06 11:40:01 +00:00
|
|
|
|
2011-08-28 21:13:03 +00:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
|
|
|
|
/* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
|
2015-12-13 21:03:13 +13:00
|
|
|
ED_gpencil_draw_view3d(NULL, scene, v3d, ar, false);
|
2009-10-28 18:03:04 +00:00
|
|
|
}
|
2012-12-17 02:34:53 +00:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* freeing the images again here could be done after the operator runs, leaving for now */
|
|
|
|
GPU_free_images_anim();
|
2012-12-17 02:34:53 +00:00
|
|
|
}
|
2009-11-09 08:03:43 +00:00
|
|
|
|
2009-10-28 18:03:04 +00:00
|
|
|
/* restore size */
|
2012-03-25 23:54:33 +00:00
|
|
|
ar->winx = bwinx;
|
|
|
|
ar->winy = bwiny;
|
2010-08-25 08:31:52 +00:00
|
|
|
ar->winrct = brect;
|
2009-10-28 18:03:04 +00:00
|
|
|
|
2009-12-08 19:27:30 +00:00
|
|
|
glPopMatrix();
|
2010-03-08 21:33:51 +00:00
|
|
|
|
2015-01-04 23:20:56 +11:00
|
|
|
UI_Theme_Restore(&theme_state);
|
2010-06-04 12:23:38 +00:00
|
|
|
|
|
|
|
G.f &= ~G_RENDER_OGL;
|
2009-10-28 18:03:04 +00:00
|
|
|
}
|
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
/**
|
|
|
|
* Set the correct matrices
|
|
|
|
*/
|
2017-05-10 16:54:01 +02:00
|
|
|
void ED_view3d_draw_setup_view(
|
|
|
|
wmWindow *win, Scene *scene, ARegion *ar, View3D *v3d, float viewmat[4][4], float winmat[4][4], const rcti *rect)
|
2017-05-09 19:21:22 +02:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
/* Setup the view matrix. */
|
|
|
|
if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_stereo3d_setup(scene, v3d, ar, rect);
|
2017-05-09 19:21:22 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect);
|
2017-05-09 19:21:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-14 12:39:52 +11:00
|
|
|
/**
|
|
|
|
* Utility func for ED_view3d_draw_offscreen
|
|
|
|
*
|
|
|
|
* \param ofs: Optional off-screen buffer, can be NULL.
|
|
|
|
* (avoids re-creating when doing multiple GL renders).
|
|
|
|
*/
|
|
|
|
ImBuf *ED_view3d_draw_offscreen_imbuf(
|
|
|
|
Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey,
|
2017-11-24 11:43:16 +01:00
|
|
|
unsigned int flag, unsigned int draw_flags,
|
|
|
|
int alpha_mode, int samples, const char *viewname,
|
2015-10-14 12:39:52 +11:00
|
|
|
/* output vars */
|
2015-11-11 21:56:25 +11:00
|
|
|
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
|
2010-03-08 20:08:04 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2010-03-08 20:08:04 +00:00
|
|
|
ImBuf *ibuf;
|
2016-03-10 22:47:18 +11:00
|
|
|
const bool draw_sky = (alpha_mode == R_ADDSKY);
|
2017-11-24 11:43:16 +01:00
|
|
|
const bool draw_background = (draw_flags & V3D_OFSDRAW_USE_BACKGROUND);
|
|
|
|
const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE);
|
2015-02-12 18:54:41 +01:00
|
|
|
|
2015-11-11 21:56:25 +11:00
|
|
|
/* view state */
|
2015-11-16 22:20:14 +11:00
|
|
|
GPUFXSettings fx_settings = v3d->fx_settings;
|
2015-11-12 00:06:26 +11:00
|
|
|
bool is_ortho = false;
|
2015-11-11 21:56:25 +11:00
|
|
|
float winmat[4][4];
|
|
|
|
|
2016-03-21 16:36:20 +11:00
|
|
|
if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
|
|
|
|
/* sizes differ, can't reuse */
|
|
|
|
ofs = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool own_ofs = (ofs == NULL);
|
|
|
|
|
2015-10-14 12:39:52 +11:00
|
|
|
if (own_ofs) {
|
|
|
|
/* bind */
|
2017-11-24 11:43:16 +01:00
|
|
|
ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, err_out);
|
2015-10-14 12:39:52 +11:00
|
|
|
if (ofs == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-04-18 16:28:39 +00:00
|
|
|
}
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2012-10-23 12:25:08 +00:00
|
|
|
ED_view3d_draw_offscreen_init(scene, v3d);
|
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_bind(ofs, true);
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2015-11-12 00:06:26 +11:00
|
|
|
/* read in pixels & stamp */
|
|
|
|
ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
|
|
|
|
|
2010-03-08 20:08:04 +00:00
|
|
|
/* render 3d view */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
|
2011-11-18 15:52:00 +00:00
|
|
|
CameraParams params;
|
2015-04-06 10:40:12 -03:00
|
|
|
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_init(¶ms);
|
2014-03-01 21:41:07 +11:00
|
|
|
/* fallback for non camera objects */
|
|
|
|
params.clipsta = v3d->near;
|
|
|
|
params.clipend = v3d->far;
|
2015-04-06 10:40:12 -03:00
|
|
|
BKE_camera_params_from_object(¶ms, camera);
|
|
|
|
BKE_camera_multiview_params(&scene->r, ¶ms, camera, viewname);
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp);
|
|
|
|
BKE_camera_params_compute_matrix(¶ms);
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
BKE_camera_to_gpu_dof(camera, &fx_settings);
|
|
|
|
|
2015-11-11 21:56:25 +11:00
|
|
|
is_ortho = params.is_ortho;
|
|
|
|
copy_m4_m4(winmat, params.winmat);
|
2010-03-08 20:08:04 +00:00
|
|
|
}
|
|
|
|
else {
|
2015-11-11 21:56:25 +11:00
|
|
|
rctf viewplane;
|
|
|
|
float clipsta, clipend;
|
|
|
|
|
|
|
|
is_ortho = ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend, NULL);
|
|
|
|
if (is_ortho) {
|
|
|
|
orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
|
|
|
|
}
|
2010-03-08 20:08:04 +00:00
|
|
|
}
|
|
|
|
|
2017-11-24 11:43:16 +01:00
|
|
|
if ((samples && use_full_sample) == 0) {
|
2015-11-12 00:06:26 +11:00
|
|
|
/* Single-pass render, common case */
|
|
|
|
ED_view3d_draw_offscreen(
|
|
|
|
scene, v3d, ar, sizex, sizey, NULL, winmat,
|
|
|
|
draw_background, draw_sky, !is_ortho, viewname,
|
|
|
|
fx, &fx_settings, ofs);
|
2015-11-11 21:56:25 +11:00
|
|
|
|
2015-11-12 00:06:26 +11:00
|
|
|
if (ibuf->rect_float) {
|
|
|
|
GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
|
|
|
|
}
|
|
|
|
else if (ibuf->rect) {
|
|
|
|
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling.
|
2015-11-16 21:06:40 +11:00
|
|
|
* Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */
|
2015-11-12 00:06:26 +11:00
|
|
|
static float jit_ofs[32][2];
|
|
|
|
float winmat_jitter[4][4];
|
|
|
|
/* use imbuf as temp storage, before writing into it from accumulation buffer */
|
|
|
|
unsigned char *rect_temp = ibuf->rect ? (void *)ibuf->rect : (void *)ibuf->rect_float;
|
|
|
|
unsigned int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int[4]), "accum1");
|
|
|
|
unsigned int i;
|
|
|
|
int j;
|
|
|
|
|
2016-02-16 23:11:29 +11:00
|
|
|
BLI_jitter_init(jit_ofs, samples);
|
2015-11-12 00:06:26 +11:00
|
|
|
|
|
|
|
/* first sample buffer, also initializes 'rv3d->persmat' */
|
|
|
|
ED_view3d_draw_offscreen(
|
|
|
|
scene, v3d, ar, sizex, sizey, NULL, winmat,
|
|
|
|
draw_background, draw_sky, !is_ortho, viewname,
|
|
|
|
fx, &fx_settings, ofs);
|
|
|
|
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp);
|
|
|
|
|
|
|
|
i = sizex * sizey * 4;
|
|
|
|
while (i--) {
|
|
|
|
accum_buffer[i] = rect_temp[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip the first sample */
|
|
|
|
for (j = 1; j < samples; j++) {
|
|
|
|
copy_m4_m4(winmat_jitter, winmat);
|
|
|
|
window_translate_m4(
|
|
|
|
winmat_jitter, rv3d->persmat,
|
|
|
|
(jit_ofs[j][0] * 2.0f) / sizex,
|
|
|
|
(jit_ofs[j][1] * 2.0f) / sizey);
|
|
|
|
|
|
|
|
ED_view3d_draw_offscreen(
|
|
|
|
scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
|
|
|
|
draw_background, draw_sky, !is_ortho, viewname,
|
|
|
|
fx, &fx_settings, ofs);
|
|
|
|
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp);
|
|
|
|
|
|
|
|
i = sizex * sizey * 4;
|
|
|
|
while (i--) {
|
|
|
|
accum_buffer[i] += rect_temp[i];
|
|
|
|
}
|
|
|
|
}
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2015-11-12 00:06:26 +11:00
|
|
|
if (ibuf->rect_float) {
|
|
|
|
float *rect_float = ibuf->rect_float;
|
|
|
|
i = sizex * sizey * 4;
|
|
|
|
while (i--) {
|
|
|
|
rect_float[i] = (float)(accum_buffer[i] / samples) * (1.0f / 255.0f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unsigned char *rect_ub = (unsigned char *)ibuf->rect;
|
|
|
|
i = sizex * sizey * 4;
|
|
|
|
while (i--) {
|
|
|
|
rect_ub[i] = accum_buffer[i] / samples;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(accum_buffer);
|
|
|
|
}
|
2010-03-08 20:08:04 +00:00
|
|
|
|
|
|
|
/* unbind */
|
2015-02-12 18:54:41 +01:00
|
|
|
GPU_offscreen_unbind(ofs, true);
|
2010-03-08 20:08:04 +00:00
|
|
|
|
2015-10-14 12:39:52 +11:00
|
|
|
if (own_ofs) {
|
|
|
|
GPU_offscreen_free(ofs);
|
|
|
|
}
|
2015-11-11 21:56:25 +11:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ibuf->rect_float && ibuf->rect)
|
2010-08-26 23:30:15 +00:00
|
|
|
IMB_rect_from_float(ibuf);
|
2015-01-04 23:20:56 +11:00
|
|
|
|
2010-03-08 20:08:04 +00:00
|
|
|
return ibuf;
|
|
|
|
}
|
|
|
|
|
2015-10-14 12:39:52 +11:00
|
|
|
/**
|
|
|
|
* Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf)
|
|
|
|
*
|
|
|
|
* \param ofs: Optional off-screen buffer can be NULL.
|
|
|
|
* (avoids re-creating when doing multiple GL renders).
|
|
|
|
*
|
|
|
|
* \note used by the sequencer
|
|
|
|
*/
|
|
|
|
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
|
|
|
|
Scene *scene, Object *camera, int width, int height,
|
2017-11-24 11:43:16 +01:00
|
|
|
unsigned int flag, unsigned int draw_flags, int drawtype,
|
|
|
|
int alpha_mode, int samples, const char *viewname,
|
2015-11-11 21:56:25 +11:00
|
|
|
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
|
2010-03-08 21:33:51 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
View3D v3d = {NULL};
|
|
|
|
ARegion ar = {NULL};
|
|
|
|
RegionView3D rv3d = {{{0}}};
|
2010-03-08 21:33:51 +00:00
|
|
|
|
|
|
|
/* connect data */
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d.regionbase.first = v3d.regionbase.last = &ar;
|
|
|
|
ar.regiondata = &rv3d;
|
|
|
|
ar.regiontype = RGN_TYPE_WINDOW;
|
2010-03-08 21:33:51 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d.camera = camera;
|
|
|
|
v3d.lay = scene->lay;
|
2010-03-16 17:37:34 +00:00
|
|
|
v3d.drawtype = drawtype;
|
2010-03-16 17:49:31 +00:00
|
|
|
v3d.flag2 = V3D_RENDER_OVERRIDE;
|
2010-03-08 21:33:51 +00:00
|
|
|
|
2017-11-24 12:19:26 +01:00
|
|
|
if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) {
|
|
|
|
v3d.flag2 |= V3D_SHOW_GPENCIL;
|
|
|
|
}
|
|
|
|
if (draw_flags & V3D_OFSDRAW_USE_SOLID_TEX) {
|
2012-12-12 12:42:12 +00:00
|
|
|
v3d.flag2 |= V3D_SOLID_TEX;
|
2017-11-24 12:19:26 +01:00
|
|
|
}
|
|
|
|
if (draw_flags & V3D_OFSDRAW_USE_BACKGROUND) {
|
2015-12-13 21:03:13 +13:00
|
|
|
v3d.flag3 |= V3D_SHOW_WORLD;
|
2017-11-24 12:19:26 +01:00
|
|
|
}
|
|
|
|
if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) {
|
|
|
|
if (camera->type == OB_CAMERA) {
|
|
|
|
v3d.fx_settings.dof = &((Camera *)camera->data)->gpu_dof;
|
|
|
|
v3d.fx_settings.fx_flag |= GPU_FX_FLAG_DOF;
|
|
|
|
}
|
|
|
|
}
|
2012-12-12 12:42:12 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d.persp = RV3D_CAMOB;
|
2010-03-08 21:33:51 +00:00
|
|
|
|
|
|
|
copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
|
|
|
|
normalize_m4(rv3d.viewinv);
|
|
|
|
invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
|
|
|
|
|
|
|
|
{
|
2011-11-18 15:52:00 +00:00
|
|
|
CameraParams params;
|
2015-11-23 15:44:15 +11:00
|
|
|
Object *view_camera = BKE_camera_multiview_render(scene, v3d.camera, viewname);
|
2011-11-18 15:52:00 +00:00
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_init(¶ms);
|
2015-11-23 15:44:15 +11:00
|
|
|
BKE_camera_params_from_object(¶ms, view_camera);
|
|
|
|
BKE_camera_multiview_params(&scene->r, ¶ms, view_camera, viewname);
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_compute_viewplane(¶ms, width, height, scene->r.xasp, scene->r.yasp);
|
|
|
|
BKE_camera_params_compute_matrix(¶ms);
|
2011-11-18 15:52:00 +00:00
|
|
|
|
|
|
|
copy_m4_m4(rv3d.winmat, params.winmat);
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d.near = params.clipsta;
|
|
|
|
v3d.far = params.clipend;
|
|
|
|
v3d.lens = params.lens;
|
2010-03-08 21:33:51 +00:00
|
|
|
}
|
|
|
|
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
|
2010-03-08 21:33:51 +00:00
|
|
|
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
|
|
|
|
|
2015-10-14 12:39:52 +11:00
|
|
|
return ED_view3d_draw_offscreen_imbuf(
|
2017-11-24 11:43:16 +01:00
|
|
|
scene, &v3d, &ar, width, height, flag, draw_flags,
|
|
|
|
alpha_mode, samples, viewname, fx, ofs, err_out);
|
2010-03-08 21:33:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-19 16:39:18 +10:00
|
|
|
/**
|
|
|
|
* \note The info that this uses is updated in #ED_refresh_viewport_fps,
|
|
|
|
* which currently gets called during #SCREEN_OT_animation_step.
|
2010-02-12 00:44:26 +00:00
|
|
|
*/
|
2014-06-19 16:39:18 +10:00
|
|
|
void ED_scene_draw_fps(Scene *scene, const rcti *rect)
|
2010-02-12 00:44:26 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ScreenFrameRateInfo *fpsi = scene->fps_info;
|
2010-02-12 00:44:26 +00:00
|
|
|
float fps;
|
|
|
|
char printable[16];
|
|
|
|
int i, tot;
|
|
|
|
|
|
|
|
if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime)
|
|
|
|
return;
|
|
|
|
|
|
|
|
printable[0] = '\0';
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* this is too simple, better do an average */
|
2012-03-25 23:54:33 +00:00
|
|
|
fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
|
2010-02-12 00:44:26 +00:00
|
|
|
#else
|
2012-03-25 23:54:33 +00:00
|
|
|
fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
|
2010-02-12 00:44:26 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0, tot = 0, fps = 0.0f; i < REDRAW_FRAME_AVERAGE; i++) {
|
2010-02-12 00:44:26 +00:00
|
|
|
if (fpsi->redrawtimes_fps[i]) {
|
|
|
|
fps += fpsi->redrawtimes_fps[i];
|
|
|
|
tot++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tot) {
|
|
|
|
fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
|
|
|
|
|
|
|
|
//fpsi->redrawtime_index++;
|
|
|
|
//if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE)
|
|
|
|
// fpsi->redrawtime = 0;
|
|
|
|
|
|
|
|
fps = fps / tot;
|
|
|
|
}
|
|
|
|
#endif
|
2010-04-15 16:44:38 +00:00
|
|
|
|
2013-04-07 15:09:06 +00:00
|
|
|
/* is this more than half a frame behind? */
|
2012-05-20 19:49:27 +00:00
|
|
|
if (fps + 0.5f < (float)(FPS)) {
|
2010-02-12 00:44:26 +00:00
|
|
|
UI_ThemeColor(TH_REDALERT);
|
2013-02-19 15:45:56 +00:00
|
|
|
BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2010-02-12 00:44:26 +00:00
|
|
|
else {
|
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
2013-02-19 15:45:56 +00:00
|
|
|
BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
|
2010-02-12 00:44:26 +00:00
|
|
|
}
|
2013-02-20 08:39:31 +00:00
|
|
|
|
|
|
|
#ifdef WITH_INTERNATIONAL
|
|
|
|
BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
|
|
|
|
#else
|
2012-12-18 13:59:47 +00:00
|
|
|
BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
|
2013-02-20 08:39:31 +00:00
|
|
|
#endif
|
2010-02-12 00:44:26 +00:00
|
|
|
}
|
|
|
|
|
2018-01-23 12:13:48 +11:00
|
|
|
static bool view3d_main_region_do_render_draw(const Scene *scene)
|
2012-06-25 12:13:21 +00:00
|
|
|
{
|
|
|
|
RenderEngineType *type = RE_engines_find(scene->r.engine);
|
|
|
|
|
|
|
|
return (type && type->view_update && type->view_draw);
|
|
|
|
}
|
|
|
|
|
2018-01-23 12:13:48 +11:00
|
|
|
bool ED_view3d_calc_render_border(
|
|
|
|
const Scene *scene, const View3D *v3d, const ARegion *ar,
|
|
|
|
rcti *rect)
|
2013-04-14 21:42:58 +00:00
|
|
|
{
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
rctf viewborder;
|
|
|
|
bool use_border;
|
|
|
|
|
|
|
|
/* test if there is a 3d view rendering */
|
2015-11-28 17:14:45 +01:00
|
|
|
if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
|
2013-04-14 21:42:58 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/* test if there is a border render */
|
|
|
|
if (rv3d->persp == RV3D_CAMOB)
|
|
|
|
use_border = (scene->r.mode & R_BORDER) != 0;
|
|
|
|
else
|
|
|
|
use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
|
|
|
|
|
|
|
|
if (!use_border)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* compute border */
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
|
|
|
|
|
|
|
|
rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
|
|
|
|
rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
|
|
|
|
rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
|
|
|
|
rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rect->xmin = v3d->render_border.xmin * ar->winx;
|
|
|
|
rect->xmax = v3d->render_border.xmax * ar->winx;
|
|
|
|
rect->ymin = v3d->render_border.ymin * ar->winy;
|
|
|
|
rect->ymax = v3d->render_border.ymax * ar->winy;
|
|
|
|
}
|
|
|
|
|
2013-08-05 04:19:34 +00:00
|
|
|
BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
|
|
|
|
BLI_rcti_isect(&ar->winrct, rect, rect);
|
2013-04-14 21:42:58 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
|
2014-04-12 15:34:59 +10:00
|
|
|
ARegion *ar, View3D *v3d,
|
|
|
|
bool clip_border, const rcti *border_rect)
|
2011-11-02 18:20:53 +00:00
|
|
|
{
|
2014-04-12 15:34:59 +10:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2011-11-02 18:20:53 +00:00
|
|
|
RenderEngineType *type;
|
2012-06-06 23:27:43 +00:00
|
|
|
GLint scissor[4];
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2012-03-28 09:07:10 +00:00
|
|
|
/* create render engine */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!rv3d->render_engine) {
|
2012-09-04 13:29:07 +00:00
|
|
|
RenderEngine *engine;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
type = RE_engines_find(scene->r.engine);
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!(type->view_update && type->view_draw))
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
engine = RE_engine_create_ex(type, true);
|
2012-09-04 13:29:07 +00:00
|
|
|
|
2012-11-05 08:05:14 +00:00
|
|
|
engine->tile_x = scene->r.tilex;
|
|
|
|
engine->tile_y = scene->r.tiley;
|
2012-10-08 11:48:51 +00:00
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
type->view_update(engine, C);
|
|
|
|
|
|
|
|
rv3d->render_engine = engine;
|
2011-11-02 18:20:53 +00:00
|
|
|
}
|
|
|
|
|
2012-03-28 09:07:10 +00:00
|
|
|
/* setup view matrices */
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL, NULL);
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2012-03-28 09:07:10 +00:00
|
|
|
/* background draw */
|
2012-06-06 23:27:43 +00:00
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
|
2013-04-14 21:42:58 +00:00
|
|
|
if (clip_border) {
|
2012-06-06 23:27:43 +00:00
|
|
|
/* for border draw, we only need to clear a subset of the 3d view */
|
2013-04-14 21:42:58 +00:00
|
|
|
if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
|
2012-06-15 15:01:32 +00:00
|
|
|
glGetIntegerv(GL_SCISSOR_BOX, scissor);
|
2013-04-14 21:42:58 +00:00
|
|
|
glScissor(border_rect->xmin, border_rect->ymin,
|
|
|
|
BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
|
2012-06-15 15:01:32 +00:00
|
|
|
}
|
2013-03-20 23:14:18 +00:00
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
2012-06-06 23:27:43 +00:00
|
|
|
}
|
|
|
|
|
2011-11-02 18:20:53 +00:00
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
2012-03-25 23:54:33 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2012-03-28 09:07:10 +00:00
|
|
|
if (v3d->flag & V3D_DISPBGPICS)
|
2014-05-19 14:18:02 +02:00
|
|
|
view3d_draw_bgpic_test(scene, ar, v3d, false, true);
|
2012-03-28 09:07:10 +00:00
|
|
|
else
|
|
|
|
fdrawcheckerboard(0, 0, ar->winx, ar->winy);
|
|
|
|
|
2012-06-06 23:27:43 +00:00
|
|
|
/* render result draw */
|
2012-03-25 23:54:33 +00:00
|
|
|
type = rv3d->render_engine->type;
|
2011-11-02 18:20:53 +00:00
|
|
|
type->view_draw(rv3d->render_engine, C);
|
|
|
|
|
2012-04-10 14:59:06 +00:00
|
|
|
if (v3d->flag & V3D_DISPBGPICS)
|
2014-05-19 14:18:02 +02:00
|
|
|
view3d_draw_bgpic_test(scene, ar, v3d, true, true);
|
2012-04-10 14:59:06 +00:00
|
|
|
|
2013-04-14 21:42:58 +00:00
|
|
|
if (clip_border) {
|
2012-06-15 15:01:32 +00:00
|
|
|
/* restore scissor as it was before */
|
|
|
|
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
|
|
|
|
}
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2011-11-02 18:20:53 +00:00
|
|
|
}
|
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
|
2011-11-02 18:20:53 +00:00
|
|
|
{
|
2013-04-14 21:42:58 +00:00
|
|
|
float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
|
|
|
|
|
2013-07-16 11:42:07 +00:00
|
|
|
if (!rv3d->render_engine || !rv3d->render_engine->text[0])
|
2011-11-02 18:20:53 +00:00
|
|
|
return;
|
2013-04-14 21:42:58 +00:00
|
|
|
|
|
|
|
if (render_border) {
|
|
|
|
/* draw darkened background color. no alpha because border render does
|
2015-11-28 17:14:45 +01:00
|
|
|
* partial redraw and will not redraw the region behind this info bar */
|
2013-04-14 21:42:58 +00:00
|
|
|
float alpha = 1.0f - fill_color[3];
|
2013-12-09 17:03:37 +11:00
|
|
|
Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
|
2011-11-02 18:20:53 +00:00
|
|
|
|
2013-12-09 17:03:37 +11:00
|
|
|
if (camera) {
|
|
|
|
if (camera->flag & CAM_SHOWPASSEPARTOUT) {
|
|
|
|
alpha *= (1.0f - camera->passepartalpha);
|
|
|
|
}
|
2013-04-14 21:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
|
|
|
|
mul_v3_fl(fill_color, alpha);
|
|
|
|
fill_color[3] = 1.0f;
|
|
|
|
}
|
|
|
|
|
2015-07-01 21:48:42 +02:00
|
|
|
ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
|
2011-11-02 18:20:53 +00:00
|
|
|
}
|
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
|
2015-04-06 10:40:12 -03:00
|
|
|
{
|
2017-05-09 19:21:22 +02:00
|
|
|
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
|
2015-04-06 10:40:12 -03:00
|
|
|
return false;
|
2017-05-09 19:21:22 +02:00
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
|
2015-04-06 10:40:12 -03:00
|
|
|
return false;
|
2017-05-09 19:21:22 +02:00
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
switch (v3d->stereo3d_camera) {
|
|
|
|
case STEREO_MONO_ID:
|
2015-04-06 10:40:12 -03:00
|
|
|
return false;
|
2017-05-09 19:21:22 +02:00
|
|
|
break;
|
|
|
|
case STEREO_3D_ID:
|
|
|
|
/* win will be NULL when calling this from the selection or draw loop. */
|
|
|
|
if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
|
|
|
|
!BKE_scene_multiview_is_stereo3d(&scene->r))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
/* We always need the stereo calculation for left and right cameras. */
|
|
|
|
case STEREO_LEFT_ID:
|
|
|
|
case STEREO_RIGHT_ID:
|
|
|
|
default:
|
|
|
|
break;
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
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
|
2015-11-28 17:14:45 +01:00
|
|
|
* view3d)main_region_setup_view() code to account for that.
|
2015-04-06 10:40:12 -03:00
|
|
|
*/
|
2017-05-10 16:54:01 +02:00
|
|
|
static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
|
2015-04-06 10:40:12 -03:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2018-02-16 01:13:46 +11:00
|
|
|
BLI_thread_lock(LOCK_VIEW3D);
|
2015-04-06 10:40:12 -03:00
|
|
|
data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
|
2015-04-06 10:40:12 -03:00
|
|
|
|
|
|
|
data->shiftx = shiftx;
|
2018-02-16 01:13:46 +11:00
|
|
|
BLI_thread_unlock(LOCK_VIEW3D);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
|
|
|
|
float viewmat[4][4];
|
|
|
|
Object *view_ob = v3d->camera;
|
|
|
|
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
|
|
|
|
|
2018-02-16 01:13:46 +11:00
|
|
|
BLI_thread_lock(LOCK_VIEW3D);
|
2015-04-06 10:40:12 -03:00
|
|
|
v3d->camera = camera;
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
|
2015-04-06 10:40:12 -03:00
|
|
|
|
|
|
|
v3d->camera = view_ob;
|
2018-02-16 01:13:46 +11:00
|
|
|
BLI_thread_unlock(LOCK_VIEW3D);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
|
|
|
|
float winmat[4][4], const char *viewname)
|
|
|
|
{
|
|
|
|
/* update the viewport matrices with the new camera */
|
|
|
|
if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
|
|
|
|
float viewmat[4][4];
|
|
|
|
const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
|
|
|
|
float viewmat[4][4];
|
|
|
|
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
|
|
|
|
|
|
|
|
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
|
2017-05-10 16:54:01 +02:00
|
|
|
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-09 11:48:04 +10:00
|
|
|
#ifdef WITH_GAMEENGINE
|
2013-12-17 14:42:47 -08:00
|
|
|
static void update_lods(Scene *scene, float camera_pos[3])
|
|
|
|
{
|
|
|
|
Scene *sce_iter;
|
|
|
|
Base *base;
|
|
|
|
Object *ob;
|
|
|
|
|
|
|
|
for (SETLOOPER(scene, sce_iter, base)) {
|
|
|
|
ob = base->object;
|
|
|
|
BKE_object_lod_update(ob, camera_pos);
|
|
|
|
}
|
|
|
|
}
|
2014-04-09 11:48:04 +10:00
|
|
|
#endif
|
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
|
2014-04-12 15:34:59 +10:00
|
|
|
ARegion *ar, const char **grid_unit)
|
2013-01-07 06:33:29 +00:00
|
|
|
{
|
2016-02-04 22:26:46 +01:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2014-04-12 15:34:59 +10:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
unsigned int lay_used = v3d->lay_used;
|
2015-02-12 18:54:41 +01:00
|
|
|
|
|
|
|
/* post processing */
|
|
|
|
bool do_compositing = false;
|
|
|
|
|
2013-01-07 06:33:29 +00:00
|
|
|
/* shadow buffers, before we setup matrices */
|
|
|
|
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
|
2015-03-23 22:32:49 +01:00
|
|
|
gpu_update_lamps_shadows_world(scene, v3d);
|
|
|
|
|
2013-01-07 06:33:29 +00:00
|
|
|
/* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
|
|
|
|
if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
|
|
|
|
rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
|
|
|
|
GPU_default_lights();
|
|
|
|
}
|
|
|
|
|
2017-05-09 19:21:22 +02:00
|
|
|
/* Setup the view matrix. */
|
2017-05-10 16:54:01 +02:00
|
|
|
ED_view3d_draw_setup_view(CTX_wm_window(C), scene, ar, v3d, NULL, NULL, NULL);
|
2013-01-07 06:33:29 +00:00
|
|
|
|
2014-04-09 11:48:04 +10:00
|
|
|
rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
|
|
|
|
#ifdef WITH_GAMEENGINE
|
2014-10-28 12:49:04 +01:00
|
|
|
if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) {
|
2014-04-09 11:48:04 +10:00
|
|
|
rv3d->rflag |= RV3D_IS_GAME_ENGINE;
|
|
|
|
|
|
|
|
/* Make sure LoDs are up to date */
|
|
|
|
update_lods(scene, rv3d->viewinv[3]);
|
|
|
|
}
|
|
|
|
#endif
|
2013-12-17 14:42:47 -08:00
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
/* framebuffer fx needed, we need to draw offscreen first */
|
2015-05-04 14:34:44 +02:00
|
|
|
if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
|
2015-02-12 18:54:41 +01:00
|
|
|
GPUFXSettings fx_settings;
|
|
|
|
BKE_screen_gpu_fx_validate(&v3d->fx_settings);
|
|
|
|
fx_settings = v3d->fx_settings;
|
|
|
|
if (!rv3d->compositor)
|
|
|
|
rv3d->compositor = GPU_fx_compositor_create();
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB && v3d->camera)
|
|
|
|
BKE_camera_to_gpu_dof(v3d->camera, &fx_settings);
|
|
|
|
else {
|
|
|
|
fx_settings.dof = NULL;
|
|
|
|
}
|
2015-03-23 18:54:56 +01:00
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
|
|
|
|
}
|
|
|
|
|
2013-01-07 06:33:29 +00:00
|
|
|
/* clear the background */
|
2015-11-28 17:14:45 +01:00
|
|
|
view3d_main_region_clear(scene, v3d, ar);
|
2009-10-28 18:03:04 +00:00
|
|
|
|
2010-01-08 09:30:36 +00:00
|
|
|
/* enables anti-aliasing for 3D view drawing */
|
2016-02-04 22:26:46 +01:00
|
|
|
if (win->multisamples != USER_MULTISAMPLE_NONE) {
|
2015-11-24 02:20:38 -05:00
|
|
|
glEnable(GL_MULTISAMPLE);
|
2012-11-24 00:59:10 +00:00
|
|
|
}
|
2012-11-10 11:55:45 +00:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* main drawing call */
|
2015-02-17 18:35:56 +01:00
|
|
|
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
|
2012-04-10 14:59:06 +00:00
|
|
|
|
2015-02-12 18:54:41 +01:00
|
|
|
/* post process */
|
|
|
|
if (do_compositing) {
|
|
|
|
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
|
|
|
|
}
|
2015-02-13 11:52:27 +01:00
|
|
|
|
2014-04-12 15:34:59 +10:00
|
|
|
/* Disable back anti-aliasing */
|
2016-02-04 22:26:46 +01:00
|
|
|
if (win->multisamples != USER_MULTISAMPLE_NONE) {
|
2015-11-24 02:20:38 -05:00
|
|
|
glDisable(GL_MULTISAMPLE);
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2009-01-13 19:57:36 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
|
2010-10-02 09:28:41 +00:00
|
|
|
/* find header and force tag redraw */
|
2012-03-25 23:54:33 +00:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
|
|
|
ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
|
2011-05-20 05:27:31 +00:00
|
|
|
ED_region_tag_redraw(ar_header); /* can be NULL */
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2010-03-16 17:49:31 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
|
2010-03-16 17:49:31 +00:00
|
|
|
BDR_drawSketch(C);
|
|
|
|
}
|
|
|
|
|
2016-08-18 00:21:55 -04:00
|
|
|
#ifdef WITH_INPUT_NDOF
|
2014-02-04 21:04:36 +11:00
|
|
|
if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) && (rv3d->persp != RV3D_CAMOB))
|
2012-07-08 20:36:00 +00:00
|
|
|
/* TODO: draw something else (but not this) during fly mode */
|
2011-07-26 02:35:46 +00:00
|
|
|
draw_rotation_guide(rv3d);
|
2016-08-18 00:21:55 -04:00
|
|
|
#endif
|
2011-10-23 13:00:41 +00:00
|
|
|
}
|
|
|
|
|
2015-02-17 03:26:03 +01:00
|
|
|
static bool is_cursor_visible(Scene *scene)
|
|
|
|
{
|
2018-01-12 12:41:03 +11:00
|
|
|
if (U.app_flag & USER_APP_VIEW3D_HIDE_CURSOR) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-02-17 03:26:03 +01:00
|
|
|
Object *ob = OBACT;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
2015-03-25 20:16:27 +11:00
|
|
|
if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
|
2015-02-17 03:26:03 +01:00
|
|
|
if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* no exception met? then don't draw cursor! */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
|
2014-04-12 15:34:59 +10:00
|
|
|
ARegion *ar, View3D *v3d,
|
|
|
|
const char *grid_unit, bool render_border)
|
2011-10-23 13:00:41 +00:00
|
|
|
{
|
2015-12-13 21:03:13 +13:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2014-04-12 15:34:59 +10:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2012-12-18 13:59:47 +00:00
|
|
|
rcti rect;
|
|
|
|
|
|
|
|
/* local coordinate visible rect inside region, to accomodate overlapping ui */
|
|
|
|
ED_region_visible_rect(ar, &rect);
|
2011-10-23 13:00:41 +00:00
|
|
|
|
2012-10-16 11:57:46 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2010-10-02 19:31:23 +00:00
|
|
|
drawviewborder(scene, ar, v3d);
|
2012-10-16 11:57:46 +00:00
|
|
|
}
|
|
|
|
else if (v3d->flag2 & V3D_RENDER_BORDER) {
|
2016-05-07 23:53:35 +10:00
|
|
|
glLineWidth(1.0f);
|
2012-10-16 11:57:46 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
cpack(0x4040FF);
|
|
|
|
|
2016-01-22 01:45:39 -05:00
|
|
|
sdrawbox(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
|
|
|
|
v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
|
2012-10-16 11:57:46 +00:00
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
2010-03-16 17:49:31 +00:00
|
|
|
|
2012-12-17 05:36:00 +00:00
|
|
|
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
|
|
|
|
/* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
|
2015-12-13 21:03:13 +13:00
|
|
|
ED_gpencil_draw_view3d(wm, scene, v3d, ar, false);
|
2012-12-17 05:36:00 +00:00
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
|
2013-12-14 15:23:57 +02:00
|
|
|
Object *ob;
|
2012-10-25 03:10:35 +00:00
|
|
|
|
2015-02-17 03:26:03 +01:00
|
|
|
/* 3d cursor */
|
|
|
|
if (is_cursor_visible(scene)) {
|
|
|
|
drawcursor(scene, ar, v3d);
|
|
|
|
}
|
2012-10-25 03:10:35 +00:00
|
|
|
|
|
|
|
if (U.uiflag & USER_SHOW_ROTVIEWICON)
|
2012-12-18 13:59:47 +00:00
|
|
|
draw_view_axis(rv3d, &rect);
|
2012-10-25 03:10:35 +00:00
|
|
|
else
|
2012-12-18 13:59:47 +00:00
|
|
|
draw_view_icon(rv3d, &rect);
|
2012-10-25 03:10:35 +00:00
|
|
|
|
2013-12-14 15:23:57 +02:00
|
|
|
ob = OBACT;
|
2012-10-25 03:10:35 +00:00
|
|
|
if (U.uiflag & USER_DRAWVIEWINFO)
|
2012-12-18 13:59:47 +00:00
|
|
|
draw_selected_name(scene, ob, &rect);
|
2010-03-16 17:49:31 +00:00
|
|
|
}
|
2011-11-14 19:45:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->render_engine) {
|
2015-11-28 17:14:45 +01:00
|
|
|
view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border);
|
2011-11-02 18:20:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-25 03:10:35 +00:00
|
|
|
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
|
2015-08-07 15:39:32 +02:00
|
|
|
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
|
2013-10-17 21:17:33 +00:00
|
|
|
ED_scene_draw_fps(scene, &rect);
|
2012-10-25 03:10:35 +00:00
|
|
|
}
|
|
|
|
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
|
2012-12-18 13:59:47 +00:00
|
|
|
draw_viewport_name(ar, v3d, &rect);
|
2012-10-25 03:10:35 +00:00
|
|
|
}
|
2012-01-18 10:41:38 +00:00
|
|
|
|
2012-10-25 03:10:35 +00:00
|
|
|
if (grid_unit) { /* draw below the viewport name */
|
|
|
|
char numstr[32] = "";
|
2010-11-23 14:14:06 +00:00
|
|
|
|
2012-10-25 03:10:35 +00:00
|
|
|
UI_ThemeColor(TH_TEXT_HI);
|
|
|
|
if (v3d->grid != 1.0f) {
|
|
|
|
BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
|
|
|
|
}
|
2010-11-23 14:14:06 +00:00
|
|
|
|
2012-12-18 13:59:47 +00:00
|
|
|
BLF_draw_default_ascii(rect.xmin + U.widget_unit,
|
|
|
|
rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
|
2012-10-25 03:10:35 +00:00
|
|
|
numstr[0] ? numstr : grid_unit, sizeof(numstr));
|
|
|
|
}
|
2009-08-12 14:11:53 +00:00
|
|
|
}
|
2011-10-23 13:00:41 +00:00
|
|
|
}
|
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
void view3d_main_region_draw(const bContext *C, ARegion *ar)
|
2011-10-23 13:00:41 +00:00
|
|
|
{
|
2012-06-06 23:27:43 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2011-10-23 13:00:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
const char *grid_unit = NULL;
|
2013-04-14 21:42:58 +00:00
|
|
|
rcti border_rect;
|
|
|
|
bool render_border, clip_border;
|
2012-10-16 11:57:46 +00:00
|
|
|
|
2013-04-14 21:42:58 +00:00
|
|
|
/* if we only redraw render border area, skip opengl draw and also
|
|
|
|
* don't do scissor because it's already set */
|
|
|
|
render_border = ED_view3d_calc_render_border(scene, v3d, ar, &border_rect);
|
|
|
|
clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect));
|
2011-10-23 13:00:41 +00:00
|
|
|
|
2012-06-06 23:27:43 +00:00
|
|
|
/* draw viewport using opengl */
|
2015-11-28 17:14:45 +01:00
|
|
|
if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) {
|
|
|
|
view3d_main_region_draw_objects(C, scene, v3d, ar, &grid_unit);
|
2015-01-20 18:29:31 +01:00
|
|
|
|
2012-11-16 07:56:47 +00:00
|
|
|
#ifdef DEBUG_DRAW
|
|
|
|
bl_debug_draw();
|
|
|
|
#endif
|
2015-01-21 14:00:59 +01:00
|
|
|
if (G.debug & G_DEBUG_SIMDATA)
|
|
|
|
draw_sim_debug_data(scene, v3d, ar);
|
2015-01-20 18:29:31 +01:00
|
|
|
|
2011-11-02 18:20:53 +00:00
|
|
|
ED_region_pixelspace(ar);
|
|
|
|
}
|
2012-06-06 23:27:43 +00:00
|
|
|
|
|
|
|
/* draw viewport using external renderer */
|
|
|
|
if (v3d->drawtype == OB_RENDER)
|
2015-11-28 17:14:45 +01:00
|
|
|
view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2015-11-28 17:14:45 +01:00
|
|
|
view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
|
2008-12-18 17:38:21 +00:00
|
|
|
|
2009-12-17 14:38:30 +00:00
|
|
|
v3d->flag |= V3D_INVALID_BACKBUF;
|
2016-06-12 17:06:50 +02:00
|
|
|
|
|
|
|
BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_transp));
|
|
|
|
BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xray));
|
|
|
|
BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xraytransp));
|
2008-12-18 17:38:21 +00:00
|
|
|
}
|
2011-08-12 18:13:55 +00:00
|
|
|
|
2012-11-16 07:56:47 +00:00
|
|
|
#ifdef DEBUG_DRAW
|
|
|
|
/* debug drawing */
|
|
|
|
#define _DEBUG_DRAW_QUAD_TOT 1024
|
2012-11-25 13:52:13 +00:00
|
|
|
#define _DEBUG_DRAW_EDGE_TOT 1024
|
2012-11-16 07:56:47 +00:00
|
|
|
static float _bl_debug_draw_quads[_DEBUG_DRAW_QUAD_TOT][4][3];
|
|
|
|
static int _bl_debug_draw_quads_tot = 0;
|
2012-11-25 13:52:13 +00:00
|
|
|
static float _bl_debug_draw_edges[_DEBUG_DRAW_QUAD_TOT][2][3];
|
|
|
|
static int _bl_debug_draw_edges_tot = 0;
|
2014-01-14 03:58:06 +11:00
|
|
|
static unsigned int _bl_debug_draw_quads_color[_DEBUG_DRAW_QUAD_TOT];
|
|
|
|
static unsigned int _bl_debug_draw_edges_color[_DEBUG_DRAW_EDGE_TOT];
|
|
|
|
static unsigned int _bl_debug_draw_color;
|
2012-11-16 07:56:47 +00:00
|
|
|
|
|
|
|
void bl_debug_draw_quad_clear(void)
|
|
|
|
{
|
|
|
|
_bl_debug_draw_quads_tot = 0;
|
2012-11-25 13:52:13 +00:00
|
|
|
_bl_debug_draw_edges_tot = 0;
|
2014-01-14 03:58:06 +11:00
|
|
|
_bl_debug_draw_color = 0x00FF0000;
|
|
|
|
}
|
|
|
|
void bl_debug_color_set(const unsigned int color)
|
|
|
|
{
|
|
|
|
_bl_debug_draw_color = color;
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
|
|
|
void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3])
|
|
|
|
{
|
|
|
|
if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) {
|
|
|
|
printf("%s: max quad count hit %d!", __func__, _bl_debug_draw_quads_tot);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0];
|
|
|
|
copy_v3_v3(pt, v0); pt += 3;
|
|
|
|
copy_v3_v3(pt, v1); pt += 3;
|
|
|
|
copy_v3_v3(pt, v2); pt += 3;
|
|
|
|
copy_v3_v3(pt, v3); pt += 3;
|
2014-01-14 03:58:06 +11:00
|
|
|
_bl_debug_draw_quads_color[_bl_debug_draw_quads_tot] = _bl_debug_draw_color;
|
2012-11-16 07:56:47 +00:00
|
|
|
_bl_debug_draw_quads_tot++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void bl_debug_draw_edge_add(const float v0[3], const float v1[3])
|
|
|
|
{
|
2012-11-25 13:52:13 +00:00
|
|
|
if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_EDGE_TOT) {
|
|
|
|
printf("%s: max edge count hit %d!", __func__, _bl_debug_draw_edges_tot);
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-11-25 13:52:13 +00:00
|
|
|
float *pt = &_bl_debug_draw_edges[_bl_debug_draw_edges_tot][0][0];
|
2012-11-16 07:56:47 +00:00
|
|
|
copy_v3_v3(pt, v0); pt += 3;
|
|
|
|
copy_v3_v3(pt, v1); pt += 3;
|
2014-01-14 03:58:06 +11:00
|
|
|
_bl_debug_draw_edges_color[_bl_debug_draw_edges_tot] = _bl_debug_draw_color;
|
2012-11-25 13:52:13 +00:00
|
|
|
_bl_debug_draw_edges_tot++;
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
static void bl_debug_draw(void)
|
|
|
|
{
|
2014-01-14 03:58:06 +11:00
|
|
|
unsigned int color;
|
2012-11-16 07:56:47 +00:00
|
|
|
if (_bl_debug_draw_quads_tot) {
|
|
|
|
int i;
|
2014-01-14 03:58:06 +11:00
|
|
|
color = _bl_debug_draw_quads_color[0];
|
|
|
|
cpack(color);
|
2012-11-18 01:22:31 +00:00
|
|
|
for (i = 0; i < _bl_debug_draw_quads_tot; i ++) {
|
2014-01-14 03:58:06 +11:00
|
|
|
if (_bl_debug_draw_quads_color[i] != color) {
|
|
|
|
color = _bl_debug_draw_quads_color[i];
|
|
|
|
cpack(color);
|
|
|
|
}
|
2013-01-21 18:19:34 +00:00
|
|
|
glBegin(GL_LINE_LOOP);
|
2012-11-16 07:56:47 +00:00
|
|
|
glVertex3fv(_bl_debug_draw_quads[i][0]);
|
|
|
|
glVertex3fv(_bl_debug_draw_quads[i][1]);
|
|
|
|
glVertex3fv(_bl_debug_draw_quads[i][2]);
|
|
|
|
glVertex3fv(_bl_debug_draw_quads[i][3]);
|
2013-01-21 18:19:34 +00:00
|
|
|
glEnd();
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
|
|
|
}
|
2012-11-25 13:52:13 +00:00
|
|
|
if (_bl_debug_draw_edges_tot) {
|
|
|
|
int i;
|
2014-01-14 03:58:06 +11:00
|
|
|
color = _bl_debug_draw_edges_color[0];
|
|
|
|
cpack(color);
|
2012-11-25 13:52:13 +00:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
|
2014-01-14 03:58:06 +11:00
|
|
|
if (_bl_debug_draw_edges_color[i] != color) {
|
|
|
|
color = _bl_debug_draw_edges_color[i];
|
|
|
|
cpack(color);
|
|
|
|
}
|
2012-11-25 13:52:13 +00:00
|
|
|
glVertex3fv(_bl_debug_draw_edges[i][0]);
|
|
|
|
glVertex3fv(_bl_debug_draw_edges[i][1]);
|
|
|
|
}
|
|
|
|
glEnd();
|
2014-01-14 03:58:06 +11:00
|
|
|
color = _bl_debug_draw_edges_color[0];
|
|
|
|
cpack(color);
|
2012-11-25 13:52:13 +00:00
|
|
|
glPointSize(4.0);
|
|
|
|
glBegin(GL_POINTS);
|
|
|
|
for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
|
2014-01-14 03:58:06 +11:00
|
|
|
if (_bl_debug_draw_edges_color[i] != color) {
|
|
|
|
color = _bl_debug_draw_edges_color[i];
|
|
|
|
cpack(color);
|
|
|
|
}
|
2012-11-25 13:52:13 +00:00
|
|
|
glVertex3fv(_bl_debug_draw_edges[i][0]);
|
|
|
|
glVertex3fv(_bl_debug_draw_edges[i][1]);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
2012-11-16 07:56:47 +00:00
|
|
|
}
|
|
|
|
#endif
|