Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt12
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c132
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c1471
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c1047
-rw-r--r--source/blender/editors/space_view3d/drawobject.c4895
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c111
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c3
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c349
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c29
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4580
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c2186
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c293
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c51
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c59
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h118
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c27
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_armature.c220
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_camera.c401
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_empty.c196
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_forcefield.c118
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_lamp.c289
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_ruler.c1079
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c31
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c29
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c239
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c366
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c440
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c43
30 files changed, 11000 insertions, 7853 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index a5c60248bf1..de8380aa8bb 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../blenlib
../../blentranslation
../../bmesh
+ ../../draw
../../gpu
../../imbuf
../../makesdna
@@ -52,11 +53,18 @@ set(SRC
view3d_buttons.c
view3d_camera_control.c
view3d_draw.c
+ view3d_draw_legacy.c
view3d_edit.c
view3d_fly.c
view3d_walk.c
view3d_header.c
view3d_iterators.c
+ view3d_manipulator_armature.c
+ view3d_manipulator_camera.c
+ view3d_manipulator_empty.c
+ view3d_manipulator_forcefield.c
+ view3d_manipulator_lamp.c
+ view3d_manipulator_ruler.c
view3d_ops.c
view3d_project.c
view3d_ruler.c
@@ -94,8 +102,4 @@ if(WITH_MOD_SMOKE)
add_definitions(-DWITH_SMOKE)
endif()
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index f0e65f84205..66355a50478 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -49,7 +49,8 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "ED_keyframes_draw.h"
@@ -71,8 +72,8 @@ void draw_motion_paths_init(View3D *v3d, ARegion *ar)
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
}
/* set color
@@ -86,10 +87,11 @@ void draw_motion_paths_init(View3D *v3d, ARegion *ar)
* - User selected color for next frames
*/
static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short sel, int sfra, int efra,
- float prev_color[3], float frame_color[3], float next_color[3])
+ float prev_color[3], float frame_color[3], float next_color[3], unsigned color)
{
int frame = sfra + i;
int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
+ unsigned char ubcolor[3];
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
float intensity; /* how faint */
@@ -97,7 +99,7 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
if (frame < CFRA) {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: previous frames color is darker than current frame */
- glColor3fv(prev_color);
+ rgb_float_to_uchar(ubcolor, prev_color);
}
else {
/* black - before cfra */
@@ -109,13 +111,14 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
/* intensity = 0.8f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
+
+ UI_GetThemeColorBlend3ubv(TH_WIRE, blend_base, intensity, ubcolor);
}
}
else if (frame > CFRA) {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: next frames color is equal to user selected color */
- glColor3fv(next_color);
+ rgb_float_to_uchar(ubcolor, next_color);
}
else {
/* blue - after cfra */
@@ -127,13 +130,14 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
/* intensity = 0.8f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
+
+ UI_GetThemeColorBlend3ubv(TH_BONE_POSE, blend_base, intensity, ubcolor);
}
}
else {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: current frame color is slightly darker than user selected color */
- glColor3fv(frame_color);
+ rgb_float_to_uchar(ubcolor, frame_color);
}
else {
/* green - on cfra */
@@ -143,9 +147,12 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
else {
intensity = 0.99f;
}
- UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
+ UI_GetThemeColorBlendShade3ubv(TH_CFRAME, TH_BACK, intensity, 10, ubcolor);
}
}
+
+ immAttrib3ubv(color, ubcolor);
+
#undef SET_INTENSITY
}
@@ -231,42 +238,65 @@ void draw_motion_path_instance(Scene *scene,
/* set line thickness */
glLineWidth(mpath->line_thickness);
- glBegin(GL_LINE_STRIP);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+
+ immBegin(GWN_PRIM_LINE_STRIP, len);
+
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
+
/* Set color */
- set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color);
+ set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color, color);
+
/* draw a vertex with this color */
- glVertex3fv(mpv->co);
+ immVertex3fv(pos, mpv->co);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
+
/* back to old line thickness */
glLineWidth(old_width);
}
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
/* Point must be bigger than line thickness */
glPointSize(mpath->line_thickness + 1.0);
- /* draw little black point at each frame
- * NOTE: this is not really visible/noticeable
- */
- glBegin(GL_POINTS);
- for (i = 0, mpv = mpv_start; i < len; i++, mpv++)
- glVertex3fv(mpv->co);
- glEnd();
-
+ /* draw little black point at each frame */
+ immUniformColor3ub(0, 0, 0);
+
+ immBegin(GWN_PRIM_POINTS, len);
+
+ for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
+ immVertex3fv(pos, mpv->co);
+ }
+
+ immEnd();
+
/* Draw little white dots at each framestep value or replace with custom color */
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
- glColor4fv(mpath->color);
+ immUniformColor3fv(mpath->color);
}
else {
- UI_ThemeColor(TH_TEXT_HI);
+ immUniformThemeColor(TH_TEXT_HI);
}
- glBegin(GL_POINTS);
- for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize)
- glVertex3fv(mpv->co);
- glEnd();
+
+ immBegin(GWN_PRIM_POINTS, (len + stepsize - 1) / stepsize);
+
+ for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
+ immVertex3fv(pos, mpv->co);
+ }
+
+ immEnd();
/* Draw big green dot where the current frame is
* NOTE: this is only done when keyframes are shown, since this adds similar types of clutter
@@ -274,16 +304,18 @@ void draw_motion_path_instance(Scene *scene,
if ((avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) &&
(sfra < CFRA) && (CFRA <= efra))
{
- UI_ThemeColor(TH_CFRAME);
-
glPointSize(mpath->line_thickness + 5.0);
- glBegin(GL_POINTS);
+ immUniformThemeColor(TH_CFRAME);
+
+ immBegin(GWN_PRIM_POINTS, 1);
+
mpv = mpv_start + (CFRA - sfra);
- glVertex3fv(mpv->co);
- glEnd();
-
- UI_ThemeColor(TH_TEXT_HI);
+ immVertex3fv(pos, mpv->co);
+
+ immEnd();
}
+
+ immUnbindProgram();
/* XXX, this isn't up to date but probably should be kept so. */
invert_m4_m4(ob->imat, ob->obmat);
@@ -353,24 +385,28 @@ void draw_motion_path_instance(Scene *scene,
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
col[3] = 255;
- /* if custom, point must be bigger than line */
- if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
- glPointSize(mpath->line_thickness + 3.0);
- }
- else {
- glPointSize(4.0f);
- }
- glColor3ubv(col);
+ /* point must be bigger than line */
+ glPointSize(mpath->line_thickness + 3.0);
+
+ pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(col);
- glBegin(GL_POINTS);
+ immBeginAtMost(GWN_PRIM_POINTS, len);
+
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
int frame = sfra + i;
float mframe = (float)(frame);
- if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
- glVertex3fv(mpv->co);
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
+ immVertex3fv(pos, mpv->co);
+ }
}
- glEnd();
+
+ immEnd();
+
+ immUnbindProgram();
/* Draw frame numbers of keyframes */
if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
@@ -398,5 +434,5 @@ void draw_motion_path_instance(Scene *scene,
void draw_motion_paths_cleanup(View3D *v3d)
{
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- glPopMatrix();
+ gpuPopMatrix();
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 5208013b6fe..f04b8c0cdad 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -54,15 +54,20 @@
#include "BKE_modifier.h"
#include "BKE_nla.h"
#include "BKE_curve.h"
+#include "BKE_context.h"
+#include "DEG_depsgraph.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "ED_armature.h"
#include "ED_keyframes_draw.h"
#include "GPU_basic_shader.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "UI_resources.h"
@@ -74,8 +79,10 @@
/* global here is reset before drawing each bone */
static ThemeWireColor *bcolor = NULL;
+static float fcolor[4] = {0.0f};
+static bool flat_color;
-/* values of colCode for set_pchan_glcolor */
+/* values of colCode for set_pchan_color */
enum {
PCHAN_COLOR_NORMAL = 0, /* normal drawing */
PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
@@ -128,7 +135,7 @@ static void set_pchan_colorset(Object *ob, bPoseChannel *pchan)
}
}
-/* This function is for brightening/darkening a given color (like UI_ThemeColorShade()) */
+/* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */
static void cp_shade_color3ub(unsigned char cp[3], const int offset)
{
int r, g, b;
@@ -146,13 +153,13 @@ static void cp_shade_color3ub(unsigned char cp[3], const int offset)
}
/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
-static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
+static bool set_pchan_color(short colCode, int boneflag, short constflag)
{
switch (colCode) {
case PCHAN_COLOR_NORMAL:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -169,20 +176,20 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
cp_shade_color3ub(cp, -50);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
- UI_ThemeColor(TH_BONE_POSE_ACTIVE);
+ UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor);
}
else if (boneflag & BONE_DRAW_ACTIVE) {
- UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */
+ UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor);
}
else if (boneflag & BONE_SELECTED) {
- UI_ThemeColor(TH_BONE_POSE);
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
}
else {
- UI_ThemeColor(TH_WIRE);
+ UI_GetThemeColor4fv(TH_WIRE, fcolor);
}
}
@@ -191,21 +198,25 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SOLID:
{
if (bcolor) {
- glColor3ubv((unsigned char *)bcolor->solid);
+ rgb_uchar_to_float(fcolor, (unsigned char *)bcolor->solid);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
- else
- UI_ThemeColor(TH_BONE_SOLID);
return true;
}
case PCHAN_COLOR_CONSTS:
{
if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
- if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
- else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
- else if (constflag & PCHAN_HAS_SPLINEIK) glColor4ub(200, 255, 0, 80);
- else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
-
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 80);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 80);
+
+ rgba_uchar_to_float(fcolor, cp);
+
return true;
}
return false;
@@ -213,7 +224,7 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SPHEREBONE_BASE:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -225,12 +236,18 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
copy_v3_v3_char((char *)cp, bcolor->solid);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
- if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE);
- else UI_ThemeColor(TH_BONE_SOLID);
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
return true;
@@ -238,7 +255,7 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SPHEREBONE_END:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -253,12 +270,18 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
cp_shade_color3ub(cp, -30);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
- if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10);
- else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor);
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
+ }
}
break;
}
@@ -266,19 +289,24 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
{
/* inner part in background color or constraint */
if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) {
- if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
- else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
- else if (constflag & PCHAN_HAS_SPLINEIK) glColor3ub(200, 255, 0);
- else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
- else if (constflag) UI_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 255);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 255);
+ else if (constflag) UI_GetThemeColor4ubv(TH_BONE_POSE, cp); /* PCHAN_HAS_ACTION */
+
+ rgb_uchar_to_float(fcolor, cp);
}
else {
if (bcolor) {
const char *cp = bcolor->solid;
- glColor4ub(cp[0], cp[1], cp[2], 204);
+ rgb_uchar_to_float(fcolor, (unsigned char *)cp);
+ fcolor[3] = 204.f / 255.f;
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
}
- else
- UI_ThemeColorShade(TH_BACK, -30);
}
return true;
@@ -288,26 +316,37 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
return false;
}
-static void set_ebone_glColor(const unsigned int boneflag)
+static void set_ebone_color(const unsigned int boneflag)
{
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
- UI_ThemeColor(TH_EDGE_SELECT);
+ UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor);
}
else if (boneflag & BONE_DRAW_ACTIVE) {
- UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f); /* unselected active */
+ UI_GetThemeColorBlendShade4fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, fcolor);
}
else if (boneflag & BONE_SELECTED) {
- UI_ThemeColorShade(TH_EDGE_SELECT, -20);
+ UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, fcolor);
}
else {
- UI_ThemeColor(TH_WIRE_EDIT);
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
}
}
/* *************** Armature drawing, helper calls for parts ******************* */
+static void add_solid_flat_triangle(Gwn_VertBuf *vbo, unsigned int *vertex, unsigned int pos, unsigned int nor,
+ const float p1[3], const float p2[3], const float p3[3], const float n[3])
+{
+ GWN_vertbuf_attr_set(vbo, nor, *vertex, n);
+ GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p1);
+ GWN_vertbuf_attr_set(vbo, nor, *vertex, n);
+ GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p2);
+ GWN_vertbuf_attr_set(vbo, nor, *vertex, n);
+ GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p3);
+}
+
/* half the cube, in Y */
-static const float cube[8][3] = {
+static const float cube_vert[8][3] = {
{-1.0, 0.0, -1.0},
{-1.0, 0.0, 1.0},
{-1.0, 1.0, 1.0},
@@ -318,128 +357,184 @@ static const float cube[8][3] = {
{ 1.0, 1.0, -1.0},
};
+static const float cube_wire[24] = {
+ 0, 1, 1, 2, 2, 3, 3, 0,
+ 4, 5, 5, 6, 6, 7, 7, 4,
+ 0, 4, 1, 5, 2, 6, 3, 7,
+};
+
static void drawsolidcube_size(float xsize, float ysize, float zsize)
{
- static GLuint displist = 0;
- float n[3] = {0.0f};
-
- glScalef(xsize, ysize, zsize);
-
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
+ static Gwn_VertFormat format = {0};
+ static Gwn_VertBuf vbo = {{0}};
+ static Gwn_Batch batch = {{0}};
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ if (format.attrib_ct == 0) {
+ unsigned int i = 0;
+ float n[3] = {0.0f};
+ /* Vertex format */
+ unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ /* Vertices */
+ GWN_vertbuf_init_with_format(&vbo, &format);
+ GWN_vertbuf_data_alloc(&vbo, 36);
- glBegin(GL_QUADS);
n[0] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[1], cube_vert[2], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[3], cube_vert[0], n);
n[0] = 0;
n[1] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[4], cube_vert[5], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[5], cube_vert[1], cube_vert[0], n);
n[1] = 0;
n[0] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[4], cube_vert[7], cube_vert[6], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[5], cube_vert[4], n);
n[0] = 0;
n[1] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[3], cube_vert[2], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[6], cube_vert[7], n);
n[1] = 0;
n[2] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[1], cube_vert[5], cube_vert[6], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[2], cube_vert[1], n);
n[2] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
- glEnd();
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[4], cube_vert[0], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[3], cube_vert[7], n);
- glEndList();
+ GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL);
}
- glCallList(displist);
+ gpuPushMatrix();
+ gpuScale3f(xsize, ysize, zsize);
+
+ if (flat_color) {
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ /* TODO replace with good default lighting shader ? */
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3fv(&batch, "light", light_vec);
+ }
+ GWN_batch_uniform_4fv(&batch, "color", fcolor);
+ GWN_batch_draw(&batch);
+
+ gpuPopMatrix();
}
static void drawcube_size(float xsize, float ysize, float zsize)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[6]);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]);
- glEnd();
-
- glBegin(GL_LINES);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]);
- glVertex3fv(cube[2]); glVertex3fv(cube[6]);
- glVertex3fv(cube[3]); glVertex3fv(cube[7]);
- glEnd();
-
- glEndList();
+ static Gwn_VertFormat format = {0};
+ static Gwn_VertBuf vbo = {{0}};
+ static Gwn_IndexBufBuilder elb = {0};
+ static Gwn_IndexBuf el = {0};
+ static Gwn_Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ /* Elements */
+ GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 8);
+ for (int i = 0; i < 12; ++i) {
+ GWN_indexbuf_add_line_verts(&elb, cube_wire[i * 2], cube_wire[i * 2 + 1]);
+ }
+ GWN_indexbuf_build_in_place(&elb, &el);
+
+ /* Vertices */
+ GWN_vertbuf_init_with_format(&vbo, &format);
+ GWN_vertbuf_data_alloc(&vbo, 8);
+ for (int i = 0; i < 8; ++i) {
+ GWN_vertbuf_attr_set(&vbo, pos, i, cube_vert[i]);
+ }
+
+ GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glScalef(xsize, ysize, zsize);
- glCallList(displist);
-
+ gpuPushMatrix();
+ gpuScale3f(xsize, ysize, zsize);
+
+ GWN_batch_program_use_begin(&batch);
+ GWN_batch_uniform_4fv(&batch, "color", fcolor);
+ GWN_batch_draw(&batch);
+
+ gpuPopMatrix();
}
static void draw_bonevert(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glPushMatrix();
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- glRotatef(90, 0, 1, 0);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- glRotatef(90, 1, 0, 0);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- gluDeleteQuadric(qobj);
-
- glPopMatrix();
- glEndList();
+ static Gwn_VertFormat format = {0};
+ static Gwn_VertBuf vbo = {{0}};
+ static Gwn_Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ /* Vertices */
+ GWN_vertbuf_init_with_format(&vbo, &format);
+ GWN_vertbuf_data_alloc(&vbo, 96);
+ for (int i = 0; i < 16; ++i) {
+ float vert[3] = {0.f, 0.f, 0.f};
+ const float r = 0.05f;
+
+ vert[0] = r * cosf(2 * M_PI * i / 16.f);
+ vert[1] = r * sinf(2 * M_PI * i / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 0, vert);
+ vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[1] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 1, vert);
+
+ vert[0] = 0.f;
+ vert[1] = r * cosf(2 * M_PI * i / 16.f);
+ vert[2] = r * sinf(2 * M_PI * i / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 2, vert);
+ vert[1] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 3, vert);
+
+ vert[1] = 0.f;
+ vert[0] = r * cosf(2 * M_PI * i / 16.f);
+ vert[2] = r * sinf(2 * M_PI * i / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 4, vert);
+ vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 5, vert);
+ }
+
+ GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, NULL);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glCallList(displist);
+ GWN_batch_program_use_begin(&batch);
+ GWN_batch_uniform_4fv(&batch, "color", fcolor);
+ GWN_batch_draw(&batch);
}
static void draw_bonevert_solid(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
- /* Draw tips of a bone */
- gluSphere(qobj, 0.05, 8, 5);
- gluDeleteQuadric(qobj);
-
- glEndList();
+ Gwn_Batch *batch = GPU_batch_preset_sphere(0);
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ gpuPushMatrix();
+ gpuScaleUniform(0.05);
+
+ if (flat_color) {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
+ else {
+ /* TODO replace with good default lighting shader ? */
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3fv(batch, "light", light_vec);
+ }
+ GWN_batch_uniform_4fv(batch, "color", fcolor);
+ GWN_batch_draw(batch);
- glCallList(displist);
+ gpuPopMatrix();
}
static const float bone_octahedral_verts[6][3] = {
@@ -451,8 +546,11 @@ static const float bone_octahedral_verts[6][3] = {
{ 0.0f, 1.0f, 0.0f}
};
-static const unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2};
-static const unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1};
+static const unsigned int bone_octahedral_wire[24] = {
+ 0, 1, 1, 5, 5, 3, 3, 0,
+ 0, 4, 4, 5, 5, 2, 2, 0,
+ 1, 2, 2, 3, 3, 4, 4, 1,
+};
static const unsigned int bone_octahedral_solid_tris[8][3] = {
{2, 1, 0}, /* bottom */
@@ -480,70 +578,78 @@ static const float bone_octahedral_solid_normals[8][3] = {
static void draw_bone_octahedral(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- /* Section 1, sides */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
- glDrawElements(GL_LINE_LOOP,
- sizeof(bone_octahedral_wire_sides) / sizeof(*bone_octahedral_wire_sides),
- GL_UNSIGNED_INT,
- bone_octahedral_wire_sides);
-
- /* Section 1, square */
- glDrawElements(GL_LINE_LOOP,
- sizeof(bone_octahedral_wire_square) / sizeof(*bone_octahedral_wire_square),
- GL_UNSIGNED_INT,
- bone_octahedral_wire_square);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glEndList();
+ static Gwn_VertFormat format = {0};
+ static Gwn_VertBuf vbo = {{0}};
+ static Gwn_IndexBufBuilder elb = {0};
+ static Gwn_IndexBuf el = {0};
+ static Gwn_Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ /* Elements */
+ GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 6);
+ for (int i = 0; i < 12; ++i) {
+ GWN_indexbuf_add_line_verts(&elb, bone_octahedral_wire[i * 2], bone_octahedral_wire[i * 2 + 1]);
+ }
+ GWN_indexbuf_build_in_place(&elb, &el);
+
+ /* Vertices */
+ GWN_vertbuf_init_with_format(&vbo, &format);
+ GWN_vertbuf_data_alloc(&vbo, 6);
+ for (int i = 0; i < 6; ++i) {
+ GWN_vertbuf_attr_set(&vbo, pos, i, bone_octahedral_verts[i]);
+ }
+
+ GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glCallList(displist);
-}
+ GWN_batch_program_use_begin(&batch);
+ GWN_batch_uniform_4fv(&batch, "color", fcolor);
+ GWN_batch_draw(&batch);
+}
static void draw_bone_solid_octahedral(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- int i;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
-#if 1
- glBegin(GL_TRIANGLES);
- for (i = 0; i < 8; i++) {
- glNormal3fv(bone_octahedral_solid_normals[i]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
- }
-
- glEnd();
-
-#else /* not working because each vert needs a different normal */
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
- glNormalPointer(GL_FLOAT, 0, bone_octahedral_solid_normals);
- glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
- glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris) / sizeof(unsigned int),
- GL_UNSIGNED_INT, bone_octahedral_solid_tris);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-#endif
+ static Gwn_VertFormat format = {0};
+ static Gwn_VertBuf vbo = {{0}};
+ static Gwn_Batch batch = {{0}};
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ if (format.attrib_ct == 0) {
+ unsigned int v_idx = 0;
+ /* Vertex format */
+ unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ /* Vertices */
+ GWN_vertbuf_init_with_format(&vbo, &format);
+ GWN_vertbuf_data_alloc(&vbo, 24);
+
+ for (int i = 0; i < 8; i++) {
+ add_solid_flat_triangle(&vbo, &v_idx, pos, nor,
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][0]],
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][1]],
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][2]],
+ bone_octahedral_solid_normals[i]);
+ }
- glEndList();
+ GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL);
}
- glCallList(displist);
-}
+ if (flat_color) {
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ /* TODO replace with good default lighting shader ? */
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3fv(&batch, "light", light_vec);
+ }
+ GWN_batch_uniform_4fv(&batch, "color", fcolor);
+ GWN_batch_draw(&batch);
+}
/* *************** Armature drawing, bones ******************* */
@@ -557,15 +663,20 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_ROOTSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
}
else {
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
if (dt > OB_WIRE)
@@ -580,24 +691,29 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
}
else {
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
- glTranslatef(0.0f, 1.0f, 0.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(0.0f, 1.0f);
if (dt > OB_WIRE)
draw_bonevert_solid();
else
draw_bonevert();
- glTranslatef(0.0f, -1.0f, 0.0f);
-
+ gpuPopMatrix();
}
/* 16 values of sin function (still same result!) */
@@ -696,8 +812,13 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
//mul_v3_fl(dirvec, head);
cross_v3_v3v3(norvec, dirvec, imat[2]);
-
- glBegin(GL_QUAD_STRIP);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immBegin(GWN_PRIM_TRI_STRIP, 66);
+ immUniformColor4ub(255, 255, 255, 50);
for (a = 0; a < 16; a++) {
vec[0] = -si[a] * dirvec[0] + co[a] * norvec[0];
@@ -707,10 +828,8 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, headvec, vec, head);
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
- glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
}
for (a = 15; a >= 0; a--) {
@@ -721,10 +840,8 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, tailvec, vec, tail);
madd_v3_v3v3fl(vec2, tailvec, vec, tail + dist);
- //glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
}
/* make it cyclic... */
@@ -735,12 +852,11 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, headvec, vec, head);
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
- //glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
@@ -752,6 +868,11 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
{
float head, tail /*, length*/;
float *headvec, *tailvec, dirvec[3];
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
/* figure out the sizes of spheres */
if (ebone) {
@@ -780,35 +901,49 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
/* sphere root color */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_ROOTSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
-
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
+
+ immUniformColor4fv(fcolor);
+
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
GPU_select_load_id(id | BONESEL_ROOT);
- drawcircball(GL_LINE_LOOP, headvec, head, imat);
+ imm_drawcircball(headvec, head, imat, pos);
}
/* Draw tip point */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
if (id != -1)
GPU_select_load_id(id | BONESEL_TIP);
- drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
+ imm_drawcircball(tailvec, tail, imat, pos);
/* base */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
- else UI_ThemeColor(TH_WIRE_EDIT);
+ if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColor4fv(TH_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
+ }
}
sub_v3_v3v3(dirvec, tailvec, headvec);
@@ -834,34 +969,40 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
if (id != -1)
GPU_select_load_id(id | BONESEL_BONE);
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 4);
add_v3_v3v3(vec, headvec, norvech);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
add_v3_v3v3(vec, tailvec, norvect);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
sub_v3_v3v3(vec, headvec, norvech);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
sub_v3_v3v3(vec, tailvec, norvect);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
- glEnd();
+ immEnd();
}
+
+ immUnbindProgram();
}
/* does wire only for outline selecting */
static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
- GLUquadricObj *qobj;
+ Gwn_Batch *sphere = GPU_batch_preset_sphere(1);
float head, tail, length;
- float fac1, fac2;
-
- glPushMatrix();
- qobj = gluNewQuadric();
+ float fac1, fac2, size1, size2;
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ /* dt is always OB_SOlID */
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3fv(sphere, "light", light_vec);
+
+ gpuPushMatrix();
/* figure out the sizes of spheres */
if (ebone) {
@@ -882,110 +1023,124 @@ static void draw_sphere_bone(const short dt, int armflag, int boneflag, short co
}
/* move to z-axis space */
- glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
+ gpuRotateAxis(-90.0f, 'X');
- if (dt == OB_SOLID) {
- /* set up solid drawing */
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
- }
- else {
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- }
-
/* sphere root color */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_ROOTSEL)
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag);
else if (dt == OB_SOLID)
- UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
GPU_select_load_id(id | BONESEL_ROOT);
- gluSphere(qobj, head, 16, 10);
+ gpuPushMatrix();
+ gpuScaleUniform(head);
+ GWN_batch_uniform_4fv(sphere, "color", fcolor);
+ GWN_batch_draw(sphere);
+ gpuPopMatrix();
}
/* Draw tip point */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
}
if (id != -1)
GPU_select_load_id(id | BONESEL_TIP);
- glTranslatef(0.0f, 0.0f, length);
- gluSphere(qobj, tail, 16, 10);
- glTranslatef(0.0f, 0.0f, -length);
+ gpuTranslate3f(0.0f, 0.0f, length);
+
+ gpuPushMatrix();
+ gpuScaleUniform(tail);
+ GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */
+ GWN_batch_uniform_4fv(sphere, "color", fcolor);
+ GWN_batch_draw(sphere);
+ gpuPopMatrix();
+
+ gpuTranslate3f(0.0f, 0.0f, -length);
/* base */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
- else UI_ThemeColor(TH_BONE_SOLID);
+ if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag);
else if (dt == OB_SOLID)
- UI_ThemeColor(TH_BONE_SOLID);
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+
+ GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */
+ GWN_batch_uniform_4fv(sphere, "color", fcolor);
fac1 = (length - head) / length;
fac2 = (length - tail) / length;
if (length > (head + tail)) {
+ size1 = fac2 * tail + (1.0f - fac2) * head;
+ size2 = fac1 * head + (1.0f - fac1) * tail;
+
if (id != -1)
GPU_select_load_id(id | BONESEL_BONE);
+ /* draw sphere on extrema */
+ gpuPushMatrix();
+ gpuTranslate3f(0.0f, 0.0f, length - tail);
+ gpuScaleUniform(size1);
+
+ GWN_batch_draw(sphere);
+ gpuPopMatrix();
+
+ gpuPushMatrix();
+ gpuTranslate3f(0.0f, 0.0f, head);
+ gpuScaleUniform(size2);
+
+ GWN_batch_draw(sphere);
+ gpuPopMatrix();
+
+ /* draw cynlinder between spheres */
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -1.0f);
-
- glTranslatef(0.0f, 0.0f, head);
- gluCylinder(qobj, fac1 * head + (1.0f - fac1) * tail, fac2 * tail + (1.0f - fac2) * head, length - head - tail, 16, 1);
- glTranslatef(0.0f, 0.0f, -head);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int nor = GWN_vertformat_attr_add(format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING);
+ immUniformColor4fv(fcolor);
+ immUniform3fv("light", light_vec);
+
+ gpuTranslate3f(0.0f, 0.0f, head);
+ imm_draw_cylinder_fill_normal_3d(pos, nor, size2, size1, length - head - tail, 16, 1);
+
+ immUnbindProgram();
glDisable(GL_POLYGON_OFFSET_FILL);
-
- /* draw sphere on extrema */
- glTranslatef(0.0f, 0.0f, length - tail);
- gluSphere(qobj, fac2 * tail + (1.0f - fac2) * head, 16, 10);
- glTranslatef(0.0f, 0.0f, -length + tail);
-
- glTranslatef(0.0f, 0.0f, head);
- gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
}
else {
+ size1 = fac1 * head + (1.0f - fac1) * tail;
+
/* 1 sphere in center */
- glTranslatef(0.0f, 0.0f, (head + length - tail) / 2.0f);
- gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
- }
-
- /* restore */
- if (dt == OB_SOLID) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ gpuTranslate3f(0.0f, 0.0f, (head + length - tail) / 2.0f);
+
+ gpuScaleUniform(size1);
+ GWN_batch_draw(sphere);
}
- glPopMatrix();
- gluDeleteQuadric(qobj);
+ gpuPopMatrix();
}
-static GLubyte bm_dot6[] = {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0};
-static GLubyte bm_dot8[] = {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C};
-
-static GLubyte bm_dot5[] = {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0};
-static GLubyte bm_dot7[] = {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38};
-
-
static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
- /* call this once, avoid constant changing */
- BLI_assert(glaGetOneInt(GL_UNPACK_ALIGNMENT) == 1);
-
float length;
if (pchan)
@@ -993,103 +1148,119 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
else
length = ebone->length;
- glPushMatrix();
- glScalef(length, length, length);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ gpuPushMatrix();
+ gpuScaleUniform(length);
/* this chunk not in object mode */
if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) {
glLineWidth(4.0f);
- if (G.f & G_PICKSEL) {
- /* no bitmap in selection mode, crashes 3d cards...
- * instead draw a solid point the same size */
- glPointSize(8.0f);
- }
+ glPointSize(8.0f);
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else if (armflag & ARM_EDITMODE) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
}
-
+
+ /* line */
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
+ if (id != -1)
+ GPU_select_load_id(id | BONESEL_BONE);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
- if (G.f & G_PICKSEL) {
+ if (G.f & G_PICKSEL)
GPU_select_load_id(id | BONESEL_ROOT);
- glBegin(GL_POINTS);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glEnd();
- }
- else {
- glRasterPos3f(0.0f, 0.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot8);
- }
+
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
}
-
- if (id != -1)
- GPU_select_load_id((GLuint) id | BONESEL_BONE);
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
-
+
/* tip */
- if (G.f & G_PICKSEL) {
- /* no bitmap in selection mode, crashes 3d cards... */
+ if (G.f & G_PICKSEL)
GPU_select_load_id(id | BONESEL_TIP);
- glBegin(GL_POINTS);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
- }
- else {
- glRasterPos3f(0.0f, 1.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot7);
- }
-
+
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+
/* further we send no names */
if (id != -1)
GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_LINEBONE, boneflag, constflag);
}
-
- glLineWidth(2.0);
-
+
+ /* Now draw the inner color */
+ glLineWidth(2.0f);
+ glPointSize(5.0f);
+
+ /* line */
+ if (armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor);
+ else UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+
/*Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
- if ((G.f & G_PICKSEL) == 0) {
- /* no bitmap in selection mode, crashes 3d cards... */
- if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
- }
- glRasterPos3f(0.0f, 0.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot6);
+ if (armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_ROOTSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_VERTEX, fcolor);
}
+ immUniformColor4fv(fcolor);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
}
-
- if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT);
- else UI_ThemeColorShade(TH_BACK, -30);
- }
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
-
+
/* tip */
if ((G.f & G_PICKSEL) == 0) {
/* no bitmap in selection mode, crashes 3d cards... */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_VERTEX, fcolor);
}
- glRasterPos3f(0.0f, 1.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot5);
+ immUniformColor4fv(fcolor);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immEnd();
}
-
- glPopMatrix();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
}
/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings
@@ -1188,18 +1359,16 @@ static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, EditBone *ebo
}
for (a = 0; a < segments; a++) {
- glPushMatrix();
- glMultMatrixf(bbone[a].mat);
+ gpuPushMatrix();
+ gpuMultMatrix(bbone[a].mat);
if (dt == OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
else drawcube_size(xwidth, dlen, zwidth);
- glPopMatrix();
+ gpuPopMatrix();
}
}
else {
- glPushMatrix();
if (dt == OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
else drawcube_size(xwidth, length, zwidth);
- glPopMatrix();
}
}
@@ -1222,26 +1391,27 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
/* draw points only if... */
if (armflag & ARM_EDITMODE) {
/* move to unitspace */
- glPushMatrix();
- glScalef(length, length, length);
+ gpuPushMatrix();
+ gpuScaleUniform(length);
draw_bone_points(dt, armflag, boneflag, id);
- glPopMatrix();
+ gpuPopMatrix();
length *= 0.95f; /* make vertices visible */
}
/* colors for modes */
if (armflag & ARM_POSEMODE) {
if (dt <= OB_WIRE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
}
else if (armflag & ARM_EDITMODE) {
if (dt == OB_WIRE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
- else
- UI_ThemeColor(TH_BONE_SOLID);
}
if (id != -1) {
@@ -1250,33 +1420,31 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
/* set up solid drawing */
if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
+ flat_color = false;
draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth);
-
- /* disable solid drawing */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
}
else {
/* wire */
if (armflag & ARM_POSEMODE) {
if (constflag && ((G.f & G_PICKSEL) == 0)) {
/* set constraint colors */
- if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
+ if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
glEnable(GL_BLEND);
+ flat_color = true;
draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth);
glDisable(GL_BLEND);
}
/* restore colors */
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
}
@@ -1286,33 +1454,41 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments)
{
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
if ((segments > 1) && (pchan)) {
float dlen = length / (float)segments;
Mat4 *bbone = bbones;
int a;
-
+
for (a = 0; a < segments; a++, bbone++) {
- glPushMatrix();
- glMultMatrixf(bbone->mat);
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, dlen, 0.0f);
- glEnd(); /* GL_LINES */
-
- glPopMatrix();
+ gpuPushMatrix();
+ gpuMultMatrix(bbone->mat);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immVertex3f(pos, 0.0f, dlen, 0.0f);
+ immEnd();
+
+ gpuPopMatrix();
}
}
else {
- glPushMatrix();
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, length, 0.0f);
- glEnd();
-
- glPopMatrix();
+ gpuPushMatrix();
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immVertex3f(pos, 0.0f, length, 0.0f);
+ immEnd();
+
+ gpuPopMatrix();
}
+
+ immUnbindProgram();
}
static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
@@ -1338,10 +1514,11 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
/* draw points only if... */
if (armflag & ARM_EDITMODE) {
/* move to unitspace */
- glPushMatrix();
- glScalef(length, length, length);
+ gpuPushMatrix();
+ gpuScaleUniform(length);
+ flat_color = true;
draw_bone_points(dt, armflag, boneflag, id);
- glPopMatrix();
+ gpuPopMatrix();
length *= 0.95f; /* make vertices visible */
}
@@ -1359,10 +1536,10 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
/* colors for modes */
if (armflag & ARM_POSEMODE) {
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
else if (armflag & ARM_EDITMODE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
}
/* draw normal */
@@ -1372,23 +1549,23 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length)
{
- /* Draw a 3d octahedral bone, we use normalized space based on length,
- * for display-lists */
-
- glScalef(length, length, length);
+ /* Draw a 3d octahedral bone, we use normalized space based on length */
+ gpuScaleUniform(length);
/* set up solid drawing */
if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- UI_ThemeColor(TH_BONE_SOLID);
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ flat_color = false;
}
+ else
+ flat_color = true;
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
if (dt <= OB_WIRE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
}
@@ -1403,12 +1580,12 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
if (dt <= OB_WIRE) {
/* colors */
if (armflag & ARM_EDITMODE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
}
else if (armflag & ARM_POSEMODE) {
if (constflag && ((G.f & G_PICKSEL) == 0)) {
/* draw constraint colors */
- if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
+ if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
glEnable(GL_BLEND);
draw_bone_solid_octahedral();
@@ -1417,7 +1594,7 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
}
/* restore colors */
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
}
draw_bone_octahedral();
@@ -1425,35 +1602,33 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
else {
/* solid */
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
else
- UI_ThemeColor(TH_BONE_SOLID);
- draw_bone_solid_octahedral();
- }
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
- /* disable solid drawing */
- if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ draw_bone_solid_octahedral();
}
}
-static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
- const short dt, int armflag, int boneflag, unsigned int id, float length)
+static void draw_custom_bone(
+ const struct EvaluationContext *eval_ctx,
+ Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob,
+ const short dt, int armflag, int boneflag, unsigned int id, float length)
{
if (ob == NULL) return;
- glScalef(length, length, length);
+ gpuScaleUniform(length);
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, 0);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, 0);
}
if (id != -1) {
GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
-
- draw_object_instance(scene, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE);
+
+ draw_object_instance(eval_ctx, scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor);
}
@@ -1461,7 +1636,20 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
{
bConstraint *con;
bPoseChannel *parchan;
-
+
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4fv(fcolor);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
for (con = pchan->constraints.first; con; con = con->next) {
if (con->enforce == 0.0f)
continue;
@@ -1471,47 +1659,45 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
{
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
int segcount = 0;
+ float ik_tip[3];
/* if only_temp, only draw if it is a temporary ik-chain */
if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP))
continue;
-
- setlinestyle(3);
- glBegin(GL_LINES);
-
+
/* exclude tip from chain? */
if ((data->flag & CONSTRAINT_IK_TIP) == 0)
parchan = pchan->parent;
else
parchan = pchan;
- glVertex3fv(parchan->pose_tail);
+ copy_v3_v3(ik_tip, parchan->pose_tail);
/* Find the chain's root */
while (parchan->parent) {
segcount++;
- if (segcount == data->rootbone || segcount > 255) {
- break; /* 255 is weak */
- }
+ /* FIXME: revise the breaking conditions */
+ if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */
parchan = parchan->parent;
}
- if (parchan)
- glVertex3fv(parchan->pose_head);
+
+ if (parchan) {
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, ik_tip);
+ immVertex3fv(shdr_pos, parchan->pose_head);
+ immEnd();
+ }
- glEnd();
- setlinestyle(0);
break;
}
case CONSTRAINT_TYPE_SPLINEIK:
{
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
int segcount = 0;
-
- setlinestyle(3);
- glBegin(GL_LINES);
+ float ik_tip[3];
parchan = pchan;
- glVertex3fv(parchan->pose_tail);
+ copy_v3_v3(ik_tip, parchan->pose_tail);
/* Find the chain's root */
while (parchan->parent) {
@@ -1521,18 +1707,21 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
parchan = parchan->parent;
}
/* Only draw line in case our chain is more than one bone long! */
- if (parchan != pchan) /* XXX revise the breaking conditions to only stop at the tail? */
- glVertex3fv(parchan->pose_head);
-
- glEnd();
- setlinestyle(0);
+ if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, ik_tip);
+ immVertex3fv(shdr_pos, parchan->pose_head);
+ immEnd();
+ }
break;
}
}
}
+
+ immUnbindProgram();
}
-static void bgl_sphere_project(float ax, float az)
+static void imm_sphere_project(unsigned int pos, float ax, float az)
{
float dir[3], sine, q3;
@@ -1543,11 +1732,13 @@ static void bgl_sphere_project(float ax, float az)
dir[1] = 1.0f - 2.0f * sine;
dir[2] = ax * q3;
- glVertex3fv(dir);
+ immVertex3fv(pos, dir);
}
-static void draw_dof_ellipse(float ax, float az)
+static void draw_dof_ellipse(unsigned int pos, float ax, float az)
{
+ const int n = 16;
+ const int tri = n * n - 2 * n + 1; /* Yay fancy math ! */
const float staticSine[16] = {
0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f,
0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f,
@@ -1556,15 +1747,15 @@ static void draw_dof_ellipse(float ax, float az)
0.994521895368f, 1.0f
};
- int i, j, n = 16;
+ int i, j;
float x, z, px, pz;
glEnable(GL_BLEND);
glDepthMask(0);
- glColor4ub(70, 70, 70, 50);
+ immUniformColor4ub(70, 70, 70, 50);
- glBegin(GL_QUADS);
+ immBegin(GWN_PRIM_TRIS, tri * 3);
pz = 0.0f;
for (i = 1; i < n; i++) {
z = staticSine[i];
@@ -1574,36 +1765,35 @@ static void draw_dof_ellipse(float ax, float az)
x = staticSine[j];
if (j == n - i) {
- glEnd();
- glBegin(GL_TRIANGLES);
- bgl_sphere_project(ax * px, az * z);
- bgl_sphere_project(ax * px, az * pz);
- bgl_sphere_project(ax * x, az * pz);
- glEnd();
- glBegin(GL_QUADS);
+ imm_sphere_project(pos, ax * px, az * z);
+ imm_sphere_project(pos, ax * px, az * pz);
+ imm_sphere_project(pos, ax * x, az * pz);
}
else {
- bgl_sphere_project(ax * x, az * z);
- bgl_sphere_project(ax * x, az * pz);
- bgl_sphere_project(ax * px, az * pz);
- bgl_sphere_project(ax * px, az * z);
+ imm_sphere_project(pos, ax * x, az * z);
+ imm_sphere_project(pos, ax * x, az * pz);
+ imm_sphere_project(pos, ax * px, az * pz);
+
+ imm_sphere_project(pos, ax * px, az * pz);
+ imm_sphere_project(pos, ax * px, az * z);
+ imm_sphere_project(pos, ax * x, az * z);
}
px = x;
}
pz = z;
}
- glEnd();
+ immEnd();
glDisable(GL_BLEND);
glDepthMask(1);
- glColor3ub(0, 0, 0);
+ immUniformColor3ub(0, 0, 0);
- glBegin(GL_LINE_STRIP);
+ immBegin(GWN_PRIM_LINE_STRIP, n);
for (i = 0; i < n; i++)
- bgl_sphere_project(staticSine[n - i - 1] * ax, staticSine[i] * az);
- glEnd();
+ imm_sphere_project(pos, staticSine[n - i - 1] * ax, staticSine[i] * az);
+ immEnd();
}
static void draw_pose_dofs(Object *ob)
@@ -1611,7 +1801,12 @@ static void draw_pose_dofs(Object *ob)
bArmature *arm = ob->data;
bPoseChannel *pchan;
Bone *bone;
-
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
@@ -1625,54 +1820,55 @@ static void draw_pose_dofs(Object *ob)
int a, i;
/* in parent-bone pose, but own restspace */
- glPushMatrix();
+ gpuPushMatrix();
copy_v3_v3(posetrans, pchan->pose_mat[3]);
- glTranslate3fv(posetrans);
+ gpuTranslate3fv(posetrans);
if (pchan->parent) {
copy_m4_m4(mat, pchan->parent->pose_mat);
mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
}
copy_m4_m3(mat, pchan->bone->bone_mat);
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
scale = bone->length * pchan->size[1];
- glScalef(scale, scale, scale);
+ gpuScaleUniform(scale);
- if (pchan->ikflag & BONE_IK_XLIMIT) {
- if (pchan->ikflag & BONE_IK_ZLIMIT) {
- float amin[3], amax[3];
-
- for (i = 0; i < 3; i++) {
- /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
- amin[i] = sinf(pchan->limitmin[i] * 0.5f);
- amax[i] = sinf(pchan->limitmax[i] * 0.5f);
- }
-
- glScalef(1.0f, -1.0f, 1.0f);
- if ((amin[0] != 0.0f) && (amin[2] != 0.0f))
- draw_dof_ellipse(amin[0], amin[2]);
- if ((amin[0] != 0.0f) && (amax[2] != 0.0f))
- draw_dof_ellipse(amin[0], amax[2]);
- if ((amax[0] != 0.0f) && (amin[2] != 0.0f))
- draw_dof_ellipse(amax[0], amin[2]);
- if ((amax[0] != 0.0f) && (amax[2] != 0.0f))
- draw_dof_ellipse(amax[0], amax[2]);
- glScalef(1.0f, -1.0f, 1.0f);
+ if (((pchan->ikflag & BONE_IK_XLIMIT) != 0) &&
+ ((pchan->ikflag & BONE_IK_ZLIMIT) != 0))
+ {
+ float amin[3], amax[3];
+
+ for (i = 0; i < 3; i++) {
+ /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
+ amin[i] = sinf(pchan->limitmin[i] * 0.5f);
+ amax[i] = sinf(pchan->limitmax[i] * 0.5f);
}
+
+ gpuScale3f(1.0f, -1.0f, 1.0f);
+ if ((amin[0] != 0.0f) && (amin[2] != 0.0f))
+ draw_dof_ellipse(pos, amin[0], amin[2]);
+ if ((amin[0] != 0.0f) && (amax[2] != 0.0f))
+ draw_dof_ellipse(pos, amin[0], amax[2]);
+ if ((amax[0] != 0.0f) && (amin[2] != 0.0f))
+ draw_dof_ellipse(pos, amax[0], amin[2]);
+ if ((amax[0] != 0.0f) && (amax[2] != 0.0f))
+ draw_dof_ellipse(pos, amax[0], amax[2]);
+ gpuScale3f(1.0f, -1.0f, 1.0f); /* XXX same as above, is this intentional? */
}
/* arcs */
if (pchan->ikflag & BONE_IK_ZLIMIT) {
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
theta = RAD2DEGF(0.5f * (pchan->limitmin[2] + pchan->limitmax[2]));
- glRotatef(theta, 0.0f, 0.0f, 1.0f);
+ gpuPushMatrix();
+ gpuRotateAxis(theta, 'Z');
- glColor3ub(50, 50, 255); /* blue, Z axis limit */
- glBegin(GL_LINE_STRIP);
+ immUniformColor3ub(50, 50, 255); /* blue, Z axis limit */
+ immBegin(GWN_PRIM_LINE_STRIP, 33);
for (a = -16; a <= 16; a++) {
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
float fac = ((float)a) / 16.0f * 0.5f;
@@ -1683,20 +1879,21 @@ static void draw_pose_dofs(Object *ob)
corner[i][0] = sinf(phi);
corner[i][1] = cosf(phi);
corner[i][2] = 0.0f;
- glVertex3fv(corner[i]);
+ immVertex3fv(pos, corner[i]);
}
- glEnd();
+ immEnd();
- glRotatef(-theta, 0.0f, 0.0f, 1.0f);
+ gpuPopMatrix();
}
if (pchan->ikflag & BONE_IK_XLIMIT) {
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
theta = RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0]));
- glRotatef(theta, 1.0f, 0.0f, 0.0f);
+ gpuPushMatrix();
+ gpuRotateAxis(theta, 'X');
- glColor3ub(255, 50, 50); /* Red, X axis limit */
- glBegin(GL_LINE_STRIP);
+ immUniformColor3ub(255, 50, 50); /* Red, X axis limit */
+ immBegin(GWN_PRIM_LINE_STRIP, 33);
for (a = -16; a <= 16; a++) {
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
float fac = ((float)a) / 16.0f * 0.5f;
@@ -1706,21 +1903,23 @@ static void draw_pose_dofs(Object *ob)
corner[i][0] = 0.0f;
corner[i][1] = sinf(phi);
corner[i][2] = cosf(phi);
- glVertex3fv(corner[i]);
+ immVertex3fv(pos, corner[i]);
}
- glEnd();
+ immEnd();
- glRotatef(-theta, 1.0f, 0.0f, 0.0f);
+ gpuPopMatrix();
}
/* out of cone, out of bone */
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
}
}
}
+
+ immUnbindProgram();
}
static void bone_matrix_translate_y(float mat[4][4], float y)
@@ -1733,9 +1932,10 @@ static void bone_matrix_translate_y(float mat[4][4], float y)
}
/* assumes object is Armature with pose */
-static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const unsigned char ob_wire_col[4],
- const bool do_const_color, const bool is_outline)
+static void draw_pose_bones(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const unsigned char ob_wire_col[4],
+ const bool do_const_color, const bool is_outline)
{
RegionView3D *rv3d = ar->regiondata;
Object *ob = base->object;
@@ -1756,7 +1956,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* being set below */
arm->layer_used = 0;
-
+
+ rgba_uchar_to_float(fcolor, ob_wire_col);
+
/* precalc inverse matrix for drawing screen aligned */
if (arm->drawtype == ARM_ENVELOPE) {
/* precalc inverse matrix for drawing screen aligned */
@@ -1805,7 +2007,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* if solid we draw that first, with selection codes, but without names, axes etc */
if (dt > OB_WIRE) {
if (arm->flag & ARM_POSEMODE)
- index = base->selcol;
+ index = base->object->select_color;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
@@ -1817,13 +2019,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
{
if (bone->layer & arm->layer) {
const bool use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
- glPushMatrix();
+ gpuPushMatrix();
if (use_custom && pchan->custom_tx) {
- glMultMatrixf(pchan->custom_tx->pose_mat);
+ gpuMultMatrix(pchan->custom_tx->pose_mat);
}
else {
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
}
/* catch exception for bone with hidden parent */
@@ -1858,7 +2060,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glDisable(GL_CULL_FACE);
}
- draw_custom_bone(scene, v3d, rv3d, pchan->custom,
+ draw_custom_bone(eval_ctx, scene, sl, v3d, rv3d, pchan->custom,
OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
}
}
@@ -1885,7 +2087,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -1913,7 +2115,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
(draw_wire || (dt <= OB_WIRE)) )
{
if (arm->flag & ARM_POSEMODE)
- index = base->selcol;
+ index = base->object->select_color;
/* only draw custom bone shapes that need to be drawn as wires */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -1926,13 +2128,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (bone->layer & arm->layer) {
if (pchan->custom) {
if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
- glPushMatrix();
+ gpuPushMatrix();
if (pchan->custom_tx) {
- glMultMatrixf(pchan->custom_tx->pose_mat);
+ gpuMultMatrix(pchan->custom_tx->pose_mat);
}
else {
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
}
/* prepare colors */
@@ -1942,7 +2144,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
else if (arm->flag & ARM_POSEMODE)
set_pchan_colorset(ob, pchan);
else {
- glColor3ubv(ob_wire_col);
+ rgba_uchar_to_float(fcolor, ob_wire_col);
}
/* catch exception for bone with hidden parent */
@@ -1954,10 +2156,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (bone == arm->act_bone)
flag |= BONE_DRAW_ACTIVE;
- draw_custom_bone(scene, v3d, rv3d, pchan->custom,
+ draw_custom_bone(eval_ctx, scene, sl, v3d, rv3d, pchan->custom,
OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -1979,7 +2181,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* draw line check first. we do selection indices */
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
if (arm->flag & ARM_POSEMODE)
- index = base->selcol;
+ index = base->object->select_color;
}
/* if solid && posemode, we draw again with polygonoffset */
else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) {
@@ -1988,7 +2190,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
else {
/* and we use selection indices if not done yet */
if (arm->flag & ARM_POSEMODE)
- index = base->selcol;
+ index = base->object->select_color;
}
if (is_cull_enabled == false) {
@@ -2011,16 +2213,30 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
* - only if V3D_HIDE_HELPLINES is enabled...
*/
if ((do_dashed & DASH_HELP_LINES) && ((bone->flag & BONE_CONNECTED) == 0)) {
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4fv(fcolor);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
if (arm->flag & ARM_POSEMODE) {
GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */
- UI_ThemeColor(TH_WIRE);
+ immUniformThemeColor(TH_WIRE);
}
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(pchan->pose_head);
- glVertex3fv(pchan->parent->pose_tail);
- glEnd();
- setlinestyle(0);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, pchan->parent->pose_tail);
+ immVertex3fv(shdr_pos, pchan->pose_head);
+ immEnd();
+
+ immUnbindProgram();
}
/* Draw a line to IK root bone
@@ -2029,8 +2245,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (arm->flag & ARM_POSEMODE) {
if (constflag & PCHAN_HAS_IK) {
if (bone->flag & BONE_SELECTED) {
- if (constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
- else glColor3ub(200, 200, 50); /* add theme! */
+ if (constflag & PCHAN_HAS_TARGET) {
+ rgba_float_args_set(fcolor, 200.f / 255.f, 120.f / 255.f, 0.f / 255.f, 1.0f);
+ }
+ /* add theme! */
+ else rgba_float_args_set(fcolor, 200.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f);
GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES));
@@ -2038,8 +2257,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (constflag & PCHAN_HAS_SPLINEIK) {
if (bone->flag & BONE_SELECTED) {
- glColor3ub(150, 200, 50); /* add theme! */
-
+ /* add theme! */
+ rgba_float_args_set(fcolor, 150.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f);
+
GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES));
}
@@ -2047,9 +2267,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
- glPushMatrix();
+ gpuPushMatrix();
if (arm->drawtype != ARM_ENVELOPE)
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
/* catch exception for bone with hidden parent */
flag = bone->flag;
@@ -2086,7 +2306,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
else
draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -2106,7 +2326,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* draw DoFs */
if (arm->flag & ARM_POSEMODE) {
- if (((base->flag & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
+ if (((base->flag_legacy & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
draw_pose_dofs(ob);
}
}
@@ -2114,26 +2334,17 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* finally names and axes */
if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) &&
(is_outline == 0) &&
- ((base->flag & OB_FROMDUPLI) == 0))
+ ((base->flag_legacy & OB_FROMDUPLI) == 0))
{
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
if ((G.f & G_PICKSEL) == 0) {
float vec[3];
unsigned char col[4];
- if (do_const_color) {
- /* so we can draw bone names in current const color */
- float tcol[4];
- glGetFloatv(GL_CURRENT_COLOR, tcol);
- rgb_float_to_uchar(col, tcol);
- col[3] = 255;
- }
- else {
- col[0] = ob_wire_col[0];
- col[1] = ob_wire_col[1];
- col[2] = ob_wire_col[2];
- col[3] = 255;
- }
+ col[0] = ob_wire_col[0];
+ col[1] = ob_wire_col[1];
+ col[2] = ob_wire_col[2];
+ col[3] = 255;
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
@@ -2156,18 +2367,16 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* Draw additional axes on the bone tail */
if ((arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE)) {
- glPushMatrix();
+ gpuPushMatrix();
copy_m4_m4(bmat, pchan->pose_mat);
bone_matrix_translate_y(bmat, pchan->bone->length);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
- glColor3ubv(col);
-
float viewmat_pchan[4][4];
mul_m4_m4m4(viewmat_pchan, rv3d->viewmatob, bmat);
- drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS);
+ drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS, col);
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -2233,9 +2442,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
/* catch exception for bone with hidden parent */
flag = eBone->flag;
@@ -2257,7 +2466,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -2295,9 +2504,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
}
else {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
@@ -2308,21 +2517,32 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
else
draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
- glPopMatrix();
+ gpuPopMatrix();
}
/* offset to parent */
if (eBone->parent) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
GPU_select_load_id(-1); /* -1 here is OK! */
- setlinestyle(3);
-
- glBegin(GL_LINES);
- glVertex3fv(eBone->parent->tail);
- glVertex3fv(eBone->head);
- glEnd();
-
- setlinestyle(0);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformThemeColor(TH_WIRE_EDIT);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, eBone->parent->tail);
+ immVertex3fv(shdr_pos, eBone->head);
+ immEnd();
+
+ immUnbindProgram();
}
}
}
@@ -2364,18 +2584,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
}
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
bone_matrix_translate_y(bmat, eBone->length);
- glMultMatrixf(bmat);
-
- glColor3ubv(col);
+ gpuMultMatrix(bmat);
float viewmat_ebone[4][4];
mul_m4_m4m4(viewmat_ebone, rv3d->viewmatob, bmat);
- drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS);
+ drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS, col);
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -2448,7 +2666,8 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
/* draw ghosts that occur within a frame range
* note: object should be in posemode
*/
-static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses_range(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2456,6 +2675,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
bPose *posen, *poseo;
float start, end, stepsize, range, colfac;
int cfrao, flago;
+ unsigned char col[4];
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2488,11 +2708,11 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
/* draw from first frame of range to last */
for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) {
colfac = (end - (float)CFRA) / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2514,7 +2734,9 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
-static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses_keys(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, Base *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2525,6 +2747,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
ActKeyColumn *ak, *akn;
float start, end, range, colfac, i;
int cfrao, flago;
+ unsigned char col[4];
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2566,13 +2789,13 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
/* draw from first frame of range to last */
for (ak = keys.first, i = 0; ak; ak = ak->next, i++) {
colfac = i / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
CFRA = (int)ak->cfra;
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2595,7 +2818,9 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
-static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, Base *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2603,7 +2828,8 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
bPose *posen, *poseo;
float cur, start, end, stepsize, range, colfac, actframe, ctime;
int cfrao, flago;
-
+ unsigned char col[4];
+
/* pre conditions, get an action with sufficient frames */
if (ELEM(NULL, adt, adt->action))
return;
@@ -2640,7 +2866,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
for (cur = stepsize; cur < range; cur += stepsize) {
ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
/* only within action range */
if (actframe + ctime >= start && actframe + ctime <= end) {
@@ -2648,14 +2874,14 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
/* only within action range */
if ((actframe - ctime >= start) && (actframe - ctime <= end)) {
@@ -2663,8 +2889,8 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
}
@@ -2689,9 +2915,10 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
/* called from drawobject.c, return true if nothing was drawn
* (ob_wire_col == NULL) when drawing ghost */
-bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4],
- const bool is_outline)
+bool draw_armature(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_outline)
{
Object *ob = base->object;
bArmature *arm = ob->data;
@@ -2700,11 +2927,7 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (v3d->flag2 & V3D_RENDER_OVERRIDE)
return true;
- /* needed for 'draw_line_bone' which draws pixel. */
- if (arm->drawtype == ARM_LINE) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- }
-
+#if 0 /* Not used until lighting is properly reimplemented */
if (dt > OB_WIRE) {
/* we use color for solid lighting */
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
@@ -2719,7 +2942,8 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); /* only for lighting... */
}
}
-
+#endif
+
/* arm->flag is being used to detect mode... */
/* editmode? */
if (arm->edbo) {
@@ -2736,7 +2960,7 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* drawing posemode selection indices or colors only in these cases */
- if (!(base->flag & OB_FROMDUPLI)) {
+ if (!(base->flag_legacy & OB_FROMDUPLI)) {
if (G.f & G_PICKSEL) {
#if 0
/* nifty but actually confusing to allow bone selection out of posemode */
@@ -2752,31 +2976,28 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (ob->mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
- draw_ghost_poses_range(scene, v3d, ar, base);
+ draw_ghost_poses_range(eval_ctx, scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_KEYS) {
- draw_ghost_poses_keys(scene, v3d, ar, base);
+ draw_ghost_poses_keys(eval_ctx, scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
- draw_ghost_poses(scene, v3d, ar, base);
+ draw_ghost_poses(eval_ctx, scene, sl, v3d, ar, base);
}
if ((dflag & DRAW_SCENESET) == 0) {
- if (ob == OBACT)
+ if (ob == OBACT(sl))
arm->flag |= ARM_POSEMODE;
- else if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
- if (ob == modifiers_isDeformedByArmature(OBACT))
+ else if (OBACT(sl) && (OBACT(sl)->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (ob == modifiers_isDeformedByArmature(OBACT(sl)))
arm->flag |= ARM_POSEMODE;
}
draw_pose_paths(scene, v3d, ar, ob);
}
}
}
- draw_pose_bones(scene, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
arm->flag &= ~ARM_POSEMODE;
-
- if (ob->mode & OB_MODE_POSE)
- UI_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */
}
else {
retval = true;
@@ -2785,9 +3006,5 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* restore */
glFrontFace(GL_CCW);
- if (arm->drawtype == ARM_LINE) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- }
-
return retval;
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index bbbf8c633bd..719fb6f764f 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -55,7 +55,6 @@
#include "BKE_editmesh.h"
#include "BKE_scene.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "UI_resources.h"
@@ -64,6 +63,7 @@
#include "GPU_material.h"
#include "GPU_basic_shader.h"
#include "GPU_shader.h"
+#include "GPU_matrix.h"
#include "RE_engine.h"
@@ -77,20 +77,6 @@ typedef struct drawMeshFaceSelect_userData {
BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */
} drawMeshFaceSelect_userData;
-typedef struct drawEMTFMapped_userData {
- BMEditMesh *em;
- bool has_mcol;
- int cd_poly_tex_offset;
- const MPoly *mpoly;
- const MTexPoly *mtexpoly;
-} drawEMTFMapped_userData;
-
-typedef struct drawTFace_userData {
- const Mesh *me;
- const MPoly *mpoly;
- const MTexPoly *mtexpoly;
-} drawTFace_userData;
-
/**************************** Face Select Mode *******************************/
/* mainly to be less confusing */
@@ -213,562 +199,6 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool d
/***************************** Texture Drawing ******************************/
-static Material *give_current_material_or_def(Object *ob, int matnr)
-{
- extern Material defmaterial; /* render module abuse... */
- Material *ma = give_current_material(ob, matnr);
-
- return ma ? ma : &defmaterial;
-}
-
-/* Icky globals, fix with userdata parameter */
-
-static struct TextureDrawState {
- Object *ob;
- Image *stencil; /* texture painting stencil */
- Image *canvas; /* texture painting canvas, for image mode */
- bool use_game_mat;
- int is_lit, is_tex;
- int color_profile;
- bool use_backface_culling;
- bool two_sided_lighting;
- unsigned char obcol[4];
- bool is_texpaint;
- bool texpaint_material; /* use material slots for texture painting */
-} Gtexdraw = {NULL, NULL, NULL, false, 0, 0, 0, false, false, {0, 0, 0, 0}, false, false};
-
-static bool set_draw_settings_cached(
- int clearcache, MTexPoly *texface, Material *ma,
- const struct TextureDrawState *gtexdraw)
-{
- static Material *c_ma;
- static int c_textured;
- static MTexPoly c_texface;
- static int c_backculled;
- static bool c_badtex;
- static int c_lit;
- static int c_has_texface;
-
- int backculled = 1;
- int alphablend = GPU_BLEND_SOLID;
- int textured = 0;
- int lit = 0;
- int has_texface = texface != NULL;
- bool need_set_tpage = false;
- bool texpaint = ((gtexdraw->ob->mode & OB_MODE_TEXTURE_PAINT) != 0);
-
- Image *ima = NULL;
-
- if (ma != NULL) {
- if (ma->mode & MA_TRANSP) {
- alphablend = GPU_BLEND_ALPHA;
- }
- }
-
- if (clearcache) {
- c_textured = c_lit = c_backculled = -1;
- memset(&c_texface, 0, sizeof(c_texface));
- c_badtex = false;
- c_has_texface = -1;
- c_ma = NULL;
- }
- else {
- textured = gtexdraw->is_tex;
- }
-
- /* convert number of lights into boolean */
- if (gtexdraw->is_lit) {
- lit = 1;
- }
-
- backculled = gtexdraw->use_backface_culling;
- if (ma) {
- if (ma->mode & MA_SHLESS) lit = 0;
- if (gtexdraw->use_game_mat) {
- backculled = backculled || (ma->game.flag & GEMAT_BACKCULL);
- alphablend = ma->game.alpha_blend;
- }
- }
-
- if (texface && !texpaint) {
- textured = textured && (texface->tpage);
-
- /* no material, render alpha if texture has depth=32 */
- if (!ma && BKE_image_has_alpha(texface->tpage))
- alphablend = GPU_BLEND_ALPHA;
- }
- else if (texpaint) {
- if (gtexdraw->texpaint_material)
- ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
- else
- ima = gtexdraw->canvas;
- }
- else
- textured = 0;
-
- if (backculled != c_backculled) {
- if (backculled) glEnable(GL_CULL_FACE);
- else glDisable(GL_CULL_FACE);
-
- c_backculled = backculled;
- }
-
- /* need to re-set tpage if textured flag changed or existsment of texface changed.. */
- need_set_tpage = textured != c_textured || has_texface != c_has_texface;
- /* ..or if settings inside texface were changed (if texface was used) */
- need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface)));
-
- if (need_set_tpage) {
- if (textured) {
- if (texpaint) {
- c_badtex = false;
- if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, 0, 1, 0, false)) {
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
-
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
- glActiveTexture(GL_TEXTURE0);
- }
- else {
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glActiveTexture(GL_TEXTURE0);
-
- c_badtex = true;
- GPU_clear_tpage(true);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- }
- else {
- c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend);
- }
- }
- else {
- GPU_set_tpage(NULL, 0, 0);
- c_badtex = false;
- }
- c_textured = textured;
- c_has_texface = has_texface;
- if (texface)
- memcpy(&c_texface, texface, sizeof(c_texface));
- }
-
- if (c_badtex) lit = 0;
- if (lit != c_lit || ma != c_ma || textured != c_textured) {
- int options = GPU_SHADER_USE_COLOR;
-
- if (c_textured && !c_badtex) {
- options |= GPU_SHADER_TEXTURE_2D;
- }
- if (gtexdraw->two_sided_lighting) {
- options |= GPU_SHADER_TWO_SIDED;
- }
-
- if (lit) {
- options |= GPU_SHADER_LIGHTING;
- if (!ma)
- ma = give_current_material_or_def(NULL, 0); /* default material */
-
- float specular[3];
- mul_v3_v3fl(specular, &ma->specr, ma->spec);
-
- GPU_basic_shader_colors(NULL, specular, ma->har, 1.0f);
- }
-
- GPU_basic_shader_bind(options);
-
- c_lit = lit;
- c_ma = ma;
- }
-
- return c_badtex;
-}
-
-static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
-{
- unsigned char obcol[4];
- bool is_tex, solidtex;
- Mesh *me = ob->data;
- ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
-
- /* XXX scene->obedit warning */
-
- /* texture draw is abused for mask selection mode, do this so wire draw
- * with face selection in weight paint is not lit. */
- if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
- solidtex = false;
- Gtexdraw.is_lit = 0;
- }
- else if ((ob->mode & OB_MODE_TEXTURE_PAINT) && BKE_scene_use_new_shading_nodes(scene)) {
- solidtex = true;
- if (v3d->flag2 & V3D_SHADELESS_TEX)
- Gtexdraw.is_lit = 0;
- else
- Gtexdraw.is_lit = -1;
- }
- else if ((v3d->drawtype == OB_SOLID) ||
- ((ob->mode & OB_MODE_EDIT) && (v3d->drawtype != OB_TEXTURE)))
- {
- /* draw with default lights in solid draw mode and edit mode */
- solidtex = true;
- Gtexdraw.is_lit = -1;
- }
- else {
- /* draw with lights in the scene otherwise */
- solidtex = false;
- if (v3d->flag2 & V3D_SHADELESS_TEX) {
- Gtexdraw.is_lit = 0;
- }
- else {
- Gtexdraw.is_lit = GPU_scene_object_lights(
- scene, ob, v3d->localvd ? v3d->localvd->lay : v3d->lay,
- rv3d->viewmat, !rv3d->is_persp);
- }
- }
-
- rgba_float_to_uchar(obcol, ob->col);
-
- if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
- else is_tex = false;
-
- Gtexdraw.ob = ob;
- Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
- Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
- Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
- Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
- Gtexdraw.is_tex = is_tex;
-
- /* naughty multitexturing hacks to quickly support stencil + shading + alpha blending
- * in new texpaint code. The better solution here would be to support GLSL */
- if (Gtexdraw.is_texpaint) {
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
-
- /* load the stencil texture here */
- if (Gtexdraw.stencil != NULL) {
- glActiveTexture(GL_TEXTURE2);
- if (GPU_verify_image(Gtexdraw.stencil, NULL, GL_TEXTURE_2D, false, false, false, false)) {
- float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
- if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
- }
- else {
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- }
- }
- }
- glActiveTexture(GL_TEXTURE0);
- }
-
- Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
- Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
- Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
- Gtexdraw.two_sided_lighting = (me->flag & ME_TWOSIDED);
-
- memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
- set_draw_settings_cached(1, NULL, NULL, &Gtexdraw);
- glCullFace(GL_BACK);
-}
-
-static void draw_textured_end(void)
-{
- if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) {
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- if (Gtexdraw.stencil != NULL) {
- glActiveTexture(GL_TEXTURE2);
- glDisable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
- glActiveTexture(GL_TEXTURE0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- /* manual reset, since we don't use tpage */
- glBindTexture(GL_TEXTURE_2D, 0);
- /* force switch off textures */
- GPU_clear_tpage(true);
- }
- else {
- /* switch off textures */
- GPU_set_tpage(NULL, 0, 0);
- }
-
- glDisable(GL_CULL_FACE);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- /* XXX, bad patch - GPU_default_lights() calls
- * glLightfv(GL_POSITION, ...) which
- * is transformed by the current matrix... we
- * need to make sure that matrix is identity.
- *
- * It would be better if drawmesh.c kept track
- * of and restored the light settings it changed.
- * - zr
- */
- glPushMatrix();
- glLoadIdentity();
- GPU_default_lights();
- glPopMatrix();
-}
-
-static DMDrawOption draw_tface__set_draw_legacy(MTexPoly *mtexpoly, const bool has_mcol, int matnr)
-{
- Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
- bool invalidtexture = false;
-
- if (ma && (ma->game.flag & GEMAT_INVISIBLE))
- return DM_DRAW_OPTION_SKIP;
-
- invalidtexture = set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw);
-
- if (mtexpoly && invalidtexture) {
- glColor3ub(0xFF, 0x00, 0xFF);
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (!has_mcol) {
- if (mtexpoly) {
- glColor3f(1.0, 1.0, 1.0);
- }
- else {
- if (ma) {
- if (ma->shade_flag & MA_OBCOLOR) {
- glColor3ubv(Gtexdraw.obcol);
- }
- else {
- float col[3];
- if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
- else copy_v3_v3(col, &ma->r);
-
- glColor3fv(col);
- }
- }
- else {
- glColor3f(1.0, 1.0, 1.0);
- }
- }
- return DM_DRAW_OPTION_NORMAL; /* normal drawing (no mcols anyway, no need to turn off) */
- }
- else {
- return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
- }
-}
-
-static DMDrawOption draw_tface__set_draw(MTexPoly *mtexpoly, const bool UNUSED(has_mcol), int matnr)
-{
- Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
-
- if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return DM_DRAW_OPTION_SKIP;
-
- if (mtexpoly || Gtexdraw.is_texpaint)
- set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw);
-
- /* always use color from mcol, as set in update_tface_color_layer */
- return DM_DRAW_OPTION_NORMAL;
-}
-
-static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
-{
- const MPoly *mp = dm->getPolyArray(dm);
- const int mpoly_num = dm->getNumPolys(dm);
- MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
- MLoopCol *finalCol;
- int i, j;
- MLoopCol *mloopcol = NULL;
-
- /* cache material values to avoid a lot of lookups */
- Material *ma = NULL;
- short mat_nr_prev = -1;
- enum {
- COPY_CALC,
- COPY_ORIG,
- COPY_PREV,
- } copy_mode = COPY_CALC;
-
- if (use_mcol) {
- mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
- if (!mloopcol)
- mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
- }
-
- if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) {
- finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL);
- }
- else {
- finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer");
- CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData);
- }
-
- for (i = mpoly_num; i--; mp++) {
- const short mat_nr = mp->mat_nr;
-
- if (UNLIKELY(mat_nr_prev != mat_nr)) {
- ma = give_current_material(Gtexdraw.ob, mat_nr + 1);
- copy_mode = COPY_CALC;
- mat_nr_prev = mat_nr;
- }
-
- /* avoid lookups */
- if (copy_mode == COPY_ORIG) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- }
- else if (copy_mode == COPY_PREV) {
- int loop_index = mp->loopstart;
- const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart];
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index] = *lcol_prev;
- }
- }
-
- /* (copy_mode == COPY_CALC) */
- else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
- if (mloopcol) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_ORIG;
- }
- else {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_PREV;
- }
- }
- else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw)) {
- int loop_index = mp->loopstart;
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index].r = 255;
- finalCol[loop_index].g = 0;
- finalCol[loop_index].b = 255;
- finalCol[loop_index].a = 255;
- }
- copy_mode = COPY_PREV;
- }
- else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
- int loop_index = mp->loopstart;
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- copy_v3_v3_uchar(&finalCol[loop_index].r, Gtexdraw.obcol);
- finalCol[loop_index].a = 255;
- }
- copy_mode = COPY_PREV;
- }
- else {
- if (mloopcol) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_ORIG;
- }
- else if (mtexpoly) {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_PREV;
- }
- else {
- float col[3];
-
- if (ma) {
- int loop_index = mp->loopstart;
- MLoopCol lcol;
-
- if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
- else copy_v3_v3(col, &ma->r);
- rgb_float_to_uchar((unsigned char *)&lcol.r, col);
- lcol.a = 255;
-
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index] = lcol;
- }
- }
- else {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- }
- copy_mode = COPY_PREV;
- }
- }
- }
-
- dm->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW;
-}
-
-static DMDrawOption draw_tface_mapped__set_draw(void *userData, int origindex, int UNUSED(mat_nr))
-{
- const Mesh *me = ((drawTFace_userData *)userData)->me;
-
- /* array checked for NULL before calling */
- MPoly *mpoly = &me->mpoly[origindex];
-
- BLI_assert(origindex >= 0 && origindex < me->totpoly);
-
- if (mpoly->flag & ME_HIDE) {
- return DM_DRAW_OPTION_SKIP;
- }
- else {
- MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[origindex] : NULL;
- int matnr = mpoly->mat_nr;
-
- return draw_tface__set_draw(tpoly, (me->mloopcol != NULL), matnr);
- }
-}
-
-static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int origindex, int mat_nr)
-{
- drawEMTFMapped_userData *data = userData;
- BMEditMesh *em = data->em;
- BMFace *efa;
-
- if (UNLIKELY(origindex >= em->bm->totface))
- return DM_DRAW_OPTION_NORMAL;
-
- efa = BM_face_at_index(em->bm, origindex);
-
- if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- return DM_DRAW_OPTION_SKIP;
- }
- else {
- MTexPoly *mtexpoly = (data->cd_poly_tex_offset != -1) ?
- BM_ELEM_CD_GET_VOID_P(efa, data->cd_poly_tex_offset) : NULL;
- int matnr = (mat_nr != -1) ? mat_nr : efa->mat_nr;
-
- return draw_tface__set_draw_legacy(mtexpoly, data->has_mcol, matnr);
- }
-}
-
/* when face select is on, use face hidden flag */
static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
{
@@ -779,288 +209,6 @@ static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int ind
return DM_DRAW_OPTION_NORMAL;
}
-static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
-{
- Mesh *me = ob->data;
- DerivedMesh *ddm;
- MPoly *mp, *mface = me->mpoly;
- MTexPoly *mtpoly = me->mtpoly;
- MLoopUV *mloopuv = me->mloopuv;
- MLoopUV *luv;
- MLoopCol *mloopcol = me->mloopcol; /* why does mcol exist? */
- MLoopCol *lcol;
-
- bProperty *prop = BKE_bproperty_object_get(ob, "Text");
- GPUVertexAttribs gattribs;
- int a, totpoly = me->totpoly;
-
- /* fake values to pass to GPU_render_text() */
- MCol tmp_mcol[4] = {{0}};
- MCol *tmp_mcol_pt = mloopcol ? tmp_mcol : NULL;
-
- /* don't draw without tfaces */
- if (!mtpoly || !mloopuv)
- return;
-
- /* don't draw when editing */
- if (ob->mode & OB_MODE_EDIT)
- return;
- else if (ob == OBACT)
- if (BKE_paint_select_elem_test(ob))
- return;
-
- ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-
- for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
- short matnr = mp->mat_nr;
- const bool mf_smooth = (mp->flag & ME_SMOOTH) != 0;
- Material *mat = (me->mat) ? me->mat[matnr] : NULL;
- int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
-
-
- if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
- /* get the polygon as a tri/quad */
- int mp_vi[4];
- float v_quad_data[4][3];
- const float *v_quad[4];
- const float *uv_quad[4];
- char string[MAX_PROPSTRING];
- int characters, i, glattrib = -1, badtex = 0;
-
-
- /* TEXFACE */
- if (glsl) {
- GPU_object_material_bind(matnr + 1, &gattribs);
-
- for (i = 0; i < gattribs.totlayer; i++) {
- if (gattribs.layer[i].type == CD_MTFACE) {
- glattrib = gattribs.layer[i].glindex;
- break;
- }
- }
- }
- else {
- badtex = set_draw_settings_cached(0, mtpoly, mat, &Gtexdraw);
- if (badtex) {
- continue;
- }
- }
-
- mp_vi[0] = me->mloop[mp->loopstart + 0].v;
- mp_vi[1] = me->mloop[mp->loopstart + 1].v;
- mp_vi[2] = me->mloop[mp->loopstart + 2].v;
- mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;
-
- /* UV */
- luv = &mloopuv[mp->loopstart];
- uv_quad[0] = luv->uv; luv++;
- uv_quad[1] = luv->uv; luv++;
- uv_quad[2] = luv->uv; luv++;
- if (mp->totloop >= 4) {
- uv_quad[3] = luv->uv;
- }
- else {
- uv_quad[3] = NULL;
- }
-
-
- /* COLOR */
- if (mloopcol) {
- unsigned int totloop_clamp = min_ii(4, mp->totloop);
- unsigned int j;
- lcol = &mloopcol[mp->loopstart];
-
- for (j = 0; j < totloop_clamp; j++, lcol++) {
- MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
- }
- }
-
- /* LOCATION */
- ddm->getVertCo(ddm, mp_vi[0], v_quad_data[0]);
- ddm->getVertCo(ddm, mp_vi[1], v_quad_data[1]);
- ddm->getVertCo(ddm, mp_vi[2], v_quad_data[2]);
- if (mp->totloop >= 4) {
- ddm->getVertCo(ddm, mp_vi[3], v_quad_data[3]);
- }
-
- v_quad[0] = v_quad_data[0];
- v_quad[1] = v_quad_data[1];
- v_quad[2] = v_quad_data[2];
- if (mp->totloop >= 4) {
- v_quad[3] = v_quad_data[2];
- }
- else {
- v_quad[3] = NULL;
- }
-
-
- /* The BM_FONT handling is in the gpu module, shared with the
- * game engine, was duplicated previously */
-
- BKE_bproperty_set_valstr(prop, string);
- characters = strlen(string);
-
- if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
- characters = 0;
-
- if (!mf_smooth) {
- float nor[3];
-
- normal_tri_v3(nor, v_quad[0], v_quad[1], v_quad[2]);
-
- glNormal3fv(nor);
- }
-
- GPU_render_text(
- mtpoly, mode, string, characters,
- (unsigned int *)tmp_mcol_pt,
- v_quad, uv_quad,
- glattrib);
- }
- }
-
- ddm->release(ddm);
-}
-
-static int compareDrawOptions(void *userData, int cur_index, int next_index)
-{
- drawTFace_userData *data = userData;
-
- if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
- return 0;
-
- if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
- return 0;
-
- return 1;
-}
-
-
-static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
-{
- drawEMTFMapped_userData *data = userData;
-
- if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
- return 0;
-
- if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
- return 0;
-
- return 1;
-}
-
-static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Object *ob, DerivedMesh *dm, const int draw_flags)
-{
- Mesh *me = ob->data;
-
- /* correct for negative scale */
- if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
- else glFrontFace(GL_CCW);
-
- /* draw the textured mesh */
- draw_textured_begin(scene, v3d, rv3d, ob);
-
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- if (ob->mode & OB_MODE_EDIT) {
- drawEMTFMapped_userData data;
-
- data.em = me->edit_btmesh;
- data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
- data.cd_poly_tex_offset = CustomData_get_offset(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
-
- data.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
- data.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
-
- dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
- }
- else {
- DMDrawFlag dm_draw_flag;
- drawTFace_userData userData;
-
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- dm_draw_flag = DM_DRAW_USE_TEXPAINT_UV;
- }
- else {
- dm_draw_flag = DM_DRAW_USE_ACTIVE_UV;
- }
-
- if (ob == OBACT) {
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
- dm_draw_flag |= DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH | DM_DRAW_SKIP_HIDDEN;
- }
- else if (ob->mode & OB_MODE_SCULPT) {
- dm_draw_flag |= DM_DRAW_SKIP_HIDDEN | DM_DRAW_USE_COLORS;
- }
- else if ((ob->mode & OB_MODE_TEXTURE_PAINT) == 0) {
- dm_draw_flag |= DM_DRAW_USE_COLORS;
- }
- }
- else {
- if ((ob->mode & OB_MODE_TEXTURE_PAINT) == 0) {
- dm_draw_flag |= DM_DRAW_USE_COLORS;
- }
- }
-
-
- userData.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
- userData.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
-
- if (draw_flags & DRAW_FACE_SELECT) {
- userData.me = me;
-
- dm->drawMappedFacesTex(
- dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions,
- &userData, dm_draw_flag);
- }
- else {
- userData.me = NULL;
-
- /* if ((ob->mode & OB_MODE_ALL_PAINT) == 0) */ {
-
- /* Note: this isn't efficient and runs on every redraw,
- * its needed so material colors are used for vertex colors.
- * In the future we will likely remove 'texface' so, just avoid running this where possible,
- * (when vertex paint or weight paint are used).
- *
- * Note 2: We disable optimization for now since it causes T48788
- * and it is now too close to release to do something smarter.
- *
- * TODO(sergey): Find some real solution here.
- */
-
- update_tface_color_layer(dm, !(ob->mode & OB_MODE_TEXTURE_PAINT));
- }
-
- dm->drawFacesTex(
- dm, draw_tface__set_draw, compareDrawOptions,
- &userData, dm_draw_flag);
- }
- }
-
- /* draw game engine text hack */
- if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- if (BKE_bproperty_object_get(ob, "Text")) {
- draw_mesh_text(scene, ob, 0);
- }
- }
-
- draw_textured_end();
-
- /* draw edges and selected faces over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
- bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
- draw_mesh_face_select(rv3d, me, dm, draw_select_edges);
- }
-
- /* reset from negative scale correction */
- glFrontFace(GL_CCW);
-
- /* in editmode, the blend mode needs to be set in case it was ADD */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
/************************** NEW SHADING NODES ********************************/
typedef struct TexMatCallback {
@@ -1072,187 +220,11 @@ typedef struct TexMatCallback {
bool two_sided_lighting;
} TexMatCallback;
-static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
-{
- /* all we have to do here is simply enable the GLSL material, but note
- * that the GLSL code will give different result depending on the drawtype,
- * in texture draw mode it will output the active texture node, in material
- * draw mode it will show the full material. */
- GPU_object_material_bind(mat_nr, attribs);
-}
-
-static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
-{
- /* texture draw mode without GLSL */
- TexMatCallback *data = (TexMatCallback *)userData;
- GPUVertexAttribs *gattribs = attribs;
- Image *ima;
- ImageUser *iuser;
- bNode *node;
-
- /* draw image texture if we find one */
- if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
- /* get openl texture */
- int mipmap = 1;
- int bindcode = (ima) ? GPU_verify_image(ima, iuser, GL_TEXTURE_2D, 0, 0, mipmap, false) : 0;
-
- if (bindcode) {
- NodeTexBase *texbase = node->storage;
-
- /* disable existing material */
- GPU_object_material_unbind();
-
- /* bind texture */
- glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
-
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixf(texbase->tex_mapping.mat);
- glMatrixMode(GL_MODELVIEW);
-
- /* use active UV texture layer */
- memset(gattribs, 0, sizeof(*gattribs));
-
- gattribs->layer[0].type = CD_MTFACE;
- gattribs->layer[0].name[0] = '\0';
- gattribs->layer[0].gltexco = 1;
- gattribs->totlayer = 1;
-
- /* bind material */
- float diffuse[3] = {1.0f, 1.0f, 1.0f};
-
- int options = GPU_SHADER_TEXTURE_2D;
- if (!data->shadeless)
- options |= GPU_SHADER_LIGHTING;
- if (data->two_sided_lighting)
- options |= GPU_SHADER_TWO_SIDED;
-
- GPU_basic_shader_colors(diffuse, NULL, 0, 1.0f);
- GPU_basic_shader_bind(options);
-
- return;
- }
- }
-
- /* disable texture material */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- if (data->shadeless) {
- glColor3f(1.0f, 1.0f, 1.0f);
- memset(gattribs, 0, sizeof(*gattribs));
- }
- else {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- /* enable solid material */
- GPU_object_material_bind(mat_nr, attribs);
- }
-}
-
-static bool tex_mat_set_face_mesh_cb(void *userData, int index)
-{
- /* faceselect mode face hiding */
- TexMatCallback *data = (TexMatCallback *)userData;
- Mesh *me = (Mesh *)data->me;
- MPoly *mp = &me->mpoly[index];
-
- return !(mp->flag & ME_HIDE);
-}
-
-static bool tex_mat_set_face_editmesh_cb(void *userData, int index)
-{
- /* editmode face hiding */
- TexMatCallback *data = (TexMatCallback *)userData;
- Mesh *me = (Mesh *)data->me;
- BMEditMesh *em = me->edit_btmesh;
- BMFace *efa;
-
- if (UNLIKELY(index >= em->bm->totface))
- return DM_DRAW_OPTION_NORMAL;
-
- efa = BM_face_at_index(em->bm, index);
-
- return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
-}
-
-void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
+void draw_mesh_textured(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
Object *ob, DerivedMesh *dm, const int draw_flags)
{
- /* if not cycles, or preview-modifiers, or drawing matcaps */
- if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
- (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
- (BKE_scene_use_new_shading_nodes(scene) == false) ||
- ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
- {
- draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
- return;
- }
- else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
- draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
- return;
- }
-
- /* set opengl state for negative scale & color */
- if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
- else glFrontFace(GL_CCW);
-
- Mesh *me = ob->data;
-
- bool shadeless = ((v3d->flag2 & V3D_SHADELESS_TEX) &&
- ((v3d->drawtype == OB_TEXTURE) || (ob->mode & OB_MODE_TEXTURE_PAINT)));
- bool two_sided_lighting = (me->flag & ME_TWOSIDED) != 0;
-
- TexMatCallback data = {scene, ob, me, dm, shadeless, two_sided_lighting};
- bool (*set_face_cb)(void *, int);
- bool picking = (G.f & G_PICKSEL) != 0;
-
- /* face hiding callback depending on mode */
- if (ob == scene->obedit)
- set_face_cb = tex_mat_set_face_editmesh_cb;
- else if (draw_flags & DRAW_FACE_SELECT)
- set_face_cb = tex_mat_set_face_mesh_cb;
- else
- set_face_cb = NULL;
-
- /* test if we can use glsl */
- const int drawtype = view3d_effective_drawtype(v3d);
- bool glsl = (drawtype == OB_MATERIAL) && !picking;
-
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
-
- if (glsl || picking) {
- /* draw glsl or solid */
- dm->drawMappedFacesMat(dm,
- tex_mat_set_material_cb,
- set_face_cb, &data);
- }
- else {
- /* draw textured */
- dm->drawMappedFacesMat(dm,
- tex_mat_set_texture_cb,
- set_face_cb, &data);
- }
-
- GPU_end_object_materials();
-
- /* reset opengl state */
- GPU_end_object_materials();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- glFrontFace(GL_CCW);
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- /* faceselect mode drawing over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
- bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
- draw_mesh_face_select(rv3d, ob->data, dm, draw_select_edges);
- }
+ UNUSED_VARS(scene, sl, v3d, rv3d, ob, dm, draw_flags);
+ return;
}
/* Vertex Paint and Weight Paint */
@@ -1299,13 +271,6 @@ void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light,
flags |= DM_DRAW_NEED_NORMALS;
}
- /* Don't show alpha in wire mode. */
- const bool show_alpha = use_light;
- if (show_alpha) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
if (me->mloopcol) {
dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data,
DM_DRAW_USE_COLORS | flags);
@@ -1315,10 +280,6 @@ void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light,
dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data, flags);
}
- if (show_alpha) {
- glDisable(GL_BLEND);
- }
-
if (use_light) {
draw_mesh_paint_light_end();
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index d7e3b78cdc3..eaf699d8385 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -54,6 +54,7 @@
#include "BKE_camera.h"
#include "BKE_colortools.h"
#include "BKE_constraint.h" /* for the get_constraint_target function */
+#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
#include "BKE_deform.h"
@@ -62,6 +63,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -80,6 +82,8 @@
#include "BKE_editmesh.h"
+#include "DEG_depsgraph.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -90,6 +94,10 @@
#include "GPU_select.h"
#include "GPU_basic_shader.h"
#include "GPU_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_batch.h"
+#include "GPU_matrix.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@@ -105,6 +113,13 @@
#include "view3d_intern.h" /* bad level include */
+#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
+
+/* prototypes */
+static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos);
+
+// #define USE_MESH_DM_SELECT
+
/* Workaround for sequencer scene render mode.
*
* Strips doesn't use DAG to update objects or so, which
@@ -129,6 +144,7 @@ typedef struct drawDMVerts_userData {
BMVert *eve_act;
char sel;
+ unsigned int pos, color;
/* cached theme values */
unsigned char th_editmesh_active[4];
@@ -181,6 +197,7 @@ typedef struct drawDMFacesSel_userData {
} drawDMFacesSel_userData;
typedef struct drawDMNormal_userData {
+ unsigned int pos;
BMesh *bm;
int uniform_scale;
float normalsize;
@@ -189,6 +206,7 @@ typedef struct drawDMNormal_userData {
} drawDMNormal_userData;
typedef struct drawMVertOffset_userData {
+ unsigned int pos, col;
MVert *mvert;
int offset;
} drawMVertOffset_userData;
@@ -196,9 +214,11 @@ typedef struct drawMVertOffset_userData {
typedef struct drawDMLayer_userData {
BMesh *bm;
int cd_layer_offset;
+ unsigned int pos, col;
} drawDMLayer_userData;
typedef struct drawBMOffset_userData {
+ unsigned int pos, col;
BMesh *bm;
int offset;
} drawBMOffset_userData;
@@ -206,25 +226,23 @@ typedef struct drawBMOffset_userData {
typedef struct drawBMSelect_userData {
BMesh *bm;
bool select;
+ unsigned int pos;
} drawBMSelect_userData;
-static void draw_bounding_volume(Object *ob, char type);
-static void drawcube_size(float size);
-static void drawcircle_size(float size);
-static void draw_empty_sphere(float size);
-static void draw_empty_cone(float size);
-static void draw_box(const float vec[8][3], bool solid);
+static void drawcube_size(float size, unsigned pos);
+static void drawcircle_size(float size, unsigned pos);
+static void draw_empty_sphere(float size, unsigned pos);
+static void draw_empty_cone(float size, unsigned pos);
-static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
+static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac, float r_col[3])
{
- float col_wire[3], col_bg[3], col[3];
+ float col_wire[3], col_bg[3];
rgb_uchar_to_float(col_wire, ob_wire_col);
UI_GetThemeColor3fv(theme_id, col_bg);
- interp_v3_v3v3(col, col_bg, col_wire, fac);
- glColor3fv(col);
+ interp_v3_v3v3(r_col, col_bg, col_wire, fac);
}
int view3d_effective_drawtype(const struct View3D *v3d)
@@ -296,13 +314,13 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
/* check for glsl drawing */
-bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
+bool draw_glsl_material(Scene *scene, SceneLayer *sl, Object *ob, View3D *v3d, const char dt)
{
if (G.f & G_PICKSEL)
return false;
if (!check_object_draw_texture(scene, v3d, dt))
return false;
- if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
+ if (ob == OBACT(sl) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return false;
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
@@ -318,7 +336,7 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
static bool check_alpha_pass(Base *base)
{
- if (base->flag & OB_FROMDUPLI)
+ if (base->flag_legacy & OB_FROMDUPLI)
return false;
if (G.f & G_PICKSEL)
@@ -414,9 +432,9 @@ static const float cosval[CIRCLE_RESOL] = {
* \param viewmat_local_unit is typically the 'rv3d->viewmatob'
* copied into a 3x3 matrix and normalized.
*/
-static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
+static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis, unsigned pos)
{
- int line_type;
+ Gwn_PrimType line_type = GWN_PRIM_LINES;
float buffer[4][3];
int n = 0;
@@ -429,8 +447,6 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
switch (axis) {
case 0: /* x axis */
- line_type = GL_LINES;
-
/* bottom left to top right */
negate_v3_v3(v1, dx);
sub_v3_v3(v1, dy);
@@ -450,8 +466,6 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
break;
case 1: /* y axis */
- line_type = GL_LINES;
-
/* bottom left to top right */
mul_v3_fl(dx, 0.75f);
negate_v3_v3(v1, dx);
@@ -472,7 +486,7 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
break;
case 2: /* z axis */
- line_type = GL_LINE_STRIP;
+ line_type = GWN_PRIM_LINE_STRIP;
/* start at top left */
negate_v3_v3(v1, dx);
@@ -501,54 +515,60 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
return;
}
+ immBegin(line_type, n);
for (int i = 0; i < n; i++) {
mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]);
add_v3_v3(buffer[i], c);
+ immVertex3fv(pos, buffer[i]);
}
+ immEnd();
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, buffer);
- glDrawArrays(line_type, 0, n);
- glDisableClientState(GL_VERTEX_ARRAY);
+ /* TODO: recode this function for clarity once we're not in a hurry to modernize GL usage */
}
-void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
+void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4])
{
int axis;
float v1[3] = {0.0, 0.0, 0.0};
float v2[3] = {0.0, 0.0, 0.0};
float v3[3] = {0.0, 0.0, 0.0};
- glLineWidth(1);
+ glLineWidth(1.0f);
- switch (drawtype) {
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ if (color) {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4ubv(color);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ }
+ switch (drawtype) {
case OB_PLAINAXES:
+ immBegin(GWN_PRIM_LINES, 6);
for (axis = 0; axis < 3; axis++) {
- glBegin(GL_LINES);
-
v1[axis] = size;
v2[axis] = -size;
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
/* reset v1 & v2 to zero */
v1[axis] = v2[axis] = 0.0f;
-
- glEnd();
}
+ immEnd();
break;
- case OB_SINGLE_ARROW:
- glBegin(GL_LINES);
+ case OB_SINGLE_ARROW:
+ immBegin(GWN_PRIM_LINES, 2);
/* in positive z direction only */
v1[2] = size;
- glVertex3fv(v1);
- glVertex3fv(v2);
- glEnd();
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immEnd();
/* square pyramid */
- glBegin(GL_TRIANGLES);
+ immBegin(GWN_PRIM_TRIS, 12);
v2[0] = size * 0.035f; v2[1] = size * 0.035f;
v3[0] = size * -0.035f; v3[1] = size * 0.035f;
@@ -564,28 +584,27 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
v3[0] = -v3[0];
}
- glVertex3fv(v1);
- glVertex3fv(v2);
- glVertex3fv(v3);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immVertex3fv(pos, v3);
}
- glEnd();
-
+ immEnd();
break;
+
case OB_CUBE:
- drawcube_size(size);
+ drawcube_size(size, pos);
break;
case OB_CIRCLE:
- drawcircle_size(size);
+ drawcircle_size(size, pos);
break;
case OB_EMPTY_SPHERE:
- draw_empty_sphere(size);
+ draw_empty_sphere(size, pos);
break;
case OB_EMPTY_CONE:
- draw_empty_cone(size);
+ draw_empty_cone(size, pos);
break;
case OB_ARROWS:
@@ -599,34 +618,34 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
for (axis = 0; axis < 3; axis++) {
const int arrow_axis = (axis == 0) ? 1 : 0;
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 6);
v2[axis] = size;
- glVertex3fv(v1);
- glVertex3fv(v2);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+
v1[axis] = size * 0.85f;
v1[arrow_axis] = -size * 0.08f;
- glVertex3fv(v1);
- glVertex3fv(v2);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+
v1[arrow_axis] = size * 0.08f;
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
- glEnd();
-
- v2[axis] += size * 0.125f;
+ immEnd();
- draw_xyz_wire(viewmat_local_unit, v2, size, axis);
+ v2[axis] += size * 0.125f;
+ draw_xyz_wire(viewmat_local_unit, v2, size, axis, pos);
/* reset v1 & v2 to zero */
v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
}
- break;
}
}
+
+ immUnbindProgram();
}
@@ -634,38 +653,39 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], eStereoViews sview)
{
Image *ima = ob->data;
- ImBuf *ibuf;
- ImageUser iuser = *ob->iuser;
- /* Support multi-view */
- if (ima && (sview == STEREO_RIGHT_ID)) {
- iuser.multiview_eye = sview;
- iuser.flag |= IMA_SHOW_STEREO;
- BKE_image_multiview_index(ima, &iuser);
- }
+ const float ob_alpha = ob->col[3];
+ float ima_x, ima_y;
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ int bindcode = 0;
- if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
- IMB_rect_from_float(ibuf);
- }
+ if (ima) {
+ ImageUser iuser = *ob->iuser;
+
+ /* Support multi-view */
+ if (ima && (sview == STEREO_RIGHT_ID)) {
+ iuser.multiview_eye = sview;
+ iuser.flag |= IMA_SHOW_STEREO;
+ BKE_image_multiview_index(ima, &iuser);
+ }
- int ima_x, ima_y;
+ if (ob_alpha > 0.0f) {
+ bindcode = GPU_verify_image(ima, &iuser, GL_TEXTURE_2D, 0, false, false, false);
+ /* don't bother drawing the image if alpha = 0 */
+ }
- /* Get the buffer dimensions so we can fallback to fake ones */
- if (ibuf && ibuf->rect) {
- ima_x = ibuf->x;
- ima_y = ibuf->y;
+ int w, h;
+ BKE_image_get_size(ima, &iuser, &w, &h);
+ ima_x = w;
+ ima_y = h;
}
else {
- ima_x = 1;
- ima_y = 1;
+ /* if no image, make it a 1x1 empty square, honor scale & offset */
+ ima_x = ima_y = 1.0f;
}
- float sca_x = 1.0f;
- float sca_y = 1.0f;
-
/* Get the image aspect even if the buffer is invalid */
+ float sca_x = 1.0f, sca_y = 1.0f;
if (ima) {
if (ima->aspx > ima->aspy) {
sca_y = ima->aspy / ima->aspx;
@@ -675,61 +695,98 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
}
}
- /* Calculate the scale center based on object's origin */
- float ofs_x = ob->ima_ofs[0] * ima_x;
- float ofs_y = ob->ima_ofs[1] * ima_y;
+ float scale_x;
+ float scale_y;
+ {
+ const float scale_x_inv = ima_x * sca_x;
+ const float scale_y_inv = ima_y * sca_y;
+ if (scale_x_inv > scale_y_inv) {
+ scale_x = ob->empty_drawsize;
+ scale_y = ob->empty_drawsize * (scale_y_inv / scale_x_inv);
+ }
+ else {
+ scale_x = ob->empty_drawsize * (scale_x_inv / scale_y_inv);
+ scale_y = ob->empty_drawsize;
+ }
+ }
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ const float ofs_x = ob->ima_ofs[0] * scale_x;
+ const float ofs_y = ob->ima_ofs[1] * scale_y;
- /* Calculate Image scale */
- float scale = ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y);
+ const rctf rect = {
+ .xmin = ofs_x,
+ .xmax = ofs_x + scale_x,
+ .ymin = ofs_y,
+ .ymax = ofs_y + scale_y,
+ };
- /* Set the object scale */
- glScalef(scale * sca_x, scale * sca_y, 1.0f);
+ bool use_blend = false;
- if (ibuf && ibuf->rect) {
- const bool use_clip = (U.glalphaclip != 1.0f);
- int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP) ? GL_NEAREST : GL_LINEAR;
- /* Setup GL params */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (bindcode) {
+ use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima);
- if (use_clip) {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, U.glalphaclip);
+ if (use_blend) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- /* Use the object color and alpha */
- glColor4fv(ob->col);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+ immUniform1f("alpha", ob_alpha);
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
- /* Draw the Image on the screen */
- glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, rect.xmin, rect.ymin);
- glDisable(GL_BLEND);
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, rect.xmax, rect.ymin);
- if (use_clip) {
- glDisable(GL_ALPHA_TEST);
- glAlphaFunc(GL_ALWAYS, 0.0f);
- }
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, rect.xmax, rect.ymax);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, rect.xmin, rect.ymax);
+ immEnd();
+
+ immUnbindProgram();
+
+ glBindTexture(GL_TEXTURE_2D, 0); /* necessary? */
}
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ /* Draw the image outline */
+ glLineWidth(1.5f);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ const bool picking = dflag & DRAW_CONSTCOLOR;
+ if (picking) {
+ /* TODO: deal with picking separately, use this function just to draw */
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ if (use_blend) {
+ glDisable(GL_BLEND);
+ }
+
+ imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+ glEnable(GL_LINE_SMOOTH);
- /* Calculate the outline vertex positions */
- glBegin(GL_LINE_LOOP);
- glVertex2f(ofs_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
- glVertex2f(ofs_x, ofs_y + ima_y);
- glEnd();
+ if (!use_blend) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
- /* Reset GL settings */
- glPopMatrix();
+ imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+ }
+
+ immUnbindProgram();
}
static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
@@ -747,62 +804,65 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
}
}
-void drawcircball(int mode, const float cent[3], float rad, const float tmat[4][4])
+void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos)
{
float verts[CIRCLE_RESOL][3];
circball_array_fill(verts, cent, rad, tmat);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, verts);
- glDrawArrays(mode, 0, CIRCLE_RESOL);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL);
+ for (int i = 0; i < CIRCLE_RESOL; ++i) {
+ immVertex3fv(pos, verts[i]);
+ }
+ immEnd();
}
/* circle for object centers, special_color is for library or ob users */
-static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, bool special_color)
+static void drawcentercircle(View3D *v3d, RegionView3D *UNUSED(rv3d), const float co[3], int selstate, bool special_color)
{
- const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f;
- float verts[CIRCLE_RESOL][3];
+ const float outlineWidth = 1.0f * U.pixelsize;
+ const float size = U.obcenter_dia * U.pixelsize + outlineWidth;
+
+ if (v3d->zbuf) {
+ glDisable(GL_DEPTH_TEST);
+ /* TODO(merwin): fit things like this into plates/buffers design */
+ }
- /* using glDepthFunc guarantees that it does write z values,
- * but not checks for it, so centers remain visible independent of draw order */
- if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
- /* write to near buffer always */
- glDepthRange(0.0, 0.0);
glEnable(GL_BLEND);
-
+ GPU_enable_program_point_size();
+
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("size", size);
+
if (special_color) {
- if (selstate == ACTIVE || selstate == SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
- else glColor4ub(0x55, 0xCC, 0xCC, 155);
+ if (selstate == ACTIVE || selstate == SELECT) immUniformColor4ub(0x88, 0xFF, 0xFF, 155);
+ else immUniformColor4ub(0x55, 0xCC, 0xCC, 155);
}
else {
- if (selstate == ACTIVE) UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
- else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
- else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
+ if (selstate == ACTIVE) immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
+ else if (selstate == SELECT) immUniformThemeColorShadeAlpha(TH_SELECT, 0, -80);
+ else if (selstate == DESELECT) immUniformThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
}
- circball_array_fill(verts, co, size, rv3d->viewinv);
-
- /* enable vertex array */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, verts);
-
- /* 1. draw filled, blended polygon */
- glDrawArrays(GL_POLYGON, 0, CIRCLE_RESOL);
+ /* set up outline */
+ float outlineColor[4];
+ UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, outlineColor);
+ immUniform4fv("outlineColor", outlineColor);
+ immUniform1f("outlineWidth", outlineWidth);
- /* 2. draw outline */
- glLineWidth(1);
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
- glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, co);
+ immEnd();
- /* finish up */
- glDisableClientState(GL_VERTEX_ARRAY);
+ immUnbindProgram();
- glDepthRange(0.0, 1.0);
+ GPU_disable_program_point_size();
glDisable(GL_BLEND);
- if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ }
}
/* *********** text drawing for object/particles/armature ************* */
@@ -893,36 +953,30 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
if (tot) {
int col_pack_prev = 0;
-#if 0
- bglMats mats; /* ZBuffer depth vars */
- double ux, uy, uz;
- float depth;
-
- if (v3d->zbuf)
- bgl_get_mats(&mats);
-#endif
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_disable();
}
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
wmOrtho2_region_pixelspace(ar);
- glLoadIdentity();
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
if (depth_write) {
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
}
else {
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
}
+ const int font_id = BLF_default();
+
for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
if (vos->sco[0] != IS_CLIPPED) {
if (col_pack_prev != vos->col.pack) {
- glColor3ubv(vos->col.ub);
+ BLF_color3ubv(font_id, vos->col.ub);
col_pack_prev = vos->col.pack;
}
@@ -941,13 +995,11 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
else {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_enable();
@@ -971,9 +1023,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
/* draws a cube given the scaling of the cube, assuming that
* all required matrices have been set (used for drawing empties)
*/
-static void drawcube_size(float size)
+static void drawcube_size(float size, unsigned pos)
{
- const GLfloat pos[8][3] = {
+ const float verts[8][3] = {
{-size, -size, -size},
{-size, -size, size},
{-size, size, -size},
@@ -986,13 +1038,21 @@ static void drawcube_size(float size)
const GLubyte indices[24] = {0,1,1,3,3,2,2,0,0,4,4,5,5,7,7,6,6,4,1,5,3,7,2,6};
+#if 0
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pos);
+ glVertexPointer(3, GL_FLOAT, 0, verts);
glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
+#else
+ immBegin(GWN_PRIM_LINES, 24);
+ for (int i = 0; i < 24; ++i) {
+ immVertex3fv(pos, verts[indices[i]]);
+ }
+ immEnd();
+#endif
}
-static void drawshadbuflimits(Lamp *la, float mat[4][4])
+static void drawshadbuflimits(const Lamp *la, const float mat[4][4], unsigned pos)
{
float sta[3], end[3], lavec[3];
@@ -1002,16 +1062,16 @@ static void drawshadbuflimits(Lamp *la, float mat[4][4])
madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta);
madd_v3_v3v3fl(end, mat[3], lavec, la->clipend);
- glBegin(GL_LINES);
- glVertex3fv(sta);
- glVertex3fv(end);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, sta);
+ immVertex3fv(pos, end);
+ immEnd();
- glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex3fv(sta);
- glVertex3fv(end);
- glEnd();
+ glPointSize(3.0f);
+ immBegin(GWN_PRIM_POINTS, 2);
+ immVertex3fv(pos, sta);
+ immVertex3fv(pos, end);
+ immEnd();
}
static void spotvolume(float lvec[3], float vvec[3], const float inp)
@@ -1077,62 +1137,63 @@ static void spotvolume(float lvec[3], float vvec[3], const float inp)
mul_m3_v3(mat2, vvec);
}
-static void draw_spot_cone(Lamp *la, float x, float z)
+static void draw_spot_cone(Lamp *la, float x, float z, unsigned pos)
{
z = fabsf(z);
- glBegin(GL_TRIANGLE_FAN);
- glVertex3f(0.0f, 0.0f, -x);
+ const bool square = (la->mode & LA_SQUARE);
+
+ immBegin(GWN_PRIM_TRI_FAN, square ? 6 : 34);
+ immVertex3f(pos, 0.0f, 0.0f, -x);
- if (la->mode & LA_SQUARE) {
- glVertex3f(z, z, 0);
- glVertex3f(-z, z, 0);
- glVertex3f(-z, -z, 0);
- glVertex3f(z, -z, 0);
- glVertex3f(z, z, 0);
+ if (square) {
+ immVertex3f(pos, z, z, 0);
+ immVertex3f(pos, -z, z, 0);
+ immVertex3f(pos, -z, -z, 0);
+ immVertex3f(pos, z, -z, 0);
+ immVertex3f(pos, z, z, 0);
}
else {
for (int a = 0; a < 33; a++) {
float angle = a * M_PI * 2 / (33 - 1);
- glVertex3f(z * cosf(angle), z * sinf(angle), 0);
+ immVertex3f(pos, z * cosf(angle), z * sinf(angle), 0.0f);
}
}
- glEnd();
+ immEnd();
}
-static void draw_transp_spot_volume(Lamp *la, float x, float z)
+static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos)
{
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
/* draw backside darkening */
glCullFace(GL_FRONT);
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- draw_spot_cone(la, x, z);
+ draw_spot_cone(la, x, z, pos);
/* draw front side lighting */
glCullFace(GL_BACK);
glBlendFunc(GL_ONE, GL_ONE);
- glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
+ immUniformColor3f(0.2f, 0.2f, 0.2f);
- draw_spot_cone(la, x, z);
+ draw_spot_cone(la, x, z, pos);
/* restore state */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
- glCullFace(GL_BACK);
}
#ifdef WITH_GAMEENGINE
-static void draw_transp_sun_volume(Lamp *la)
+static void draw_transp_sun_volume(Lamp *la, unsigned pos)
{
float box[8][3];
@@ -1145,50 +1206,46 @@ static void draw_transp_sun_volume(Lamp *la)
box[1][2] = box[2][2] = box[5][2] = box[6][2] = -la->clipsta;
/* draw edges */
- draw_box(box, false);
+ imm_draw_box(box, false, pos);
/* draw faces */
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
/* draw backside darkening */
glCullFace(GL_FRONT);
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- draw_box(box, true);
+ imm_draw_box(box, true, pos);
/* draw front side lighting */
glCullFace(GL_BACK);
glBlendFunc(GL_ONE, GL_ONE);
- glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
+ immUniformColor3f(0.2f, 0.2f, 0.2f);
- draw_box(box, true);
+ imm_draw_box(box, true, pos);
/* restore state */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
- glCullFace(GL_BACK);
}
#endif
-static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
+void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
{
Object *ob = base->object;
const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
Lamp *la = ob->data;
float vec[3], lvec[3], vvec[3], circrad;
- float lampsize;
float imat[4][4];
- unsigned char curcol[4];
- unsigned char col[4];
/* cone can't be drawn for duplicated lamps, because duplilist would be freed */
/* the moment of view3d_draw_transp() call */
const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object);
@@ -1196,7 +1253,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
!(G.f & G_PICKSEL) &&
(la->type == LA_SPOT) &&
(la->mode & LA_SHOW_CONE) &&
- !(base->flag & OB_FROMDUPLI) &&
+ !(base->flag_legacy & OB_FROMDUPLI) &&
!is_view);
#ifdef WITH_GAMEENGINE
@@ -1208,7 +1265,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
((la->mode & LA_SHAD_BUF) ||
(la->mode & LA_SHAD_RAY)) &&
(la->mode & LA_SHOW_SHADOW_BOX) &&
- !(base->flag & OB_FROMDUPLI) &&
+ !(base->flag_legacy & OB_FROMDUPLI) &&
!is_view);
#else
const bool drawshadowbox = false;
@@ -1216,118 +1273,159 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
if ((drawcone || drawshadowbox) && !v3d->transp) {
/* in this case we need to draw delayed */
- ED_view3d_after_add(v3d->xray ? &v3d->afterdraw_xraytransp : &v3d->afterdraw_transp, base, dflag);
+ ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
return;
}
-
+
/* we first draw only the screen aligned & fixed scale stuff */
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
/* lets calculate the scale: */
- lampsize = pixsize * ((float)U.obcenter_dia * 0.5f);
+ const float lampsize_px = U.obcenter_dia;
+ const float lampsize = pixsize * lampsize_px * 0.5f;
/* and view aligned matrix: */
copy_m4_m4(imat, rv3d->viewinv);
normalize_v3(imat[0]);
normalize_v3(imat[1]);
+ const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
/* lamp center */
copy_v3_v3(vec, ob->obmat[3]);
+ float curcol[4];
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* for AA effects */
- curcol[0] = ob_wire_col[0];
- curcol[1] = ob_wire_col[1];
- curcol[2] = ob_wire_col[2];
- curcol[3] = 154;
- glColor4ubv(curcol);
+ rgb_uchar_to_float(curcol, ob_wire_col);
+ curcol[3] = 0.6f;
+ /* TODO: pay attention to GL_BLEND */
}
- glLineWidth(1);
+ glLineWidth(1.0f);
+ setlinestyle(3);
if (lampsize > 0.0f) {
+ const float outlineWidth = 1.5f * U.pixelsize;
+ const float lampdot_size = lampsize_px * U.pixelsize + outlineWidth;
+ /* Inner Circle */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ const float *color = curcol;
if (ob->id.us > 1) {
- if (is_obact || (ob->flag & SELECT)) {
- glColor4ub(0x88, 0xFF, 0xFF, 155);
+ if (is_obact || ((base->flag & BASE_SELECTED) != 0)) {
+ static const float active_color[4] = {0.533f, 1.0f, 1.0f, 1.0f};
+ color = active_color;
}
else {
- glColor4ub(0x77, 0xCC, 0xCC, 155);
+ static const float inactive_color[4] = {0.467f, 0.8f, 0.8f, 1.0f};
+ color = inactive_color;
}
}
+
+ GPU_enable_program_point_size();
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("size", lampdot_size);
+ immUniform1f("outlineWidth", outlineWidth);
+ immUniformColor3fvAlpha(color, 0.3f);
+ immUniform4fv("outlineColor", color);
+
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
+ GPU_disable_program_point_size();
}
-
- /* Inner Circle */
- glEnable(GL_BLEND);
- drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
- glDisable(GL_BLEND);
- drawcircball(GL_POLYGON, vec, lampsize, imat);
-
+ else {
+ /* CONSTCOLOR in effect */
+ /* TODO: separate picking from drawing */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ /* color doesn't matter, so don't set */
+ glPointSize(lampdot_size);
+
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ immUnbindProgram();
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ /* TODO(merwin): short term, use DEPTH_ONLY for picking
+ * long term, separate picking from drawing
+ */
+
/* restore */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (ob->id.us > 1)
- glColor4ubv(curcol);
+ immUniformColor4fv(curcol);
}
/* Outer circle */
circrad = 3.0f * lampsize;
- setlinestyle(3);
- drawcircball(GL_LINE_LOOP, vec, circrad, imat);
+ imm_drawcircball(vec, circrad, imat, pos);
/* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
if (la->type != LA_HEMI) {
if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
- drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f * pixsize, imat);
+ imm_drawcircball(vec, circrad + 3.0f * pixsize, imat, pos);
}
}
}
else {
- setlinestyle(3);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ immUniformColor4fv(curcol);
+ }
circrad = 0.0f;
}
-
+
/* draw the pretty sun rays */
if (la->type == LA_SUN) {
float v1[3], v2[3], mat[3][3];
short axis;
-
+
/* setup a 45 degree rotation matrix */
axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2);
/* vectors */
mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
mul_v3_v3fl(v2, imat[0], circrad * 2.5f);
-
+
/* center */
- glTranslate3fv(vec);
-
+ gpuPushMatrix();
+ gpuTranslate3fv(vec);
+
setlinestyle(3);
-
- glBegin(GL_LINES);
+
+ immBegin(GWN_PRIM_LINES, 16);
for (axis = 0; axis < 8; axis++) {
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
mul_m3_v3(mat, v1);
mul_m3_v3(mat, v2);
}
- glEnd();
-
- glTranslatef(-vec[0], -vec[1], -vec[2]);
+ immEnd();
+ gpuPopMatrix();
}
-
+
if (la->type == LA_LOCAL) {
if (la->mode & LA_SPHERE) {
- drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
+ imm_drawcircball(vec, la->dist, imat, pos);
}
}
-
- glPopMatrix(); /* back in object space */
+
+ gpuPopMatrix(); /* back in object space */
zero_v3(vec);
-
+
if (is_view) {
/* skip drawing extra info */
}
@@ -1359,24 +1457,18 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
{z_abs, -z_abs, x},
{-z_abs, z_abs, x},
};
- const unsigned char indices[] = {
- 0, 1, 3,
- 0, 3, 2,
- 0, 2, 4,
- 0, 1, 4,
- };
- /* Draw call:
- * activate and specify pointer to vertex array */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vertices);
- /* draw the pyramid */
- glDrawElements(GL_LINE_STRIP, 12, GL_UNSIGNED_BYTE, indices);
-
- /* deactivate vertex arrays after drawing */
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(GWN_PRIM_LINES, 16);
+ for (int i = 1; i <= 4; ++i) {
+ immVertex3fv(pos, vertices[0]); /* apex to corner */
+ immVertex3fv(pos, vertices[i]);
+ int next_i = (i == 4) ? 1 : (i + 1);
+ immVertex3fv(pos, vertices[i]); /* corner to next corner */
+ immVertex3fv(pos, vertices[next_i]);
+ }
+ immEnd();
- glTranslatef(0.0f, 0.0f, x);
+ gpuTranslate3f(0.0f, 0.0f, x);
/* draw the square representing spotbl */
if (la->type == LA_SPOT) {
@@ -1386,22 +1478,21 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != z_abs) {
- fdrawbox(blend, -blend, -blend, blend);
+ imm_draw_box_wire_3d(pos, blend, -blend, -blend, blend);
}
}
}
else {
-
/* draw the angled sides of the cone */
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vvec);
- glVertex3fv(vec);
- glVertex3fv(lvec);
- glEnd();
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immVertex3fv(pos, vvec);
+ immVertex3fv(pos, vec);
+ immVertex3fv(pos, lvec);
+ immEnd();
/* draw the circle at the end of the cone */
- glTranslatef(0.0f, 0.0f, x);
- circ(0.0f, 0.0f, z_abs);
+ gpuTranslate3f(0.0f, 0.0f, x);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, z_abs, 32);
/* draw the circle representing spotbl */
if (la->type == LA_SPOT) {
@@ -1411,17 +1502,17 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != z_abs) {
- circ(0.0f, 0.0f, blend);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, blend, 32);
}
}
}
if (drawcone)
- draw_transp_spot_volume(la, x, z);
+ draw_transp_spot_volume(la, x, z, pos);
/* draw clip start, useful for wide cones where its not obvious where the start is */
- glTranslatef(0.0, 0.0, -x); /* reverse translation above */
- glBegin(GL_LINES);
+ gpuTranslate3f(0.0f, 0.0f, -x); /* reverse translation above */
+ immBegin(GWN_PRIM_LINES, 2);
if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) {
float lvec_clip[3];
float vvec_clip[3];
@@ -1430,41 +1521,40 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac);
interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac);
- glVertex3fv(lvec_clip);
- glVertex3fv(vvec_clip);
+ immVertex3fv(pos, lvec_clip);
+ immVertex3fv(pos, vvec_clip);
}
/* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
else {
- glVertex3f(0.0, 0.0, -circrad);
- glVertex3f(0.0, 0.0, -la->dist);
+ immVertex3f(pos, 0.0f, 0.0f, -circrad);
+ immVertex3f(pos, 0.0f, 0.0f, -la->dist);
}
- glEnd();
+ immEnd();
}
else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
-
/* draw the line from the circle along the dist */
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 2);
vec[2] = -circrad;
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
vec[2] = -la->dist;
- glVertex3fv(vec);
- glEnd();
-
+ immVertex3fv(pos, vec);
+ immEnd();
+
if (la->type == LA_HEMI) {
/* draw the hemisphere curves */
short axis, steps, dir;
float outdist, zdist, mul;
zero_v3(vec);
- outdist = 0.14; mul = 1.4; dir = 1;
-
+ outdist = 0.14f; mul = 1.4f; dir = 1;
+
setlinestyle(4);
/* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
for (axis = 0; axis < 4; axis++) {
- float v[3] = {0.0, 0.0, 0.0};
- zdist = 0.02;
-
- glBegin(GL_LINE_STRIP);
-
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ zdist = 0.02f;
+
+ immBegin(GWN_PRIM_LINE_STRIP, 6);
+
for (steps = 0; steps < 6; steps++) {
if (axis == 0 || axis == 1) { /* x axis up, x axis down */
/* make the arcs start at the edge of the energy circle */
@@ -1477,13 +1567,13 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
}
v[2] = v[2] - steps * zdist;
-
- glVertex3fv(v);
-
+
+ immVertex3fv(pos, v);
+
zdist = zdist * mul;
}
-
- glEnd();
+
+ immEnd();
/* flip the direction */
dir = -dir;
}
@@ -1491,96 +1581,92 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
#ifdef WITH_GAMEENGINE
if (drawshadowbox) {
- draw_transp_sun_volume(la);
+ draw_transp_sun_volume(la, pos);
}
#endif
-
}
else if (la->type == LA_AREA) {
setlinestyle(3);
if (la->area_shape == LA_AREA_SQUARE)
- fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
+ imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
else if (la->area_shape == LA_AREA_RECT)
- fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
+ imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, -circrad);
- glVertex3f(0.0, 0.0, -la->dist);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, -circrad);
+ immVertex3f(pos, 0.0f, 0.0f, -la->dist);
+ immEnd();
}
-
+
/* and back to viewspace */
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
copy_v3_v3(vec, ob->obmat[3]);
setlinestyle(0);
-
+
if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) {
- drawshadbuflimits(la, ob->obmat);
+ drawshadbuflimits(la, ob->obmat, pos);
}
-
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- UI_GetThemeColor4ubv(TH_LAMP, col);
- glColor4ubv(col);
+ immUniformThemeColor(TH_LAMP);
}
glEnable(GL_BLEND);
-
+
if (vec[2] > 0) vec[2] -= circrad;
else vec[2] += circrad;
-
- glBegin(GL_LINES);
- glVertex3fv(vec);
+
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, vec);
vec[2] = 0;
- glVertex3fv(vec);
- glEnd();
-
- glPointSize(2.0);
- glBegin(GL_POINTS);
- glVertex3fv(vec);
- glEnd();
-
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ glPointSize(2.0f);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
glDisable(GL_BLEND);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- /* restore for drawing extra stuff */
- glColor3ubv(ob_wire_col);
- }
- /* and finally back to org object space! */
- glPopMatrix();
+
+ immUnbindProgram();
+ gpuPopMatrix();
}
-static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3])
+static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3], unsigned pos)
{
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, -sta);
- glVertex3f(0.0, 0.0, -end);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, -sta);
+ immVertex3f(pos, 0.0f, 0.0f, -end);
+ immEnd();
if (!(dflag & DRAW_PICKING)) {
- glPointSize(3.0);
- glBegin(GL_POINTS);
+ glPointSize(3.0f);
+ /* would like smooth round points here, but that means binding another shader...
+ * if it's really desired, pull these points into their own function to be called after */
+ immBegin(GWN_PRIM_POINTS, 2);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(col);
+ immUniformColor3ubv(col);
}
- glVertex3f(0.0, 0.0, -sta);
- glVertex3f(0.0, 0.0, -end);
- glEnd();
+ immVertex3f(pos, 0.0f, 0.0f, -sta);
+ immVertex3f(pos, 0.0f, 0.0f, -end);
+ immEnd();
}
}
/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
/* qdn: now also enabled for Blender to set focus point for defocus composite node */
-static void draw_focus_cross(float dist, float size)
+static void draw_focus_cross(float dist, float size, unsigned pos)
{
- glBegin(GL_LINES);
- glVertex3f(-size, 0.0f, -dist);
- glVertex3f(size, 0.0f, -dist);
- glVertex3f(0.0f, -size, -dist);
- glVertex3f(0.0f, size, -dist);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex3f(pos, -size, 0.0f, -dist);
+ immVertex3f(pos, size, 0.0f, -dist);
+ immVertex3f(pos, 0.0f, -size, -dist);
+ immVertex3f(pos, 0.0f, size, -dist);
+ immEnd();
}
#ifdef VIEW3D_CAMERA_BORDER_HACK
@@ -1590,26 +1676,6 @@ bool view3d_camera_border_hack_test = false;
/* ****************** draw clip data *************** */
-static void draw_bundle_sphere(void)
-{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
- gluSphere(qobj, 0.05, 8, 8);
- gluDeleteQuadric(qobj);
-
- glEndList();
- }
-
- glCallList(displist);
-}
-
static void draw_viewport_object_reconstruction(
Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d,
MovieClip *clip, MovieTrackingObject *tracking_object,
@@ -1635,7 +1701,7 @@ static void draw_viewport_object_reconstruction(
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
mul_v3_fl(camera_size, tracking_object->scale);
- glPushMatrix();
+ gpuPushMatrix();
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
/* current ogl matrix is translated in camera space, bundles should
@@ -1643,8 +1709,8 @@ static void draw_viewport_object_reconstruction(
* from current ogl matrix */
invert_m4_m4(imat, base->object->obmat);
- glMultMatrixf(imat);
- glMultMatrixf(mat);
+ gpuMultMatrix(imat);
+ gpuMultMatrix(mat);
}
else {
float obmat[4][4];
@@ -1653,7 +1719,7 @@ static void draw_viewport_object_reconstruction(
BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
invert_m4_m4(imat, obmat);
- glMultMatrixf(imat);
+ gpuMultMatrix(imat);
}
for (track = tracksbase->first; track; track = track->next) {
@@ -1666,66 +1732,93 @@ static void draw_viewport_object_reconstruction(
continue;
if (dflag & DRAW_PICKING)
- GPU_select_load_id(base->selcol + (tracknr << 16));
+ GPU_select_load_id(base->object->select_color + (tracknr << 16));
- glPushMatrix();
- glTranslate3fv(track->bundle_pos);
- glScalef(v3d->bundle_size / 0.05f / camera_size[0],
- v3d->bundle_size / 0.05f / camera_size[1],
- v3d->bundle_size / 0.05f / camera_size[2]);
+ gpuPushMatrix();
+ gpuTranslate3fv(track->bundle_pos);
+ gpuScale3f(v3d->bundle_size / 0.05f / camera_size[0],
+ v3d->bundle_size / 0.05f / camera_size[1],
+ v3d->bundle_size / 0.05f / camera_size[2]);
const int v3d_drawtype = view3d_effective_drawtype(v3d);
if (v3d_drawtype == OB_WIRE) {
+ unsigned char color[4];
+ const unsigned char *color_ptr = NULL;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ color_ptr = ob_wire_col;
}
else {
- glColor3fv(track->color);
+ rgba_float_to_uchar(color, track->color);
+ color_ptr = color;
}
}
- drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
+ drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr);
}
else if (v3d_drawtype > OB_WIRE) {
if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) {
+ Gwn_Batch *batch;
+
+ gpuScaleUniform(0.05f);
+
/* selection outline */
if (selected) {
+ batch = GPU_batch_preset_sphere_wire(1);
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_uniform_4f(batch, "color",
+ ob_wire_col[0] / 255.f,
+ ob_wire_col[1] / 255.f,
+ ob_wire_col[2] / 255.f, 1.0f);
+ }
+ else {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
-
glLineWidth(2.0f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- draw_bundle_sphere();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ GWN_batch_draw(batch);
}
+ batch = GPU_batch_preset_sphere(0);
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
- else UI_ThemeColor(TH_BUNDLE_SOLID);
+ const float light[3] = {0.0f, 0.0f, 1.0f};
+ float col[3];
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3fv(batch, "light", light);
+
+ if (track->flag & TRACK_CUSTOMCOLOR) copy_v3_v3(col, track->color);
+ else UI_GetThemeColor3fv(TH_BUNDLE_SOLID, col);
+ GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
+ }
+ else {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
- draw_bundle_sphere();
+ GWN_batch_draw(batch);
}
else {
+ unsigned char color[4];
+ const unsigned char *color_ptr = NULL;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (selected) {
- glColor3ubv(ob_wire_col);
+ color_ptr = ob_wire_col;
}
else {
- if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
- else UI_ThemeColor(TH_WIRE);
+ if (track->flag & TRACK_CUSTOMCOLOR) rgba_float_to_uchar(color, track->color);
+ else UI_GetThemeColor4ubv(TH_WIRE, color);
+
+ color_ptr = color;
}
}
- drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
+ drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr);
}
}
- glPopMatrix();
+ gpuPopMatrix();
if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
float pos[3];
@@ -1745,22 +1838,27 @@ static void draw_viewport_object_reconstruction(
MovieTrackingReconstruction *reconstruction;
reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
- if (reconstruction->camnr) {
+ if (reconstruction->camnr >= 2) {
MovieReconstructedCamera *camera = reconstruction->cameras;
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CAMERA_PATH);
- UI_ThemeColor(TH_CAMERA_PATH);
glLineWidth(2.0f);
- glBegin(GL_LINE_STRIP);
+ immBegin(GWN_PRIM_LINE_STRIP, reconstruction->camnr);
for (int a = 0; a < reconstruction->camnr; a++, camera++) {
- glVertex3fv(camera->mat[3]);
+ immVertex3fv(pos, camera->mat[3]);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
}
}
- glPopMatrix();
+ gpuPopMatrix();
*global_track_index = tracknr;
}
@@ -1795,67 +1893,65 @@ static void draw_viewport_reconstruction(
/* restore */
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
- }
-
if (dflag & DRAW_PICKING)
- GPU_select_load_id(base->selcol);
+ GPU_select_load_id(base->object->select_color);
}
-static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
+/* camera frame */
+static void drawcamera_frame(float vec[4][3], bool filled, unsigned pos)
{
- glBegin(mode);
- glVertex3fv(near_plane[0]);
- glVertex3fv(far_plane[0]);
- glVertex3fv(far_plane[1]);
- glVertex3fv(near_plane[1]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(near_plane[1]);
- glVertex3fv(far_plane[1]);
- glVertex3fv(far_plane[2]);
- glVertex3fv(near_plane[2]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(near_plane[2]);
- glVertex3fv(far_plane[2]);
- glVertex3fv(far_plane[3]);
- glVertex3fv(near_plane[3]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(far_plane[3]);
- glVertex3fv(near_plane[3]);
- glVertex3fv(near_plane[0]);
- glVertex3fv(far_plane[0]);
- glEnd();
+ immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4);
+ immVertex3fv(pos, vec[0]);
+ immVertex3fv(pos, vec[1]);
+ immVertex3fv(pos, vec[2]);
+ immVertex3fv(pos, vec[3]);
+ immEnd();
}
-/* camera frame */
-static void drawcamera_frame(float vec[4][3], const GLenum mode)
+/* center point to camera frame */
+static void drawcamera_framelines(float vec[4][3], float origin[3], unsigned pos)
{
- glBegin(mode);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[1]);
- glVertex3fv(vec[2]);
- glVertex3fv(vec[3]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 8);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[0]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[1]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[2]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[3]);
+ immEnd();
}
-/* center point to camera frame */
-static void drawcamera_framelines(float vec[4][3], float origin[3])
+static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], bool filled, unsigned pos)
{
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec[1]);
- glVertex3fv(origin);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[3]);
- glVertex3fv(origin);
- glVertex3fv(vec[2]);
- glEnd();
+ drawcamera_frame(near_plane, filled, pos);
+ drawcamera_frame(far_plane, filled, pos);
+
+ if (filled) {
+ immBegin(GWN_PRIM_TRI_STRIP, 10);
+
+ immVertex3fv(pos, near_plane[0]);
+ immVertex3fv(pos, far_plane[0]);
+ immVertex3fv(pos, near_plane[1]);
+ immVertex3fv(pos, far_plane[1]);
+ immVertex3fv(pos, near_plane[2]);
+ immVertex3fv(pos, far_plane[2]);
+ immVertex3fv(pos, near_plane[3]);
+ immVertex3fv(pos, far_plane[3]);
+ immVertex3fv(pos, near_plane[0]);
+ immVertex3fv(pos, far_plane[0]);
+
+ immEnd();
+ }
+ else {
+ immBegin(GWN_PRIM_LINES, 8);
+ for (int i = 0; i < 4; ++i) {
+ immVertex3fv(pos, near_plane[i]);
+ immVertex3fv(pos, far_plane[i]);
+ }
+ immEnd();
+ }
}
static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
@@ -1867,7 +1963,7 @@ static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
static void drawcamera_stereo3d(
Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
- float vec[4][3], float drawsize, const float scale[3])
+ float vec[4][3], float drawsize, const float scale[3], unsigned pos)
{
float obmat[4][4];
float vec_lr[2][4][3];
@@ -1883,15 +1979,15 @@ static void drawcamera_stereo3d(
zero_v3(tvec);
- glPushMatrix();
+ /* caller bound GPU_SHADER_3D_UNIFORM_COLOR, passed in pos attribute ID */
for (int i = 0; i < 2; i++) {
ob = BKE_camera_multiview_render(scene, ob, names[i]);
cam_lr[i] = ob->data;
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
- glMultMatrixf(obmat);
+ gpuMultMatrix(obmat);
copy_m3_m3(vec_lr[i], vec);
copy_v3_v3(vec_lr[i][3], vec[3]);
@@ -1908,10 +2004,10 @@ static void drawcamera_stereo3d(
if (is_stereo3d_cameras) {
/* camera frame */
- drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
+ drawcamera_frame(vec_lr[i], false, pos);
/* center point to camera frame */
- drawcamera_framelines(vec_lr[i], tvec);
+ drawcamera_framelines(vec_lr[i], tvec, pos);
}
/* connecting line */
@@ -1925,21 +2021,20 @@ static void drawcamera_stereo3d(
}
}
-
/* the remaining drawing takes place in the view space */
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
if (is_stereo3d_cameras) {
/* draw connecting lines */
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(2, 0xAAAA);
+ glLineStipple(2, 0xAAAA);
+ glEnable(GL_LINE_STIPPLE);
- glBegin(GL_LINES);
- glVertex3fv(origin[0]);
- glVertex3fv(origin[1]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, origin[0]);
+ immVertex3fv(pos, origin[1]);
+ immEnd();
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ glDisable(GL_LINE_STIPPLE);
}
/* draw convergence plane */
@@ -1964,21 +2059,21 @@ static void drawcamera_stereo3d(
add_v3_v3(local_plane[i], axis_center);
}
- glColor3f(0.0f, 0.0f, 0.0f);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
/* camera frame */
- drawcamera_frame(local_plane, GL_LINE_LOOP);
+ drawcamera_frame(local_plane, false, pos);
if (v3d->stereo3d_convergence_alpha > 0.0f) {
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
- glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
- drawcamera_frame(local_plane, GL_QUADS);
+ drawcamera_frame(local_plane, true, pos);
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
}
@@ -2003,37 +2098,31 @@ static void drawcamera_stereo3d(
}
/* camera frame */
- glColor3f(0.0f, 0.0f, 0.0f);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
- drawcamera_frame(near_plane, GL_LINE_LOOP);
- drawcamera_frame(far_plane, GL_LINE_LOOP);
- drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
+ drawcamera_volume(near_plane, far_plane, false, pos);
if (v3d->stereo3d_volume_alpha > 0.0f) {
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
if (i == 0)
- glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
+ immUniformColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
else
- glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
+ immUniformColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
- drawcamera_frame(near_plane, GL_QUADS);
- drawcamera_frame(far_plane, GL_QUADS);
- drawcamera_volume(near_plane, far_plane, GL_QUADS);
+ drawcamera_volume(near_plane, far_plane, true, pos);
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
}
}
-
- glPopMatrix();
}
/* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dflag, const unsigned char ob_wire_col[4])
+void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dflag, const unsigned char ob_wire_col[4])
{
/* a standing up pyramid with (0,0,0) as top */
Camera *cam;
@@ -2096,8 +2185,12 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
asp, shift, &drawsize, vec);
- glDisable(GL_CULL_FACE);
- glLineWidth(1);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
/* camera frame */
if (!is_stereo3d_cameras) {
@@ -2106,27 +2199,29 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
float obmat[4][4];
bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat);
- glMultMatrixf(obmat);
+ gpuMultMatrix(obmat);
- drawcamera_frame(vec, GL_LINE_LOOP);
- glPopMatrix();
+ drawcamera_frame(vec, false, pos);
+ gpuPopMatrix();
}
else {
- drawcamera_frame(vec, GL_LINE_LOOP);
+ drawcamera_frame(vec, false, pos);
}
}
- if (is_view)
+ if (is_view) {
+ immUnbindProgram();
return;
+ }
zero_v3(tvec);
/* center point to camera frame */
if (!is_stereo3d_cameras)
- drawcamera_framelines(vec, tvec);
+ drawcamera_framelines(vec, tvec, pos);
/* arrow on top */
tvec[2] = vec[1][2]; /* copy the depth */
@@ -2135,22 +2230,25 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
* for active cameras. We actually draw both outline+filled
* for active cameras so the wire can be seen side-on */
for (int i = 0; i < 2; i++) {
- if (i == 0) glBegin(GL_LINE_LOOP);
- else if (i == 1 && is_active) glBegin(GL_TRIANGLES);
+ if (i == 0) immBegin(GWN_PRIM_LINE_LOOP, 3);
+ else if (i == 1 && is_active) {
+ glDisable(GL_CULL_FACE); /* TODO: declarative state tracking */
+ immBegin(GWN_PRIM_TRIS, 3);
+ }
else break;
tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
- glVertex3fv(tvec); /* left */
+ immVertex3fv(pos, tvec); /* left */
tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
- glVertex3fv(tvec); /* right */
+ immVertex3fv(pos, tvec); /* right */
tvec[0] = shift[0];
tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
- glVertex3fv(tvec); /* top */
+ immVertex3fv(pos, tvec); /* top */
- glEnd();
+ immEnd();
}
if ((dflag & DRAW_SCENESET) == 0) {
@@ -2161,16 +2259,15 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
copy_m4_m4(nobmat, ob->obmat);
normalize_m4(nobmat);
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
- glMultMatrixf(nobmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ gpuMultMatrix(nobmat);
if (cam->flag & CAM_SHOWLIMITS) {
const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120};
- draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col));
+ draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col), pos);
/* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */
- draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize);
+ draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize, pos);
}
if (cam->flag & CAM_SHOWMIST) {
@@ -2179,69 +2276,79 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
if (world) {
draw_limit_line(world->miststa, world->miststa + world->mistdist,
- dflag, (is_active ? col_hi : col));
+ dflag, (is_active ? col_hi : col), pos);
}
}
- glPopMatrix();
}
}
/* stereo cameras drawing */
if (is_stereo3d) {
- drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
+ drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale, pos);
}
+
+ immUnbindProgram();
}
/* flag similar to draw_object() */
-static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
- Object *UNUSED(ob), int UNUSED(flag))
+void drawspeaker(const unsigned char ob_wire_col[3])
{
- float vec[3];
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- glEnable(GL_BLEND);
- glLineWidth(1);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (ob_wire_col) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+
+ glLineWidth(1.0f);
+
+ const int segments = 16;
for (int j = 0; j < 3; j++) {
- vec[2] = 0.25f * j - 0.125f;
+ float z = 0.25f * j - 0.125f;
- glBegin(GL_LINE_LOOP);
- for (int i = 0; i < 16; i++) {
- vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
- vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
- glVertex3fv(vec);
+ immBegin(GWN_PRIM_LINE_LOOP, segments);
+ for (int i = 0; i < segments; i++) {
+ float x = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
+ float y = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
+ immVertex3f(pos, x, y, z);
}
- glEnd();
+ immEnd();
}
for (int j = 0; j < 4; j++) {
- vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f;
- vec[1] = ((j % 2) * (j - 2)) * 0.5f;
- glBegin(GL_LINE_STRIP);
+ float x = (((j + 1) % 2) * (j - 1)) * 0.5f;
+ float y = ((j % 2) * (j - 2)) * 0.5f;
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
for (int i = 0; i < 3; i++) {
if (i == 1) {
- vec[0] *= 0.5f;
- vec[1] *= 0.5f;
+ x *= 0.5f;
+ y *= 0.5f;
}
- vec[2] = 0.25f * i - 0.125f;
- glVertex3fv(vec);
+ float z = 0.25f * i - 0.125f;
+ immVertex3f(pos, x, y, z);
}
- glEnd();
+ immEnd();
}
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
-static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
+static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel,
+ unsigned int pos, unsigned int color)
{
BPoint *bp = lt->def;
const float *co = dl ? dl->verts : NULL;
+ float active_color[4], draw_color[4];
- const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
- UI_ThemeColor(color);
+ UI_GetThemeColor4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, draw_color);
+ UI_GetThemeColor4fv(TH_ACTIVE_VERT, active_color);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+ immBeginAtMost(GWN_PRIM_POINTS, lt->pntsw * lt->pntsv * lt->pntsu);
for (int w = 0; w < lt->pntsw; w++) {
int wxt = (w == 0 || w == lt->pntsw - 1);
@@ -2253,12 +2360,12 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
if (bp->hide == 0) {
/* check for active BPoint and ensure selected */
if ((bp == actbp) && (bp->f1 & SELECT)) {
- UI_ThemeColor(TH_ACTIVE_VERT);
- glVertex3fv(dl ? co : bp->vec);
- UI_ThemeColor(color);
+ immAttrib4fv(color, active_color);
+ immVertex3fv(pos, dl ? co : bp->vec);
}
else if ((bp->f1 & SELECT) == sel) {
- glVertex3fv(dl ? co : bp->vec);
+ immAttrib4fv(color, draw_color);
+ immVertex3fv(pos, dl ? co : bp->vec);
}
}
}
@@ -2266,32 +2373,32 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
}
}
- glEnd();
+ immEnd();
}
-static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
+static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol,
+ unsigned int pos, unsigned int color)
{
int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
if (actdef_wcol) {
float col[3];
MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1);
-
weight_to_rgb(col, mdw ? mdw->weight : 0.0f);
- glColor3fv(col);
-
+ immAttrib3fv(color, col);
}
if (dl) {
- glVertex3fv(&dl->verts[index * 3]);
+ immVertex3fv(pos, &dl->verts[index * 3]);
}
else {
- glVertex3fv(lt->def[index].vec);
+ immVertex3fv(pos, lt->def[index].vec);
}
}
#ifdef SEQUENCER_DAG_WORKAROUND
-static void ensure_curve_cache(Scene *scene, Object *object)
+static void ensure_curve_cache(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *object)
{
bool need_recalc = object->curve_cache == NULL;
/* Render thread might have freed the curve cache if the
@@ -2320,13 +2427,13 @@ static void ensure_curve_cache(Scene *scene, Object *object)
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- BKE_displist_make_curveTypes(scene, object, false);
+ BKE_displist_make_curveTypes(eval_ctx, scene, object, false);
break;
case OB_MBALL:
- BKE_displist_make_mball(G.main->eval_ctx, scene, object);
+ BKE_displist_make_mball(eval_ctx, scene, object);
break;
case OB_LATTICE:
- BKE_lattice_modifiers_calc(scene, object);
+ BKE_lattice_modifiers_calc(eval_ctx, scene, object);
break;
}
}
@@ -2334,7 +2441,7 @@ static void ensure_curve_cache(Scene *scene, Object *object)
#endif
/* lattice color is hardcoded, now also shows weightgroup values in edit mode */
-static void drawlattice(View3D *v3d, Object *ob)
+static void drawlattice(View3D *v3d, Object *ob, const short dflag, const unsigned char ob_wire_col[4])
{
Lattice *lt = ob->data;
DispList *dl;
@@ -2347,15 +2454,37 @@ static void drawlattice(View3D *v3d, Object *ob)
if (is_edit) {
lt = lt->editlatt->latt;
- UI_ThemeColor(TH_WIRE_EDIT);
-
if (ob->defbase.first && lt->dvert) {
actdef_wcol = ob->actdef;
}
}
- glLineWidth(1);
- glBegin(GL_LINES);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int color, pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ if (actdef_wcol) {
+ color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (is_edit) {
+ immUniformThemeColor(TH_WIRE_EDIT);
+ }
+ else {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+ else {
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ glLineWidth(1.0f);
+ immBeginAtMost(GWN_PRIM_LINES, lt->pntsw * lt->pntsv * lt->pntsu * 6);
+
for (w = 0; w < lt->pntsw; w++) {
int wxt = (w == 0 || w == lt->pntsw - 1);
for (v = 0; v < lt->pntsv; v++) {
@@ -2364,30 +2493,40 @@ static void drawlattice(View3D *v3d, Object *ob)
int uxt = (u == 0 || u == lt->pntsu - 1);
if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
}
}
}
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
if (is_edit) {
BPoint *actbp = BKE_lattice_active_point_get(lt);
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
-
- lattice_draw_verts(lt, dl, actbp, 0);
- lattice_draw_verts(lt, dl, actbp, 1);
-
+
+ Gwn_VertFormat *v_format = immVertexFormat();
+ unsigned int v_pos = GWN_vertformat_attr_add(v_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int v_color = GWN_vertformat_attr_add(v_format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+
+ lattice_draw_verts(lt, dl, actbp, 0, v_pos, v_color);
+ lattice_draw_verts(lt, dl, actbp, 1, v_pos, v_color);
+
+ immUnbindProgram();
+
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
}
@@ -2401,6 +2540,7 @@ typedef struct drawDMVertSel_userData {
int active;
unsigned char *col[3]; /* (base, sel, act) */
char sel_prev;
+ unsigned int pos, color;
} drawDMVertSel_userData;
static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
@@ -2412,17 +2552,18 @@ static void drawSelectedVertices__mapFunc(void *userData, int index, const float
if (!(mv->flag & ME_HIDE)) {
const char sel = (index == data->active) ? 2 : (mv->flag & SELECT);
if (sel != data->sel_prev) {
- glColor3ubv(data->col[sel]);
+ immAttrib3ubv(data->color, data->col[sel]);
data->sel_prev = sel;
}
- glVertex3fv(co);
+ immVertex3fv(data->pos, co);
}
}
static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
{
drawDMVertSel_userData data;
+ Gwn_VertFormat *format = immVertexFormat();
/* TODO define selected color */
unsigned char base_col[3] = {0x0, 0x0, 0x0};
@@ -2437,9 +2578,18 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
data.col[1] = sel_col;
data.col[2] = act_col;
- glBegin(GL_POINTS);
+ data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* ************** DRAW MESH ****************** */
@@ -2486,25 +2636,34 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, const float
copy_v3_v3(n, no);
}
- glVertex3fv(cent);
- glVertex3f(cent[0] + n[0] * data->normalsize,
- cent[1] + n[1] * data->normalsize,
- cent[2] + n[2] * data->normalsize);
+ immVertex3fv(data->pos, cent);
+ immVertex3f(data->pos, cent[0] + n[0] * data->normalsize,
+ cent[1] + n[1] * data->normalsize,
+ cent[2] + n[2] * data->normalsize);
}
}
-static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
+ Gwn_VertFormat *format = immVertexFormat();
drawDMNormal_userData data;
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ if (dm->getNumPolys(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
+
+ immBeginAtMost(GWN_PRIM_LINES, dm->getNumPolys(dm) * 2);
dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
@@ -2515,16 +2674,28 @@ static void draw_dm_face_centers__mapFunc(void *userData, int index, const float
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) &&
(BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select))
{
- glVertex3fv(cent);
+ immVertex3fv(data->pos, cent);
}
}
-static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select)
+static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select, const unsigned char fcol[3])
{
- drawBMSelect_userData data = {em->bm, select};
+ Gwn_VertFormat *format = immVertexFormat();
+
+ drawBMSelect_userData data;
+ data.bm = em->bm;
+ data.select = select;
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ if (dm->getNumPolys(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(fcol);
- glBegin(GL_POINTS);
+ immBeginAtMost(GWN_PRIM_POINTS, dm->getNumPolys(dm));
dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
@@ -2551,71 +2722,83 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float
copy_v3_v3(n, no);
}
- glVertex3fv(co);
- glVertex3f(co[0] + n[0] * data->normalsize,
- co[1] + n[1] * data->normalsize,
- co[2] + n[2] * data->normalsize);
+ immVertex3fv(data->pos, co);
+ immVertex3f(data->pos, co[0] + n[0] * data->normalsize,
+ co[1] + n[1] * data->normalsize,
+ co[2] + n[2] * data->normalsize);
}
}
-static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
drawDMNormal_userData data;
+ Gwn_VertFormat *format = immVertexFormat();
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
+
+ immBeginAtMost(GWN_PRIM_LINES, dm->getNumVerts(dm) * 2);
dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
-/* Draw verts with color set based on selection */
-static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
- const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+static void draw_dm_verts_skin_root__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
drawDMVerts_userData *data = userData;
BMVert *eve = BM_vert_at_index(data->bm, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
/* skin nodes: draw a red circle around the root node(s) */
- if (data->cd_vskin_offset != -1) {
- const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
- if (vs->flag & MVERT_SKIN_ROOT) {
- float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
- glEnd();
-
- glColor4ubv(data->th_skin_root);
- drawcircball(GL_LINES, co, radius, data->imat);
-
- glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
- glBegin(GL_POINTS);
- }
+ const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
+ if (vs->flag & MVERT_SKIN_ROOT) {
+ float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
+ imm_drawcircball(co, radius, data->imat, data->pos);
}
+ }
+}
+
+/* Draw verts with color set based on selection */
+static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ drawDMVerts_userData *data = userData;
+ BMVert *eve = BM_vert_at_index(data->bm, index);
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
/* draw active in a different color - no need to stop/start point drawing for this :D */
if (eve == data->eve_act) {
- glColor4ubv(data->th_editmesh_active);
- glVertex3fv(co);
-
- /* back to regular vertex color */
- glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
+ immAttrib4ubv(data->color, data->th_editmesh_active);
+ immVertex3fv(data->pos, co);
}
else {
- glVertex3fv(co);
+ immAttrib4ubv(data->color, data->sel ? data->th_vertex_select : data->th_vertex);
+ immVertex3fv(data->pos, co);
}
}
}
static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act,
- RegionView3D *rv3d)
+ RegionView3D *rv3d, const unsigned char col[4])
{
+ Gwn_VertFormat *format = immVertexFormat();
+
drawDMVerts_userData data;
data.sel = sel;
data.eve_act = eve_act;
data.bm = em->bm;
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
/* Cache theme values */
UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
@@ -2623,16 +2806,37 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
- /* For skin root drawing */
- data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
+ /* Set correct alpha */
+ data.th_editmesh_active[3] = data.th_vertex_select[3] = data.th_vertex[3] = data.th_skin_root[3] = col[3];
+
/* view-aligned matrix */
mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
invert_m4(data.imat);
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
+
+ /* For skin root drawing */
+ data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
+
+ if (data.cd_vskin_offset != -1) {
+ data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4ubv(data.th_skin_root);
+
+ dm->foreachMappedVert(dm, draw_dm_verts_skin_root__mapFunc, &data, DM_FOREACH_NOP);
+
+ immUnbindProgram();
+ }
}
/* Draw edges with color set based on selection */
@@ -2938,24 +3142,32 @@ static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int
}
mul_v3_fl(vec, data->normalsize);
add_v3_v3(vec, co);
- glVertex3fv(co);
- glVertex3fv(vec);
+ immVertex3fv(data->pos, co);
+ immVertex3fv(data->pos, vec);
}
}
}
-static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
drawDMNormal_userData data;
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ if (dm->getNumLoops(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ immBeginAtMost(GWN_PRIM_LINES, dm->getNumLoops(dm) * 2);
dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* Draw faces with color set based on selection
@@ -3072,7 +3284,7 @@ static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
if (data.cd_layer_offset != -1) {
- glLineWidth(3.0);
+ glLineWidth(3.0f);
dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
}
}
@@ -3102,8 +3314,10 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset);
if (bweight != 0.0f) {
- UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_BEVEL, bweight);
- glVertex3fv(co);
+ unsigned char col[3];
+ UI_GetThemeColorBlend3ubv(TH_VERTEX, TH_VERTEX_BEVEL, bweight, col);
+ immAttrib3ubv(data->col, col);
+ immVertex3fv(data->pos, co);
}
}
}
@@ -3117,11 +3331,21 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
data.bm = em->bm;
data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT);
+ /* is that ever true? */
if (data.cd_layer_offset != -1) {
- glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
- glBegin(GL_POINTS);
+ Gwn_VertFormat *format = immVertexFormat();
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2.0f);
+
+ immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
}
else {
@@ -3131,7 +3355,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
if (data.cd_layer_offset != -1) {
- glLineWidth(3.0);
+ glLineWidth(3.0f);
dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data);
}
}
@@ -3152,7 +3376,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
{
ToolSettings *ts = scene->toolsettings;
- if (v3d->zbuf) glDepthMask(0); /* disable write in zbuffer, zbuf select */
+ if (v3d->zbuf) glDepthMask(GL_FALSE); /* disable write in zbuffer, zbuf select */
for (int sel = 0; sel < 2; sel++) {
unsigned char col[4], fcol[4];
@@ -3182,15 +3406,12 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
}
if (ts->selectmode & SCE_SELECT_VERTEX) {
- glPointSize(size);
- glColor4ubv(col);
- draw_dm_verts(em, cageDM, sel, eve_act, rv3d);
+ draw_dm_verts(em, cageDM, sel, eve_act, rv3d, col);
}
if (check_ob_drawface_dot(scene, v3d, obedit->dt)) {
glPointSize(fsize);
- glColor4ubv(fcol);
- draw_dm_face_centers(em, cageDM, sel);
+ draw_dm_face_centers(em, cageDM, sel, fcol);
}
if (pass == 0) {
@@ -3200,7 +3421,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
}
}
- if (v3d->zbuf) glDepthMask(1);
+ if (v3d->zbuf) glDepthMask(GL_TRUE);
}
static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
@@ -3307,11 +3528,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) {
BoundBox bb;
- bglMats mats = {{0}};
const rcti rect = {0, ar->winx, 0, ar->winy};
- view3d_get_transformation(ar, ar->regiondata, em->ob, &mats);
- ED_view3d_clipping_calc(&bb, clip_planes, &mats, &rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, ar, em->ob, &rect);
}
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
@@ -3675,7 +3894,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
}
}
-static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
+static void draw_em_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
{
@@ -3684,7 +3903,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
const bool use_occlude_wire = (dt > OB_WIRE) && (v3d->flag2 & V3D_OCCLUDE_WIRE);
bool use_depth_offset = false;
- glLineWidth(1);
+ glLineWidth(1.0f);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
@@ -3693,7 +3912,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
use_depth_offset = true;
}
else {
@@ -3713,7 +3932,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
else if (check_object_draw_texture(scene, v3d, dt)) {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind,
@@ -3723,7 +3942,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
glFrontFace(GL_CCW);
}
else {
- draw_mesh_textured(scene, v3d, rv3d, ob, finalDM, 0);
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, finalDM, 0);
}
}
else {
@@ -3740,7 +3959,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
UI_ThemeColor(TH_WIRE_EDIT);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
use_depth_offset = true;
}
else {
@@ -3790,7 +4009,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
/* don't draw unselected faces, only selected, this is MUCH nicer when texturing */
if (check_object_draw_texture(scene, v3d, dt))
@@ -3806,7 +4025,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
else if (efa_act) {
/* even if draw faces is off it would be nice to draw the stipple face
@@ -3821,7 +4040,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
#ifdef WITH_FREESTYLE
draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
@@ -3830,7 +4049,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
/* here starts all fancy draw-extra over */
@@ -3844,7 +4063,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
else {
if (me->drawflag & ME_DRAWSEAMS) {
UI_ThemeColor(TH_EDGE_SEAM);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_seams(em, cageDM);
@@ -3853,7 +4072,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
if (me->drawflag & ME_DRAWSHARP) {
UI_ThemeColor(TH_EDGE_SHARP);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_sharp(em, cageDM);
@@ -3863,7 +4082,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#ifdef WITH_FREESTYLE
if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) {
UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_freestyle(em, cageDM);
@@ -3878,7 +4097,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_dm_bweights(em, scene, cageDM);
}
- glLineWidth(1);
+ glLineWidth(1.0f);
draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
}
@@ -3886,16 +4105,13 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d);
if (me->drawflag & ME_DRAWNORMALS) {
- UI_ThemeColor(TH_NORMAL);
- draw_dm_face_normals(em, scene, ob, cageDM);
+ draw_dm_face_normals(em, scene, ob, cageDM, TH_NORMAL);
}
if (me->drawflag & ME_DRAW_VNORMALS) {
- UI_ThemeColor(TH_VNORMAL);
- draw_dm_vert_normals(em, scene, ob, cageDM);
+ draw_dm_vert_normals(em, scene, ob, cageDM, TH_VNORMAL);
}
if (me->drawflag & ME_DRAW_LNORMALS) {
- UI_ThemeColor(TH_LNORMAL);
- draw_dm_loop_normals(em, scene, ob, cageDM);
+ draw_dm_loop_normals(em, scene, ob, cageDM, TH_LNORMAL);
}
if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN |
@@ -3916,7 +4132,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
if (use_depth_offset) {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
GPU_object_material_unbind();
}
@@ -3927,15 +4143,97 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
}
+static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D *UNUSED(v3d),
+ Object *UNUSED(ob), Mesh *me, BMEditMesh *UNUSED(em), DerivedMesh *UNUSED(cageDM), DerivedMesh *UNUSED(finalDM), const char UNUSED(dt))
+{
+ /* for now... something simple! */
+ Gwn_Batch *surface = DRW_mesh_batch_cache_get_all_triangles(me);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+
+ glEnable(GL_BLEND);
+
+ /* disable depth writes for transparent surface, so it doesn't interfere with itself */
+ glDepthMask(GL_FALSE);
+
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_uniform_4f(surface, "color", 1.0f, 0.5f, 0.0f, 0.5f);
+ GWN_batch_draw(surface);
+
+#if 0 /* until I understand finalDM better */
+ if (finalDM != cageDM) {
+ puts("finalDM != cageDM");
+ Gwn_Batch *finalSurface = MBC_get_all_triangles(finalDM);
+ GWN_batch_program_set_builtin(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_uniform_4f(finalSurface, "color", 0.0f, 0.0f, 0.0f, 0.05f);
+ GWN_batch_draw(finalSurface);
+ }
+#endif
+
+ glDepthMask(GL_TRUE);
+
+ /* now write surface depth so other objects won't poke through
+ * NOTE: does not help as much as desired
+ * TODO: draw edit object last to avoid this mess
+ */
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_DEPTH_ONLY);
+ GWN_batch_draw(surface);
+
+ if (GLEW_VERSION_3_2) {
+#if 0
+ Gwn_Batch *overlay = DRW_mesh_batch_cache_get_overlay_edges(me);
+ GWN_batch_program_set_builtin(overlay, GPU_SHADER_EDGES_OVERLAY);
+ GWN_batch_uniform_2f(overlay, "viewportSize", ar->winx, ar->winy);
+ GWN_batch_draw(overlay);
+#endif
+
+#if 0 /* TODO: use this SIMPLE variant for pure triangle meshes */
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE);
+ /* use these defaults:
+ * const float edgeColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ * GWN_batch_uniform_4f(surface, "fillColor", edgeColor[0], edgeColor[1], edgeColor[2], 0.0f);
+ * GWN_batch_uniform_4fv(surface, "outlineColor", edgeColor);
+ * GWN_batch_uniform_1f(surface, "outlineWidth", 1.0f);
+ */
+ GWN_batch_uniform_2f(surface, "viewportSize", ar->winx, ar->winy);
+ GWN_batch_draw(surface);
+#endif
+ }
+ else {
+ Gwn_Batch *edges = DRW_mesh_batch_cache_get_all_edges(me);
+ GWN_batch_program_set_builtin(edges, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_uniform_4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f);
+ glEnable(GL_LINE_SMOOTH);
+ glLineWidth(1.5f);
+ GWN_batch_draw(edges);
+ glDisable(GL_LINE_SMOOTH);
+ }
+
+#if 0 /* looks good even without points */
+ Gwn_Batch *verts = MBC_get_all_verts(me);
+ glEnable(GL_BLEND);
+
+ GWN_batch_program_set_builtin(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ GWN_batch_uniform_4f(verts, "color", 0.0f, 0.0f, 0.0f, 1.0f);
+ GWN_batch_uniform_1f(verts, "size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f);
+ GWN_batch_draw(verts);
+
+ glDisable(GL_BLEND);
+#endif
+}
+
/* Mesh drawing routines */
-static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
+void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
(ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
+
+ if (ob_wire_col) glColor4ubv(ob_wire_col);
/* if transparent, we cannot draw the edges for solid select... edges
* have no material info. GPU_object_material_visible will skip the
@@ -3949,7 +4247,49 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
dm->drawEdges(dm, 0, 1);
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
+ }
+}
+
+static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active)
+{
+ if ((v3d->transp == false) && /* not when we draw the transparent pass */
+ (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
+ {
+ glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
+ glDepthMask(GL_FALSE);
+
+ float outline_color[4];
+ UI_GetThemeColor4fv((is_active ? TH_ACTIVE : TH_SELECT), outline_color);
+
+#if 1 /* new version that draws only silhouette edges */
+ Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ /* set eye vector, transformed to object coords */
+ float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+ mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
+ GWN_batch_uniform_3fv(fancy_edges, "eye", eye);
+ }
+ else {
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ }
+
+ GWN_batch_uniform_1b(fancy_edges, "drawFront", false);
+ GWN_batch_uniform_1b(fancy_edges, "drawBack", false);
+ GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true);
+ GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outline_color);
+
+ GWN_batch_draw(fancy_edges);
+#else /* alternate version that matches look of old viewport (but more efficient) */
+ Gwn_Batch *batch = MBC_get_all_edges(dm);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_uniform_4fv(batch, "color", outline_color);
+ GWN_batch_draw(batch);
+#endif
+
+ glDepthMask(GL_TRUE);
}
}
@@ -3959,19 +4299,20 @@ static bool object_is_halo(Scene *scene, Object *ob)
return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
}
-static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static void draw_mesh_fancy(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
#ifdef WITH_GAMEENGINE
- Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, scene) : base->object;
+ Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, sl) : base->object;
#else
Object *ob = base->object;
#endif
Mesh *me = ob->data;
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
bool /* no_verts,*/ no_edges, no_faces;
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- const bool is_obact = (ob == OBACT);
+ DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
+ const bool is_obact = (ob == OBACT(sl));
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
if (!dm)
@@ -4007,12 +4348,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (dt == OB_BOUNDBOX) {
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else if ((no_faces && no_edges) ||
((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
- glPointSize(1.5);
+ glPointSize(1.5f);
dm->drawVerts(dm);
}
else if ((dt == OB_WIRE) || no_faces) {
@@ -4025,19 +4366,19 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
- if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ if (draw_glsl_material(scene, sl, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
Paint *p;
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
GPUVertexAttribs gattribs;
float planes[4][4];
float (*fpl)[4] = NULL;
@@ -4045,7 +4386,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (ob->sculpt->partial_redraw) {
if (ar->do_draw & RGN_DRAW_PARTIAL) {
- ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
fpl = planes;
ob->sculpt->partial_redraw = 0;
}
@@ -4070,7 +4411,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_mesh_face_select(rv3d, me, dm, false);
}
else {
- draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, dm, draw_flags);
}
if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
@@ -4096,11 +4437,11 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
/* draw outline */
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
/* materials arent compatible with vertex colors */
@@ -4120,23 +4461,23 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
float planes[4][4];
float (*fpl)[4] = NULL;
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
if (ob->sculpt->partial_redraw) {
if (ar->do_draw & RGN_DRAW_PARTIAL) {
- ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
fpl = planes;
ob->sculpt->partial_redraw = 0;
}
@@ -4177,7 +4518,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f);
+ float color[3];
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color);
+ glColor3fv(color);
}
else {
glColor3ubv(ob_wire_col);
@@ -4195,14 +4538,14 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
*/
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
}
glLineWidth(1.0f);
dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
}
}
@@ -4221,8 +4564,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
/* returns true if nothing was drawn, for detecting to draw an object center */
-static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static bool draw_mesh_object(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
Object *ob = base->object;
Object *obedit = scene->obedit;
@@ -4233,7 +4577,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
/* If we are drawing shadows and any of the materials don't cast a shadow,
* then don't draw the object */
if (v3d->flag2 & V3D_RENDER_SHADOW) {
- for (int i = 1; i <= ob->totcol; ++i) {
+ for (int i = 0; i < ob->totcol; ++i) {
Material *ma = give_current_material(ob, i);
if (ma && !(ma->mode2 & MA_CASTSHADOW)) {
return true;
@@ -4262,7 +4606,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
}
else {
cageDM = editbmesh_get_derived_cage_and_final(
- scene, ob, em, scene->customdata_mask,
+ eval_ctx, scene, ob, em, scene->customdata_mask,
&finalDM);
}
@@ -4275,13 +4619,13 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
if (use_material) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
}
}
- draw_em_fancy(scene, ar, v3d, ob, em, cageDM, finalDM, dt);
+ draw_em_fancy(scene, sl, ar, v3d, ob, em, cageDM, finalDM, dt);
if (use_material) {
GPU_end_object_materials();
@@ -4294,16 +4638,16 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
if (dt == OB_SOLID || glsl) {
const bool check_alpha = check_alpha_pass(base);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl,
(check_alpha) ? &do_alpha_after : NULL);
}
}
- draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ draw_mesh_fancy(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
GPU_end_object_materials();
@@ -4311,7 +4655,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
}
}
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* GPU_begin_object_materials checked if this is needed */
if (do_alpha_after) {
if (ob->dtx & OB_DRAWXRAY) {
@@ -4335,18 +4679,551 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
return retval;
}
+static void make_color_variations(const unsigned char base_ubyte[4], float low[4], float med[4], float high[4], const bool other_obedit)
+{
+ /* original idea: nice variations (lighter & darker shades) of base color
+ * current implementation uses input color as high; med & low get closer to background color
+ */
+
+ float bg[3];
+ UI_GetThemeColor3fv(TH_BACK, bg);
+
+ float base[4];
+ rgba_uchar_to_float(base, base_ubyte);
+
+ if (other_obedit) {
+ /* this object should fade away so user can focus on the object being edited */
+ interp_v3_v3v3(low, bg, base, 0.1f);
+ interp_v3_v3v3(med, bg, base, 0.2f);
+ interp_v3_v3v3(high, bg, base, 0.25f);
+ }
+ else {
+ interp_v3_v3v3(low, bg, base, 0.333f);
+ interp_v3_v3v3(med, bg, base, 0.667f);
+ copy_v3_v3(high, base);
+ }
+
+ /* use original alpha */
+ low[3] = base[3];
+ med[3] = base[3];
+ high[3] = base[3];
+}
+
+static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
+{
+ if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
+ /* too complicated! use existing methods */
+ /* TODO: move this into a separate depth pre-pass */
+ draw_mesh_fancy(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ return;
+ }
+
+#ifdef WITH_GAMEENGINE
+ Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, sl) : base->object;
+#else
+ Object *ob = base->object;
+#endif
+ Mesh *me = ob->data;
+ eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */
+ bool no_edges, no_faces;
+ DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
+ const bool is_obact = (ob == OBACT(sl));
+ int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
+
+ if (!dm)
+ return;
+
+ const bool solid = dt >= OB_SOLID;
+ if (solid) {
+ DM_update_materials(dm, ob);
+ }
+
+ /* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
+ * Note: Last "preview-active" modifier in stack will win! */
+ if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob))
+ draw_flags |= DRAW_MODIFIERS_PREVIEW;
+
+ /* Unwanted combination */
+ if (draw_flags & DRAW_FACE_SELECT) {
+ draw_wire = OBDRAW_WIRE_OFF;
+ }
+ else if (ob->dtx & OB_DRAWWIRE) {
+ draw_wire = OBDRAW_WIRE_ON;
+ }
+
+ /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
+ if (dm->type == DM_TYPE_CCGDM) {
+ no_edges = !subsurf_has_edges(dm);
+ no_faces = !subsurf_has_faces(dm);
+ }
+ else {
+ no_edges = (dm->getNumEdges(dm) == 0);
+ no_faces = (dm->getNumPolys(dm) == 0);
+ }
+
+ if (solid) {
+ /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ }
+
+ if (dt == OB_BOUNDBOX) {
+ if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
+ }
+ else if ((no_faces && no_edges) ||
+ ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
+ {
+ glPointSize(1.5f);
+ // dm->drawVerts(dm);
+ // TODO: draw smooth round points as a batch
+ }
+ else if ((dt == OB_WIRE) || no_faces) {
+ draw_wire = OBDRAW_WIRE_ON;
+
+ /* enable depth for wireframes */
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ glLineWidth(1.0f);
+
+#if 1 /* fancy wireframes */
+
+ Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ /* set eye vector, transformed to object coords */
+ float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+ mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
+ GWN_batch_uniform_3fv(fancy_edges, "eye", eye);
+ }
+ else {
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ }
+
+ float frontColor[4];
+ float backColor[4];
+ float outlineColor[4];
+ make_color_variations(ob_wire_col, backColor, frontColor, outlineColor, other_obedit);
+
+ GWN_batch_uniform_4fv(fancy_edges, "frontColor", frontColor);
+ GWN_batch_uniform_4fv(fancy_edges, "backColor", backColor);
+ GWN_batch_uniform_1b(fancy_edges, "drawFront", true);
+ GWN_batch_uniform_1b(fancy_edges, "drawBack", true); /* false here = backface cull */
+ GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", false);
+
+ GWN_batch_draw(fancy_edges);
+
+ /* extra oomph for the silhouette contours */
+ glLineWidth(2.0f);
+ GWN_batch_program_use_begin(fancy_edges); /* hack to make the following uniforms stick */
+ GWN_batch_uniform_1b(fancy_edges, "drawFront", false);
+ GWN_batch_uniform_1b(fancy_edges, "drawBack", false);
+ GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true);
+ GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outlineColor);
+
+ GWN_batch_draw(fancy_edges);
+
+#else /* simple wireframes */
+
+ Gwn_Batch *batch = MBC_get_all_edges(dm);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ float color[4];
+ rgba_uchar_to_float(color, ob_wire_col);
+
+ GWN_batch_uniform_4fv(batch, "color", color);
+
+ GWN_batch_draw(batch);
+#endif
+ }
+ else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+ check_object_draw_texture(scene, v3d, dt))
+ {
+ bool draw_loose = true;
+
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
+ (draw_wire == OBDRAW_WIRE_OFF))
+ {
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(sl)));
+ }
+
+ if (draw_glsl_material(scene, sl, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ Paint *p;
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
+ GPUVertexAttribs gattribs;
+ float planes[4][4];
+ float (*fpl)[4] = NULL;
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+ if (ob->sculpt->partial_redraw) {
+ if (ar->do_draw & RGN_DRAW_PARTIAL) {
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
+ fpl = planes;
+ ob->sculpt->partial_redraw = 0;
+ }
+ }
+
+ GPU_object_material_bind(1, &gattribs);
+ dm->drawFacesSolid(dm, fpl, fast, NULL);
+ draw_loose = false;
+ }
+ else
+ dm->drawFacesGLSL(dm, GPU_object_material_bind);
+
+ GPU_object_material_unbind();
+
+ glFrontFace(GL_CCW);
+
+ if (draw_flags & DRAW_FACE_SELECT)
+ draw_mesh_face_select(rv3d, me, dm, false);
+ }
+ else {
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, dm, draw_flags);
+ }
+
+ if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
+ dm->drawLooseEdges(dm);
+ }
+ }
+ }
+ else if (dt == OB_SOLID) {
+ if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
+ /* for object selection draws no shade */
+ if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
+ /* TODO: draw basic faces with GPU_SHADER_3D_DEPTH_ONLY */
+ }
+ else {
+ const float specular[3] = {0.47f, 0.47f, 0.47f};
+
+ /* draw outline */
+ /* TODO: move this into a separate pass */
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ (draw_wire == OBDRAW_WIRE_OFF) &&
+ (ob->sculpt == NULL))
+ {
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(sl)));
+ }
+
+ /* materials arent compatible with vertex colors */
+ GPU_end_object_materials();
+
+ /* set default specular */
+ GPU_basic_shader_colors(NULL, specular, 35, 1.0f);
+ GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
+
+ dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS);
+
+ GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ }
+ }
+ else {
+ Paint *p;
+
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ (draw_wire == OBDRAW_WIRE_OFF) &&
+ (ob->sculpt == NULL))
+ {
+ /* TODO: move this into a separate pass */
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(sl)));
+ }
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
+ float planes[4][4];
+ float (*fpl)[4] = NULL;
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+ if (ob->sculpt->partial_redraw) {
+ if (ar->do_draw & RGN_DRAW_PARTIAL) {
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
+ fpl = planes;
+ ob->sculpt->partial_redraw = 0;
+ }
+ }
+
+ dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind);
+ }
+ else
+ dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
+
+ glFrontFace(GL_CCW);
+
+ GPU_object_material_unbind();
+
+ if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
+ dm->drawLooseEdges(dm);
+ }
+ }
+ }
+ else if (dt == OB_PAINT) {
+ draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
+
+ /* since we already draw wire as wp guide, don't draw over the top */
+ draw_wire = OBDRAW_WIRE_OFF;
+ }
+
+ if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */
+ /* when overriding with render only, don't bother */
+ (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) // <-- is this "== 0" in the right spot???
+ {
+ /* When using wireframe object draw in particle edit mode
+ * the mesh gets in the way of seeing the particles, fade the wire color
+ * with the background. */
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ /* TODO:
+ * Batch_UniformColor4ubv(ob_wire_col);
+ */
+ }
+
+ /* If drawing wire and drawtype is not OB_WIRE then we are
+ * overlaying the wires.
+ *
+ * No need for polygon offset because new technique is AWESOME.
+ */
+#if 0
+ glLineWidth(1.0f);
+ dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
+#else
+ /* something */
+#endif
+ }
+
+#if 0 // (merwin) what is this for?
+ if (is_obact && BKE_paint_select_vert_test(ob)) {
+ const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0;
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if (!use_depth) glDisable(GL_DEPTH_TEST);
+ else ED_view3d_polygon_offset(rv3d, 1.0);
+ drawSelectedVertices(dm, ob->data);
+ if (!use_depth) glEnable(GL_DEPTH_TEST);
+ else ED_view3d_polygon_offset(rv3d, 0.0);
+ }
+#endif
+
+ dm->release(dm);
+}
+
+static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
+{
+ EvaluationContext eval_ctx;
+ Object *ob = base->object;
+ Object *obedit = scene->obedit;
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ bool do_alpha_after = false, drawlinked = false, retval = false;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ if (v3d->flag2 & V3D_RENDER_SHADOW) {
+ /* TODO: handle shadow pass separately */
+ return true;
+ }
+
+ if (obedit && ob != obedit && ob->data == obedit->data) {
+ if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {}
+ else if (ob->modifiers.first || obedit->modifiers.first) {}
+ else drawlinked = true;
+ }
+
+ /* backface culling */
+ const bool solid = dt > OB_WIRE;
+ const bool cullBackface = solid && (v3d->flag2 & V3D_BACKFACE_CULLING);
+ if (cullBackface) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ if (ob == obedit || drawlinked) {
+ DerivedMesh *finalDM, *cageDM;
+
+ if (obedit != ob) {
+ /* linked to the edit object */
+ finalDM = cageDM = editbmesh_get_derived_base(
+ ob, em, scene->customdata_mask);
+ }
+ else {
+ cageDM = editbmesh_get_derived_cage_and_final(
+ &eval_ctx, scene, ob, em, scene->customdata_mask,
+ &finalDM);
+ }
+
+ const bool use_material = solid && ((me->drawflag & ME_DRAWEIGHT) == 0);
+
+#if 0 // why update if not being used?
+ DM_update_materials(finalDM, ob);
+ if (cageDM != finalDM) {
+ DM_update_materials(cageDM, ob);
+ }
+#endif // moved to below
+
+ if (use_material) {
+ DM_update_materials(finalDM, ob);
+ if (cageDM != finalDM) {
+ DM_update_materials(cageDM, ob);
+ }
+
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
+ }
+
+ draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt);
+
+ if (use_material) {
+ GPU_end_object_materials();
+ }
+
+ if (obedit != ob)
+ finalDM->release(finalDM);
+ }
+ else {
+ /* ob->bb was set by derived mesh system, do NULL check just to be sure */
+ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
+ if (solid) {
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+
+ if (dt == OB_SOLID || glsl) {
+ const bool check_alpha = check_alpha_pass(base);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl,
+ (check_alpha) ? &do_alpha_after : NULL);
+ }
+ }
+
+ const bool other_obedit = obedit && (obedit != ob);
+
+ draw_mesh_fancy_new(&eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
+
+ GPU_end_object_materials();
+
+ if (me->totvert == 0) retval = true;
+ }
+ }
+
+ if (cullBackface)
+ glDisable(GL_CULL_FACE);
+
+ return retval;
+}
+
/* ************** DRAW DISPLIST ****************** */
+static void drawDispListVerts(Gwn_PrimType prim_type, const void *data, unsigned int vert_ct, const unsigned char wire_col[3])
+{
+ Gwn_VertFormat format = {0};
+ unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vert_ct);
+
+ GWN_vertbuf_attr_fill(vbo, pos_id, data);
+
+ Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (wire_col) {
+ GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f);
+ }
+ GWN_batch_draw(batch);
+ GWN_batch_discard(batch);
+}
+
+/* convert dispList with elem indices to batch, only support triangles and quads
+ * XXX : This is a huge perf issue. We should cache the resulting batches inside the object instead.
+ * But new viewport will do it anyway
+ * TODO implement flat drawing */
+static void drawDispListElem(
+ bool quads, bool UNUSED(smooth), bool ndata_is_single,
+ const float *data, const float *ndata, unsigned int data_len,
+ const int *elem, unsigned int elem_len, const unsigned char wire_col[3])
+{
+ Gwn_VertFormat format = {0};
+ int i;
+ const int *idx = elem;
+ unsigned int pos_id, nor_id;
+
+ pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ if (ndata) {
+ if (ndata_is_single) {
+ /* pass */
+ }
+ else {
+ nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+ }
+
+ Gwn_IndexBufBuilder elb;
+ GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, (quads) ? elem_len * 2 : elem_len, 0xffffffff);
+
+ if (quads) {
+ for (i = elem_len; i; --i, idx += 4) {
+ GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
+ GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]);
+ }
+ }
+ else {
+ for (i = elem_len; i; --i, idx += 3) {
+ GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
+ }
+ }
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, data_len);
+
+ GWN_vertbuf_attr_fill(vbo, pos_id, data);
+
+ if (ndata) {
+ if (ndata_is_single) {
+ /* TODO: something like glNormal for a single value */
+ }
+ else {
+ GWN_vertbuf_attr_fill(vbo, nor_id, ndata);
+ }
+ }
+
+ Gwn_Batch *batch = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb), GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ if (wire_col) {
+ GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f);
+ }
+ GWN_batch_uniform_4f(batch, "color", 0.8f, 0.8f, 0.8f, 1.0f);
+ GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ GWN_batch_draw(batch);
+ GWN_batch_discard(batch);
+}
/**
* \param dl_type_mask Only draw types matching this mask.
* \return true when nothing was drawn
*/
-static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask)
+static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask, const unsigned char wire_col[3])
{
if (dlbase == NULL) return true;
- glEnableClientState(GL_VERTEX_ARRAY);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for (DispList *dl = dlbase->first; dl; dl = dl->next) {
@@ -4357,83 +5234,76 @@ static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask)
if ((dl_type_mask & (1 << dl->type)) == 0) {
continue;
}
-
+
const float *data = dl->verts;
int parts;
switch (dl->type) {
case DL_SEGM:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
-
for (parts = 0; parts < dl->parts; parts++)
- glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
-
+ drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col);
break;
- case DL_POLY:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
+ case DL_POLY:
for (parts = 0; parts < dl->parts; parts++)
- glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
-
+ drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col);
break;
- case DL_SURF:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
+ case DL_SURF:
for (parts = 0; parts < dl->parts; parts++) {
if (dl->flag & DL_CYCL_U)
- glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
+ drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col);
else
- glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
+ drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col);
}
+ float *data_aligned = MEM_mallocN(sizeof(float) * 3 * dl->parts, "aligned data");
for (int nr = 0; nr < dl->nr; nr++) {
int ofs = 3 * dl->nr;
+ int idx = 0;
data = (dl->verts) + 3 * nr;
parts = dl->parts;
- if (dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
-
while (parts--) {
- glVertex3fv(data);
+ copy_v3_v3(data_aligned + idx, data);
data += ofs;
+ idx += 3;
}
- glEnd();
-#if 0
- /* (ton) this code crashes for me when resolv is 86 or higher... no clue */
- glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
- if (dl->flag & DL_CYCL_V)
- glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
- else
- glDrawArrays(GL_LINE_STRIP, 0, dl->parts);
-#endif
+ if (dl->flag & DL_CYCL_V)
+ drawDispListVerts(GWN_PRIM_LINE_LOOP, data_aligned, dl->parts, wire_col);
+ else
+ drawDispListVerts(GWN_PRIM_LINE_STRIP, data_aligned, dl->parts, wire_col);
}
+
+ if (data_aligned)
+ MEM_freeN(data_aligned);
+
break;
case DL_INDEX3:
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
+ drawDispListElem(
+ false, true, false,
+ dl->verts, NULL, dl->nr,
+ dl->index, dl->parts, wire_col);
break;
case DL_INDEX4:
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
+ drawDispListElem(
+ true, true, false,
+ dl->verts, NULL, dl->nr,
+ dl->index, dl->parts, wire_col);
break;
}
}
- glDisableClientState(GL_VERTEX_ARRAY);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
return false;
}
-static bool drawDispListwire(ListBase *dlbase, const short ob_type)
+static bool drawDispListwire(ListBase *dlbase, const short ob_type, const unsigned char wire_col[3])
{
unsigned int dl_mask = 0xffffffff;
@@ -4442,27 +5312,25 @@ static bool drawDispListwire(ListBase *dlbase, const short ob_type)
dl_mask &= ~((1 << DL_INDEX3) | (1 << DL_INDEX4));
}
- return drawDispListwire_ex(dlbase, dl_mask);
+ return drawDispListwire_ex(dlbase, dl_mask, wire_col);
}
static bool index3_nors_incr = true;
-static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
+static void drawDispListsolid(ListBase *lb, Object *ob, const short UNUSED(dflag),
const unsigned char ob_wire_col[4], const bool use_glsl)
{
GPUVertexAttribs gattribs;
if (lb == NULL) return;
- glEnableClientState(GL_VERTEX_ARRAY);
-
/* track current material, -1 for none (needed for lines) */
short col = -1;
DispList *dl = lb->first;
while (dl) {
const float *data = dl->verts;
- const float *ndata = dl->nors;
+ //const float *ndata = dl->nors;
switch (dl->type) {
case DL_SEGM:
@@ -4472,15 +5340,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = -1;
}
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- glColor3ubv(ob_wire_col);
-
- // glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- // glDrawArrays(GL_LINE_STRIP, 0, dl->nr);
- glBegin(GL_LINE_STRIP);
- for (int nr = dl->nr; nr; nr--, data += 3)
- glVertex3fv(data);
- glEnd();
+ drawDispListVerts(GWN_PRIM_LINE_STRIP, data, dl->nr, ob_wire_col);
}
break;
case DL_POLY:
@@ -4490,14 +5350,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = -1;
}
- /* for some reason glDrawArrays crashes here in half of the platforms (not osx) */
- //glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- //glDrawArrays(GL_LINE_LOOP, 0, dl->nr);
-
- glBegin(GL_LINE_LOOP);
- for (int nr = dl->nr; nr; nr--, data += 3)
- glVertex3fv(data);
- glEnd();
+ drawDispListVerts(GWN_PRIM_LINE_LOOP, data, dl->nr, ob_wire_col);
}
break;
case DL_SURF:
@@ -4507,15 +5360,12 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL);
col = dl->col;
}
- /* FLAT/SMOOTH shading for surfaces */
- glShadeModel((dl->rt & CU_SMOOTH) ? GL_SMOOTH : GL_FLAT);
+ const unsigned int verts_len = dl->nr * dl->parts;
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glNormalPointer(GL_FLOAT, 0, dl->nors);
- glDrawElements(GL_QUADS, 4 * dl->totindex, GL_UNSIGNED_INT, dl->index);
- glDisableClientState(GL_NORMAL_ARRAY);
- glShadeModel(GL_SMOOTH);
+ drawDispListElem(
+ true, (dl->rt & CU_SMOOTH) != 0, false,
+ dl->verts, dl->nors, verts_len,
+ dl->index, dl->totindex, ob_wire_col);
}
break;
@@ -4525,8 +5375,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = dl->col;
}
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-
+#if 0
/* for polys only one normal needed */
if (index3_nors_incr) {
glEnableClientState(GL_NORMAL_ARRAY);
@@ -4534,11 +5383,17 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
}
else
glNormal3fv(ndata);
+#endif
+ /* special case, 'nors' is a single value */
+ drawDispListElem(
+ false, (dl->rt & CU_SMOOTH) != 0, true,
+ dl->verts, dl->nors, dl->nr,
+ dl->index, dl->parts, ob_wire_col);
- glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
-
+#if 0
if (index3_nors_incr)
glDisableClientState(GL_NORMAL_ARRAY);
+#endif
break;
@@ -4548,18 +5403,16 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = dl->col;
}
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glNormalPointer(GL_FLOAT, 0, dl->nors);
- glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
- glDisableClientState(GL_NORMAL_ARRAY);
+ drawDispListElem(
+ true, true, false,
+ dl->verts, dl->nors, dl->nr,
+ dl->index, dl->parts, ob_wire_col);
break;
}
dl = dl->next;
}
- glDisableClientState(GL_VERTEX_ARRAY);
glFrontFace(GL_CCW);
if (col != -1) {
@@ -4574,7 +5427,7 @@ static void drawCurveDMWired(Object *ob)
}
/* return true when nothing was drawn */
-static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
+static bool drawCurveDerivedMesh(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
{
Object *ob = base->object;
DerivedMesh *dm = ob->derivedFinal;
@@ -4588,8 +5441,8 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
if (dt > OB_WIRE && dm->getNumPolys(dm)) {
- bool glsl = draw_glsl_material(scene, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
if (!glsl)
dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
@@ -4610,7 +5463,7 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
* Only called by #drawDispList
* \return true when nothing was drawn
*/
-static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+static bool drawDispList_nobackface(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
@@ -4640,10 +5493,10 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (!render_only) {
/* when we have faces, only draw loose-wire */
if (has_faces) {
- drawDispListwire_ex(lb, (1 << DL_SEGM));
+ drawDispListwire_ex(lb, (1 << DL_SEGM), ob_wire_col);
}
else {
- drawDispListwire(lb, ob->type);
+ drawDispListwire(lb, ob->type, ob_wire_col);
}
}
@@ -4651,26 +5504,26 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
/* pass */
}
else {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
- cpack(0);
- drawDispListwire(lb, ob->type);
+ unsigned char col[4] = {0, 0, 0, 0};
+ drawDispListwire(lb, ob->type, col);
}
}
index3_nors_incr = true;
}
else {
if (!render_only || BKE_displist_has_faces(lb)) {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
}
break;
@@ -4686,19 +5539,19 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (dl->nors == NULL) BKE_displist_normals_add(lb);
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
}
else {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
break;
case OB_MBALL:
@@ -4711,19 +5564,19 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (solid) {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
}
else {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
}
break;
@@ -4731,8 +5584,9 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
return false;
}
-static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static bool drawDispList(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
bool retval;
@@ -4744,10 +5598,10 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
}
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
- if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) {
+ if (drawCurveDerivedMesh(scene, sl, v3d, rv3d, base, dt) == false) {
retval = false;
}
else {
@@ -4763,7 +5617,7 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
glFrontFace(mode);
- retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ retval = drawDispList_nobackface(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
if (mode != GL_CCW) {
glFrontFace(GL_CCW);
@@ -4778,16 +5632,63 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
}
/* *********** drawing for particles ************* */
-static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
+/* stride : offset size in bytes
+ * col[4] : the color to use when *color is NULL, can be also NULL */
+static void draw_vertex_array(Gwn_PrimType prim_type, const float *vert, const float *nor, const float *color, int stride, int vert_ct, float col[4])
+{
+ Gwn_VertFormat format = {0};
+ unsigned int pos_id, nor_id, col_id;
+ pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ if (nor) nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ if (color) col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vert_ct);
+
+ if (stride == 0) {
+ GWN_vertbuf_attr_fill(vbo, pos_id, vert);
+ if (nor) GWN_vertbuf_attr_fill(vbo, nor_id, nor);
+ if (color) GWN_vertbuf_attr_fill(vbo, col_id, color);
+ }
+ else {
+ GWN_vertbuf_attr_fill_stride(vbo, pos_id, stride, vert);
+ if (nor) GWN_vertbuf_attr_fill_stride(vbo, nor_id, stride, nor);
+ if (color) GWN_vertbuf_attr_fill_stride(vbo, col_id, stride, color);
+ }
+
+ Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ if (nor && color) {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR);
+ GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ }
+ else if (nor) {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ if (col) GWN_batch_uniform_4fv(batch, "color", col);
+ }
+ else if (color) {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+ else {
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (col) GWN_batch_uniform_4fv(batch, "color", col);
+ }
+ GWN_batch_draw(batch);
+ GWN_batch_discard(batch);
+}
+
+static void draw_particle_arrays_new(int draw_as, int ob_dt, int select,
+ const float *vert, const float *nor, const float *color,
+ int totpoint, float col[4])
{
/* draw created data arrays */
switch (draw_as) {
case PART_DRAW_AXIS:
case PART_DRAW_CROSS:
- glDrawArrays(GL_LINES, 0, 6 * totpoint);
+ draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 6 * totpoint, col);
break;
case PART_DRAW_LINE:
- glDrawArrays(GL_LINES, 0, 2 * totpoint);
+ draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 2 * totpoint, col);
break;
case PART_DRAW_BB:
if (ob_dt <= OB_WIRE || select)
@@ -4795,15 +5696,16 @@ static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int selec
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDrawArrays(GL_QUADS, 0, 4 * totpoint);
+ draw_vertex_array(GWN_PRIM_TRIS, vert, nor, color, 0, 6 * totpoint, col);
break;
default:
- glDrawArrays(GL_POINTS, 0, totpoint);
+ draw_vertex_array(GWN_PRIM_POINTS, vert, nor, color, 0, totpoint, col);
break;
}
}
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize,
- float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd)
+ float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd,
+ unsigned int pos)
{
float vec[3], vec2[3];
float *vd = NULL;
@@ -4913,24 +5815,19 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
}
case PART_DRAW_CIRC:
{
- drawcircball(GL_LINE_LOOP, state->co, pixsize, imat);
+ imm_drawcircball(state->co, pixsize, imat, pos);
break;
}
case PART_DRAW_BB:
{
float xvec[3], yvec[3], zvec[3], bb_center[3];
- if (cd) {
- cd[0] = cd[3] = cd[6] = cd[9] = ma_col[0];
- cd[1] = cd[4] = cd[7] = cd[10] = ma_col[1];
- cd[2] = cd[5] = cd[8] = cd[11] = ma_col[2];
- pdd->cd += 12;
- }
copy_v3_v3(bb->vec, state->co);
copy_v3_v3(bb->vel, state->vel);
psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
-
+
+ /* First tri */
add_v3_v3v3(pdd->vd, bb_center, xvec);
add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
@@ -4940,13 +5837,24 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
sub_v3_v3v3(pdd->vd, bb_center, xvec);
sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
+ /* Second tri */
+ add_v3_v3v3(pdd->vd, bb_center, xvec);
+ add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
+
+ sub_v3_v3v3(pdd->vd, bb_center, xvec);
+ sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
+
add_v3_v3v3(pdd->vd, bb_center, xvec);
sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
+ if (cd) {
+ for (int i = 0; i < 6; i++, cd += 3, pdd->cd += 3) {
+ copy_v3_v3(cd, ma_col);
+ }
+ }
+ for (int i = 0; i < 6; i++, pdd->nd += 3) {
+ copy_v3_v3(pdd->nd, zvec);
+ }
break;
}
}
@@ -4954,7 +5862,8 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
ParticleKey *state, int draw_as,
float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd,
- const float ct, const float pa_size, const float r_tilt, const float pixsize_scale)
+ const float ct, const float pa_size, const float r_tilt, const float pixsize_scale,
+ unsigned int pos)
{
ParticleSettings *part = psys->part;
float pixsize;
@@ -4985,7 +5894,7 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale;
- draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd);
+ draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd, pos);
}
/* unified drawing of all new particle systems draw types except dupli ob & group
* mostly tries to use vertex arrays for speed
@@ -4998,9 +5907,10 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
* 6. draw the arrays
* 7. clean up
*/
-static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Base *base, ParticleSystem *psys,
- const char ob_dt, const short dflag)
+static void draw_new_particle_system(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d,
+ Base *base, ParticleSystem *psys,
+ const char ob_dt, const short dflag)
{
Object *ob = base->object;
ParticleEditSettings *pset = PE_settings(scene);
@@ -5018,10 +5928,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
float cfra;
float ma_col[3] = {0.0f, 0.0f, 0.0f};
int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0;
- bool select = (ob->flag & SELECT) != 0, create_cdata = false, need_v = false;
+ bool select = (base->flag & BASE_SELECTED) != 0, create_cdata = false, need_v = false;
GLint polygonmode[2];
char numstr[32];
unsigned char tcol[4] = {0, 0, 0, 255};
+ unsigned int pos;
/* 1. */
if (part == NULL || !psys_check_enabled(ob, psys, G.is_rendering))
@@ -5030,7 +5941,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (pars == NULL) return;
/* don't draw normal paths in edit mode */
- if (psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART) == 0)
+ if (psys_in_edit_mode(eval_ctx->scene_layer, psys) && (pset->flag & PE_DRAW_PART) == 0)
return;
if (part->draw_as == PART_DRAW_REND)
@@ -5048,6 +5959,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
curvemapping_changed_all(psys->part->roughcurve);
/* 2. */
+ sim.eval_ctx = eval_ctx;
sim.scene = scene;
sim.ob = ob;
sim.psys = psys;
@@ -5083,16 +5995,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
copy_v3_v3(ma_col, &ma->r);
}
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(tcol);
- }
-
timestep = psys_get_timestep(&sim);
- if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
+ if ((ob->flag & OB_FROMGROUP) != 0) {
float mat[4][4];
mul_m4_m4m4(mat, ob->obmat, psys->imat);
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
}
/* needed for text display */
@@ -5212,7 +6120,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
tot_vec_size *= 2;
break;
case PART_DRAW_BB:
- tot_vec_size *= 4;
+ tot_vec_size *= 6; /* New OGL only understands tris, no choice here. */
create_ndata = 1;
break;
}
@@ -5266,6 +6174,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
totpoint = pdd->totpoint; /* draw data is up to date */
}
else {
+ if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) {
+ pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ imm_cpack(0xFFFFFF);
+ }
for (a = 0, pa = pars; a < totpart + totchild; a++, pa++) {
/* setup per particle individual stuff */
if (a < totpart) {
@@ -5336,7 +6249,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
draw_particle_data(psys, rv3d,
&state, draw_as, imat, &bb, psys->pdd,
- ct, pa_size, r_tilt, pixsize_scale);
+ ct, pa_size, r_tilt, pixsize_scale, pos);
totpoint++;
drawn = 1;
@@ -5348,7 +6261,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
draw_particle_data(psys, rv3d,
&state, draw_as, imat, &bb, psys->pdd,
- pa_time, pa_size, r_tilt, pixsize_scale);
+ pa_time, pa_size, r_tilt, pixsize_scale, pos);
totpoint++;
drawn = 1;
@@ -5370,7 +6283,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (part->draw & PART_DRAW_SIZE) {
setlinestyle(3);
- drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
+ imm_drawcircball(state.co, pa_size, imat, pos);
setlinestyle(0);
}
@@ -5407,31 +6320,19 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
}
+ if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) {
+ immUnbindProgram();
+ }
}
}
/* 6. */
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
- glEnableClientState(GL_VERTEX_ARRAY);
if (draw_as == PART_DRAW_PATH) {
ParticleCacheKey **cache, *path;
float *cdata2 = NULL;
- /* setup gl flags */
- if (1) { //ob_dt > OB_WIRE) {
- glEnableClientState(GL_NORMAL_ARRAY);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
- }
-
- // XXX test
- GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- }
-
if (totchild && (part->draw & PART_DRAW_PARENT) == 0)
totpart = 0;
else if (psys->pathcache == NULL)
@@ -5442,41 +6343,28 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
path = cache[a];
if (path->segments > 0) {
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
- if (1) { //ob_dt > OB_WIRE) {
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT) {
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- }
- }
+ if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) {
+ draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL);
+ }
+ else {
+ float color[4];
+ rgba_uchar_to_float(color, tcol);
+ draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color);
}
-
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
}
if (part->type == PART_HAIR) {
if (part->draw & PART_DRAW_GUIDE_HAIRS) {
DerivedMesh *hair_dm = psys->hair_out_dm;
-
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
+
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
if (pa->totkey > 1) {
HairKey *hkey = pa->hair;
- glVertexPointer(3, GL_FLOAT, sizeof(HairKey), hkey->world_co);
-
-#if 0 /* XXX use proper theme color here */
- UI_ThemeColor(TH_NORMAL);
-#else
- glColor3f(0.58f, 0.67f, 1.0f);
-#endif
-
- glDrawArrays(GL_LINE_STRIP, 0, pa->totkey);
+ /* XXX use proper theme color here */
+ float color[4] = {0.58f, 0.67f, 1.0f, 1.0f};
+ draw_vertex_array(GWN_PRIM_LINE_STRIP, hkey->world_co, NULL, NULL, sizeof(HairKey), pa->totkey, color);
}
}
@@ -5484,30 +6372,36 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
MVert *mvert = hair_dm->getVertArray(hair_dm);
int i;
- glColor3f(0.9f, 0.4f, 0.4f);
-
- glBegin(GL_LINES);
+ unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3f(0.9f, 0.4f, 0.4f);
+
+ unsigned int count = 0;
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
- for (i = 1; i < pa->totkey; ++i) {
- float v1[3], v2[3];
-
- copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
- copy_v3_v3(v2, mvert[pa->hair_index + i].co);
-
- mul_m4_v3(ob->obmat, v1);
- mul_m4_v3(ob->obmat, v2);
-
- glVertex3fv(v1);
- glVertex3fv(v2);
+ count += MAX2(pa->totkey - 1, 0);
+ }
+
+ if (count > 0) {
+ immBegin(GWN_PRIM_LINES, count * 2);
+ for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
+ for (i = 1; i < pa->totkey; ++i) {
+ float v1[3], v2[3];
+
+ copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
+ copy_v3_v3(v2, mvert[pa->hair_index + i].co);
+
+ mul_m4_v3(ob->obmat, v1);
+ mul_m4_v3(ob->obmat, v2);
+
+ immVertex3fv(pos_id, v1);
+ immVertex3fv(pos_id, v2);
+ }
}
+ immEnd();
}
- glEnd();
+
+ immUnbindProgram();
}
-
- glEnableClientState(GL_NORMAL_ARRAY);
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
}
if (part->draw & PART_DRAW_HAIR_GRID) {
@@ -5518,64 +6412,69 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
int *res = clmd->hair_grid_res;
int i;
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
+ unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (select)
- UI_ThemeColor(TH_ACTIVE);
+ immUniformThemeColor(TH_ACTIVE);
else
- UI_ThemeColor(TH_WIRE);
- glBegin(GL_LINES);
- glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmin[2]);
- glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmin[2]);
- glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmin[2]);
- glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmin[2]);
+ immUniformThemeColor(TH_WIRE);
+
+ immBegin(GWN_PRIM_LINES, 24);
+ immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]);
- glVertex3f(gmin[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
- glVertex3f(gmax[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
- glVertex3f(gmax[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
- glVertex3f(gmin[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]);
- glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
- glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
- glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
- glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
- glEnd();
+ immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]);
+ immEnd();
if (select)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
+ immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
else
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
- glEnable(GL_BLEND);
- glBegin(GL_LINES);
- for (i = 1; i < res[0] - 1; ++i) {
- float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1));
- glVertex3f(f, gmin[1], gmin[2]); glVertex3f(f, gmax[1], gmin[2]);
- glVertex3f(f, gmax[1], gmin[2]); glVertex3f(f, gmax[1], gmax[2]);
- glVertex3f(f, gmax[1], gmax[2]); glVertex3f(f, gmin[1], gmax[2]);
- glVertex3f(f, gmin[1], gmax[2]); glVertex3f(f, gmin[1], gmin[2]);
- }
- for (i = 1; i < res[1] - 1; ++i) {
- float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1));
- glVertex3f(gmin[0], f, gmin[2]); glVertex3f(gmax[0], f, gmin[2]);
- glVertex3f(gmax[0], f, gmin[2]); glVertex3f(gmax[0], f, gmax[2]);
- glVertex3f(gmax[0], f, gmax[2]); glVertex3f(gmin[0], f, gmax[2]);
- glVertex3f(gmin[0], f, gmax[2]); glVertex3f(gmin[0], f, gmin[2]);
- }
- for (i = 1; i < res[2] - 1; ++i) {
- float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1));
- glVertex3f(gmin[0], gmin[1], f); glVertex3f(gmax[0], gmin[1], f);
- glVertex3f(gmax[0], gmin[1], f); glVertex3f(gmax[0], gmax[1], f);
- glVertex3f(gmax[0], gmax[1], f); glVertex3f(gmin[0], gmax[1], f);
- glVertex3f(gmin[0], gmax[1], f); glVertex3f(gmin[0], gmin[1], f);
+ immUniformThemeColorShadeAlpha(TH_WIRE, 0, -100);
+
+ int count = 0;
+ count += MAX2(0, res[0] - 2) * 8;
+ count += MAX2(0, res[1] - 2) * 8;
+ count += MAX2(0, res[2] - 2) * 8;
+
+ if (count >= 2) {
+ glEnable(GL_BLEND);
+ immBegin(GWN_PRIM_LINES, count);
+ for (i = 1; i < res[0] - 1; ++i) {
+ float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1));
+ immVertex3f(pos_id, f, gmin[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmin[2]);
+ immVertex3f(pos_id, f, gmax[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmax[2]);
+ immVertex3f(pos_id, f, gmax[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmax[2]);
+ immVertex3f(pos_id, f, gmin[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmin[2]);
+ }
+ for (i = 1; i < res[1] - 1; ++i) {
+ float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1));
+ immVertex3f(pos_id, gmin[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmin[2]);
+ immVertex3f(pos_id, gmax[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmax[2]);
+ immVertex3f(pos_id, gmax[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmax[2]);
+ immVertex3f(pos_id, gmin[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmin[2]);
+ }
+ for (i = 1; i < res[2] - 1; ++i) {
+ float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1));
+ immVertex3f(pos_id, gmin[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmin[1], f);
+ immVertex3f(pos_id, gmax[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmax[1], f);
+ immVertex3f(pos_id, gmax[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmax[1], f);
+ immVertex3f(pos_id, gmin[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmin[1], f);
+ }
+ immEnd();
+ glDisable(GL_BLEND);
}
- glEnd();
- glDisable(GL_BLEND);
-
- glEnableClientState(GL_NORMAL_ARRAY);
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
+
+ immUnbindProgram();
}
}
}
@@ -5584,27 +6483,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
cache = psys->childcache;
for (a = 0; a < totchild; a++) {
path = cache[a];
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
- if (1) { //ob_dt > OB_WIRE) {
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT) {
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- }
- }
+ if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) {
+ draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL);
+ }
+ else {
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color);
}
-
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
/* restore & clean up */
- if (1) { //ob_dt > OB_WIRE) {
- if (part->draw_col == PART_DRAW_COL_MAT)
- glDisableClientState(GL_COLOR_ARRAY);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
-
if (cdata2) {
MEM_freeN(cdata2);
cdata2 = NULL;
@@ -5624,19 +6513,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) {
- glDisableClientState(GL_COLOR_ARRAY);
- /* enable point data array */
if (pdd->vdata) {
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
- }
- else
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (select) {
- UI_ThemeColor(TH_ACTIVE);
+ float color[4];
+ UI_GetThemeColor4fv(TH_ACTIVE, color);
if (part->draw_size)
glPointSize(part->draw_size + 2);
@@ -5645,48 +6526,39 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glLineWidth(3.0);
- draw_particle_arrays(draw_as, totpoint, ob_dt, 1);
+ draw_particle_arrays_new(draw_as, ob_dt, 1, pdd->vdata, NULL, NULL, totpoint, color);
}
- /* restore from select */
- glColor3fv(ma_col);
- }
-
- glPointSize(part->draw_size ? part->draw_size : 2.0);
- glLineWidth(1.0);
+ glPointSize(part->draw_size ? part->draw_size : 2.0);
+ glLineWidth(1.0);
- /* enable other data arrays */
- /* billboards are drawn this way */
- if (pdd->ndata && ob_dt > OB_WIRE) {
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, pdd->ndata);
- GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- }
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (pdd->cdata) {
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
+#if 0
+ /* enable other data arrays */
+ /* billboards are drawn this way */
+ if (pdd->ndata && ob_dt > OB_WIRE) {
+ GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
+ GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
}
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ if (pdd->cdata) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
+ }
+ }
+#endif
+
+ draw_particle_arrays_new(draw_as, ob_dt, 0, pdd->vdata, pdd->ndata, pdd->cdata, totpoint, NULL);
}
- draw_particle_arrays(draw_as, totpoint, ob_dt, 0);
pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
pdd->totpoint = totpoint;
}
if (pdd && pdd->vedata) {
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glDisableClientState(GL_COLOR_ARRAY);
- cpack(0xC0C0C0);
- }
-
- glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
-
- glDrawArrays(GL_LINES, 0, 2 * totve);
+ float color[4] = {0.75f, 0.75f, 0.75f, 1.0f};
+ draw_vertex_array(GWN_PRIM_LINES, pdd->vedata, NULL, NULL, 0, 2 * totve, color);
}
glPolygonMode(GL_FRONT, polygonmode[0]);
@@ -5695,9 +6567,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
/* 7. */
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
if (states)
MEM_freeN(states);
@@ -5720,32 +6589,28 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pdd->ma_col = NULL;
}
- if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
- glLoadMatrixf(rv3d->viewmat);
+ if ((ob->flag & OB_FROMGROUP) != 0) {
+ gpuLoadMatrix(rv3d->viewmat);
}
}
-static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit)
+static void draw_update_ptcache_edit(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit)
{
if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
- PE_update_object(scene, ob, 0);
+ PE_update_object(eval_ctx, scene, sl, ob, 0);
/* create path and child path cache if it doesn't exist already */
- if (edit->pathcache == NULL)
- psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering);
+ if (edit->pathcache == NULL) {
+ psys_cache_edit_paths(eval_ctx, scene, ob, edit, CFRA, G.is_rendering);
+ }
}
static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
{
- ParticleCacheKey **cache, *path, *pkey;
- PTCacheEditPoint *point;
- PTCacheEditKey *key;
ParticleEditSettings *pset = PE_settings(scene);
- int i, k, totpoint = edit->totpoint, timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : 0;
- int totkeys = 1;
- float sel_col[3];
- float nosel_col[3];
- float *pathcol = NULL, *pcol;
+ const int totpoint = edit->totpoint;
+ const bool timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : false;
if (edit->pathcache == NULL)
return;
@@ -5757,50 +6622,71 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glDisable(GL_DEPTH_TEST);
/* get selection theme colors */
+ float sel_col[3], nosel_col[3];
UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col);
UI_GetThemeColor3fv(TH_VERTEX, nosel_col);
/* draw paths */
- totkeys = (*edit->pathcache)->segments + 1;
+ const int totkeys = (*edit->pathcache)->segments + 1;
glEnable(GL_BLEND);
- pathcol = MEM_callocN(totkeys * 4 * sizeof(float), "particle path color data");
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
+ float *pathcol = MEM_callocN(totkeys * 4 * sizeof(float), "particle path color data");
if (pset->brushtype == PE_BRUSH_WEIGHT)
glLineWidth(2.0f);
- cache = edit->pathcache;
+ ParticleCacheKey **cache = edit->pathcache;
+ PTCacheEditPoint *point;
+ int i;
+
for (i = 0, point = edit->points; i < totpoint; i++, point++) {
- path = cache[i];
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+ ParticleCacheKey *path = cache[i];
+
+ Gwn_VertFormat format = {0};
+ unsigned int pos_id, col_id, col_comp;
+
+ col_comp = ((point->flag & PEP_HIDE) || timed) ? 4 : 3;
+
+ pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, col_comp, GWN_FETCH_FLOAT);
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, path->segments + 1);
+
+ GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(ParticleCacheKey), path->co);
+
+ float *pcol = pathcol;
if (point->flag & PEP_HIDE) {
- for (k = 0, pcol = pathcol; k < totkeys; k++, pcol += 4) {
+ for (int k = 0; k < totkeys; k++, pcol += 4) {
copy_v3_v3(pcol, path->col);
pcol[3] = 0.25f;
}
- glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
+ GWN_vertbuf_attr_fill(vbo, col_id, pathcol);
}
else if (timed) {
- for (k = 0, pcol = pathcol, pkey = path; k < totkeys; k++, pkey++, pcol += 4) {
+ ParticleCacheKey *pkey = path;
+ for (int k = 0; k < totkeys; k++, pkey++, pcol += 4) {
copy_v3_v3(pcol, pkey->col);
pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames;
}
- glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
+ GWN_vertbuf_attr_fill(vbo, col_id, pathcol);
+ }
+ else {
+ /* FIXME: shader wants 4 color components but the cache only contains ParticleCacheKey
+ * So alpha is random */
+ GWN_vertbuf_attr_fill_stride(vbo, col_id, sizeof(ParticleCacheKey), path->col);
}
- else
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
+ Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ GWN_batch_draw(batch);
+ GWN_batch_discard(batch);
}
- if (pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; }
-
+ if (pathcol) { MEM_freeN(pathcol); pathcol = NULL; }
/* draw edit vertices */
if (pset->selectmode != SCE_SELECT_PATH) {
@@ -5811,6 +6697,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
float *cd = NULL, *cdata = NULL;
int totkeys_visible = 0;
+ Gwn_VertFormat format = {0};
+ unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, (timed ? 4 : 3), GWN_FETCH_FLOAT);
+
for (i = 0, point = edit->points; i < totpoint; i++, point++)
if (!(point->flag & PEP_HIDE))
totkeys_visible += point->totkey;
@@ -5825,7 +6715,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (point->flag & PEP_HIDE)
continue;
- for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
+ PTCacheEditKey *key = point->keys;
+ for (int k = 0; k < point->totkey; k++, key++) {
if (pd) {
copy_v3_v3(pd, key->co);
pd += 3;
@@ -5850,14 +6741,20 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (point->flag & PEP_HIDE || point->totkey == 0)
continue;
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, point->totkey);
+
if (point->keys->flag & PEK_USE_WCO)
- glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co);
+ GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(PTCacheEditKey), point->keys->world_co);
else
- glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), pd);
+ GWN_vertbuf_attr_fill(vbo, pos_id, pd);
- glColorPointer((timed ? 4 : 3), GL_FLOAT, (timed ? 4 : 3) * sizeof(float), cd);
+ GWN_vertbuf_attr_fill(vbo, col_id, cd);
- glDrawArrays(GL_POINTS, 0, point->totkey);
+ Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ GWN_batch_draw(batch);
+ GWN_batch_discard(batch);
pd += pd ? 3 * point->totkey : 0;
cd += (timed ? 4 : 3) * point->totkey;
@@ -5866,23 +6763,30 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; }
}
else if (pset->selectmode == SCE_SELECT_END) {
- glBegin(GL_POINTS);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int col_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+ immBeginAtMost(GWN_PRIM_POINTS, totpoint);
for (i = 0, point = edit->points; i < totpoint; i++, point++) {
if ((point->flag & PEP_HIDE) == 0 && point->totkey) {
- key = point->keys + point->totkey - 1;
- glColor3fv((key->flag & PEK_SELECT) ? sel_col : nosel_col);
+ PTCacheEditKey *key = point->keys + point->totkey - 1;
+ if ((key->flag & PEK_SELECT) != 0) {
+ immAttrib3fv(col_id, sel_col);
+ }
+ else {
+ immAttrib3fv(col_id, nosel_col);
+ }
/* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
- glVertex3fv((key->flag & PEK_USE_WCO) ? key->world_co : key->co);
+ immVertex3fv(pos_id, (key->flag & PEK_USE_WCO) ? key->world_co : key->co);
}
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
glDisable(GL_BLEND);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -5895,130 +6799,137 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
float tw = itw * drw_size;
float th = ith * drw_size;
- glBegin(GL_LINES);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBegin(GWN_PRIM_LINES, 30);
- glColor4ub(0x7F, 0x00, 0x00, 155);
+ immAttrib4ub(col, 0x7F, 0x00, 0x00, 155);
root[1] = root[2] = 0.0f;
root[0] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[1] = tip[2] = 0.0f;
tip[0] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[1] = 0.0f; root[2] = tw;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = 0.0f; root[2] = -tw;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = tw; root[2] = 0.0f;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = -tw; root[2] = 0.0f;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glColor4ub(0x00, 0x7F, 0x00, 155);
+ immAttrib4ub(col, 0x00, 0x7F, 0x00, 155);
root[0] = root[2] = 0.0f;
root[1] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[0] = tip[2] = 0.0f;
tip[1] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[2] = tw;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[2] = -tw;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = tw; root[2] = 0.0f;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = -tw; root[2] = 0.0f;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glColor4ub(0x00, 0x00, 0x7F, 155);
+ immAttrib4ub(col, 0x00, 0x00, 0x7F, 155);
root[0] = root[1] = 0.0f;
root[2] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[0] = tip[1] = 0.0f;
tip[2] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[1] = tw;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[1] = -tw;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = tw; root[1] = 0.0f;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = -tw; root[1] = 0.0f;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* place to add drawers */
@@ -6027,7 +6938,7 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
{
if (nu->hide || hide_handles) return;
- if (nu->type == CU_BEZIER) {
+ if (nu->type == CU_BEZIER && nu->pntsu > 0) {
const float *fp;
@@ -6040,9 +6951,14 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
UI_GetThemeColor3ubv(basecol + a, handle_cols[a]);
}
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
glLineWidth(1.0f);
- glBegin(GL_LINES);
+ immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4);
BezTriple *bezt = nu->bezt;
int a = nu->pntsu;
@@ -6051,33 +6967,35 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
if ((bezt->f2 & SELECT) == sel) {
fp = bezt->vec[0];
- glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
- glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp + 3);
- glVertex3fv(fp + 6);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp + 3);
+ immVertex3fv(pos, fp + 6);
}
else if ((bezt->f1 & SELECT) == sel) {
fp = bezt->vec[0];
- glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
}
else if ((bezt->f3 & SELECT) == sel) {
fp = bezt->vec[1];
- glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
}
}
bezt++;
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
#undef TH_HANDLE_COL_TOT
@@ -6088,153 +7006,196 @@ static void drawhandlesN_active(Nurb *nu)
{
if (nu->hide) return;
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
-
- glBegin(GL_LINES);
+ if (nu->type == CU_BEZIER && nu->pntsu > 0) {
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
+ glLineWidth(2.0f);
- if (nu->type == CU_BEZIER) {
+ immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4);
BezTriple *bezt = nu->bezt;
int a = nu->pntsu;
while (a--) {
if (bezt->hide == 0) {
const float *fp = bezt->vec[0];
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
- glVertex3fv(fp + 3);
- glVertex3fv(fp + 6);
+ immVertex3fv(pos, fp + 3);
+ immVertex3fv(pos, fp + 6);
}
bezt++;
}
+ immEnd();
+ immUnbindProgram();
}
- glEnd();
-
- glColor3ub(0, 0, 0);
}
-static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, const void *vert)
+static void drawvertsN(const Nurb *nurb, const bool hide_handles, const void *vert)
{
- if (nu->hide) return;
+ const Nurb *nu;
+
+ // just quick guesstimate of how many verts to draw
+ int count = 0;
+ for (nu = nurb; nu; nu = nu->next) {
+ if (!nu->hide) {
+ if (nu->type == CU_BEZIER) {
+ count += nu->pntsu * 3;
+ }
+ else {
+ count += nu->pntsu * nu->pntsv;
+ }
+ }
+ }
+ if (count == 0) return;
- const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
- UI_ThemeColor(color);
+ unsigned char vert_color[3];
+ unsigned char vert_color_select[3];
+ unsigned char vert_color_active[3];
+ UI_GetThemeColor3ubv(TH_VERTEX, vert_color);
+ UI_GetThemeColor3ubv(TH_VERTEX_SELECT, vert_color_select);
+ UI_GetThemeColor3ubv(TH_ACTIVE_VERT, vert_color_active);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ immBeginAtMost(GWN_PRIM_POINTS, count);
- glBegin(GL_POINTS);
-
- if (nu->type == CU_BEZIER) {
+ for (nu = nurb; nu; nu = nu->next) {
- BezTriple *bezt = nu->bezt;
- int a = nu->pntsu;
- while (a--) {
- if (bezt->hide == 0) {
- if (sel == 1 && bezt == vert) {
- UI_ThemeColor(TH_ACTIVE_VERT);
+ if (nu->hide) continue;
- if (bezt->f2 & SELECT) glVertex3fv(bezt->vec[1]);
- if (!hide_handles) {
- if (bezt->f1 & SELECT) glVertex3fv(bezt->vec[0]);
- if (bezt->f3 & SELECT) glVertex3fv(bezt->vec[2]);
- }
+ if (nu->type == CU_BEZIER) {
- UI_ThemeColor(color);
- }
- else if (hide_handles) {
- if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
- }
- else {
- if ((bezt->f1 & SELECT) == sel) glVertex3fv(bezt->vec[0]);
- if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
- if ((bezt->f3 & SELECT) == sel) glVertex3fv(bezt->vec[2]);
+ const BezTriple *bezt = nu->bezt;
+ int a = nu->pntsu;
+ while (a--) {
+ if (bezt->hide == 0) {
+ if (bezt == vert) {
+ immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[1]);
+ if (!hide_handles) {
+ immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[0]);
+ immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[2]);
+ }
+ }
+ else {
+ immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[1]);
+ if (!hide_handles) {
+ immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[0]);
+ immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[2]);
+ }
+ }
}
+ bezt++;
}
- bezt++;
}
- }
- else {
- BPoint *bp = nu->bp;
- int a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->hide == 0) {
- if (bp == vert) {
- UI_ThemeColor(TH_ACTIVE_VERT);
- glVertex3fv(bp->vec);
- UI_ThemeColor(color);
- }
- else {
- if ((bp->f1 & SELECT) == sel) glVertex3fv(bp->vec);
+ else {
+ const BPoint *bp = nu->bp;
+ int a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->hide == 0) {
+ if (bp == vert) {
+ immAttrib3ubv(color, vert_color_active);
+ }
+ else {
+ immAttrib3ubv(color, bp->f1 & SELECT ? vert_color_select : vert_color);
+ }
+ immVertex3fv(pos, bp->vec);
}
+ bp++;
}
- bp++;
}
}
-
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
}
static void editnurb_draw_active_poly(Nurb *nu)
{
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
+
+ glLineWidth(2.0f);
BPoint *bp = nu->bp;
for (int b = 0; b < nu->pntsv; b++) {
- if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
+ if (nu->pntsu >= 2) {
+ if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu);
+ else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu);
- for (int a = 0; a < nu->pntsu; a++, bp++) {
- glVertex3fv(bp->vec);
- }
+ for (int a = 0; a < nu->pntsu; a++, bp++) {
+ immVertex3fv(pos, bp->vec);
+ }
- glEnd();
+ immEnd();
+ }
}
- glColor3ub(0, 0, 0);
+ immUnbindProgram();
}
static void editnurb_draw_active_nurbs(Nurb *nu)
{
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
-
- glBegin(GL_LINES);
- BPoint *bp = nu->bp;
- for (int b = 0; b < nu->pntsv; b++) {
- BPoint *bp1 = bp;
- bp++;
+ if (nu->pntsv > 0) {
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
- for (int a = nu->pntsu - 1; a > 0; a--, bp++) {
- if (bp->hide == 0 && bp1->hide == 0) {
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
- }
- bp1 = bp;
- }
- }
+ glLineWidth(2.0f);
+ // just quick guesstimate of how many verts to draw
+ int count = (nu->pntsu - 1) * nu->pntsv * 2;
+ if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2;
+ if (count < 2) return;
- if (nu->pntsv > 1) { /* surface */
+ immBeginAtMost(GWN_PRIM_LINES, count);
+ BPoint *bp = nu->bp;
+ for (int b = 0; b < nu->pntsv; b++) {
+ BPoint *bp1 = bp;
+ bp++;
- int ofs = nu->pntsu;
- for (int b = 0; b < nu->pntsu; b++) {
- BPoint *bp1 = nu->bp + b;
- bp = bp1 + ofs;
- for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
+ for (int a = nu->pntsu - 1; a > 0; a--, bp++) {
if (bp->hide == 0 && bp1->hide == 0) {
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
bp1 = bp;
}
}
- }
- glEnd();
+ if (nu->pntsv > 1) { /* surface */
+ int ofs = nu->pntsu;
+ for (int b = 0; b < nu->pntsu; b++) {
+ BPoint *bp1 = nu->bp + b;
+ bp = bp1 + ofs;
+ for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
+ if (bp->hide == 0 && bp1->hide == 0) {
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
+ }
+ bp1 = bp;
+ }
+ }
+ }
+
+ immEnd();
- glColor3ub(0, 0, 0);
+ immUnbindProgram();
+ }
}
static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
@@ -6242,6 +7203,9 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
BPoint *bp, *bp1;
int a, b;
Curve *cu = ob->data;
+ Gwn_VertFormat *format;
+ unsigned int pos, col;
+ unsigned char color[3];
int index = 0;
Nurb *nu = nurb;
@@ -6249,35 +7213,55 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (nu->hide == 0) {
switch (nu->type) {
case CU_POLY:
+ {
if (!sel && index == cu->actnu) {
/* we should draw active spline highlight below everything */
editnurb_draw_active_poly(nu);
}
- glLineWidth(1);
+ format = immVertexFormat();
+ pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ glLineWidth(1.0f);
- UI_ThemeColor(TH_NURB_ULINE);
+ immUniformThemeColor(TH_NURB_ULINE);
bp = nu->bp;
for (b = 0; b < nu->pntsv; b++) {
- if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
+ if (nu->pntsu >= 2) {
+ if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu);
+ else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu);
- for (a = 0; a < nu->pntsu; a++, bp++) {
- glVertex3fv(bp->vec);
- }
+ for (a = 0; a < nu->pntsu; a++, bp++) {
+ immVertex3fv(pos, bp->vec);
+ }
- glEnd();
+ immEnd();
+ }
}
+ immUnbindProgram();
break;
+ }
case CU_NURBS:
+ {
if (!sel && index == cu->actnu) {
/* we should draw active spline highlight below everything */
editnurb_draw_active_nurbs(nu);
}
- glLineWidth(1);
+ format = immVertexFormat();
+ pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ // just quick guesstimate of how many verts to draw
+ int count = (nu->pntsu - 1) * nu->pntsv * 2;
+ if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2;
+ if (count < 2) return;
- glBegin(GL_LINES);
+ glLineWidth(1.0f);
+
+ immBeginAtMost(GWN_PRIM_LINES, count);
bp = nu->bp;
for (b = 0; b < nu->pntsv; b++) {
@@ -6287,10 +7271,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (bp->hide == 0 && bp1->hide == 0) {
if (sel) {
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
- UI_ThemeColor(TH_NURB_SEL_ULINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_SEL_ULINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
else {
@@ -6298,10 +7282,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
/* pass */
}
else {
- UI_ThemeColor(TH_NURB_ULINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_ULINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
}
@@ -6318,10 +7302,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (bp->hide == 0 && bp1->hide == 0) {
if (sel) {
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
- UI_ThemeColor(TH_NURB_SEL_VLINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_SEL_VLINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
else {
@@ -6329,10 +7313,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
/* pass */
}
else {
- UI_ThemeColor(TH_NURB_VLINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_VLINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
}
@@ -6340,9 +7324,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
}
}
}
-
- glEnd();
+ immEnd();
+ immUnbindProgram();
break;
+ }
}
}
@@ -6352,8 +7337,9 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
}
static void draw_editnurb(
- Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
+ const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4]))
{
ToolSettings *ts = scene->toolsettings;
Object *ob = base->object;
@@ -6365,9 +7351,8 @@ static void draw_editnurb(
/* DispList */
UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col);
- glColor3ubv(wire_col);
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
/* for shadows only show solid faces */
if (v3d->flag2 & V3D_RENDER_SHADOW)
@@ -6391,79 +7376,110 @@ static void draw_editnurb(
for (nu = nurb; nu; nu = nu->next) {
if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
drawhandlesN(nu, 1, hide_handles);
- drawvertsN(nu, 0, hide_handles, NULL);
}
if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
- glColor3ubv(wire_col);
-
/* direction vectors for 3d curve paths
* when at its lowest, don't render normals */
if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) {
BevList *bl;
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_WIRE_EDIT);
+
glLineWidth(1.0f);
+
+ int count = 0;
+ int count_used = 0;
for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
- BevPoint *bevp = bl->bevpoints;
int nr = bl->nr;
int skip = nu->resolu / 16;
-
+
+#if 0
while (nr-- > 0) { /* accounts for empty bevel lists */
- const float fac = bevp->radius * ts->normalsize;
- float vec_a[3]; /* Offset perpendicular to the curve */
- float vec_b[3]; /* Delta along the curve */
+ count += 4;
+ nr -= skip;
+ }
+#else
+ /* Same as loop above */
+ count += 4 * max_ii((nr + max_ii(skip - 1, 0)) / (skip + 1), 0);
+#endif
+ }
- vec_a[0] = fac;
- vec_a[1] = 0.0f;
- vec_a[2] = 0.0f;
-
- mul_qt_v3(bevp->quat, vec_a);
- madd_v3_v3fl(vec_a, bevp->dir, -fac);
+ if (count > 2) {
+ immBegin(GWN_PRIM_LINES, count);
+ for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
+ BevPoint *bevp = bl->bevpoints;
+ int nr = bl->nr;
+ int skip = nu->resolu / 16;
- reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
- negate_v3(vec_b);
+ while (nr-- > 0) { /* accounts for empty bevel lists */
+ const float fac = bevp->radius * ts->normalsize;
+ float vec_a[3]; /* Offset perpendicular to the curve */
+ float vec_b[3]; /* Delta along the curve */
- add_v3_v3(vec_a, bevp->vec);
- add_v3_v3(vec_b, bevp->vec);
+ vec_a[0] = fac;
+ vec_a[1] = 0.0f;
+ vec_a[2] = 0.0f;
+
+ mul_qt_v3(bevp->quat, vec_a);
+ madd_v3_v3fl(vec_a, bevp->dir, -fac);
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec_a);
- glVertex3fv(bevp->vec);
- glVertex3fv(vec_b);
- glEnd();
-
- bevp += skip + 1;
- nr -= skip;
+ reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
+ negate_v3(vec_b);
+
+ add_v3_v3(vec_a, bevp->vec);
+ add_v3_v3(vec_b, bevp->vec);
+
+ immVertex3fv(pos, vec_a);
+ immVertex3fv(pos, bevp->vec);
+ immVertex3fv(pos, bevp->vec);
+ immVertex3fv(pos, vec_b);
+
+ bevp += skip + 1;
+ nr -= skip;
+ count_used += 4;
+ }
}
+ BLI_assert(count == count_used);
+ UNUSED_VARS_NDEBUG(count_used);
+
+ immEnd();
}
+ immUnbindProgram();
}
- if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
-
- for (nu = nurb; nu; nu = nu->next) {
- drawvertsN(nu, 1, hide_handles, vert);
- }
-
- if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ drawvertsN(nurb, hide_handles, vert);
+
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2])
{
- cpack(0);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
ED_view3d_polygon_offset(rv3d, -1.0);
set_inverted_drawing(1);
- glBegin(GL_QUADS);
- glVertex2fv(textcurs[0]);
- glVertex2fv(textcurs[1]);
- glVertex2fv(textcurs[2]);
- glVertex2fv(textcurs[3]);
- glEnd();
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ imm_cpack(0);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
+ immVertex2fv(pos, textcurs[0]);
+ immVertex2fv(pos, textcurs[1]);
+ immVertex2fv(pos, textcurs[2]);
+ immVertex2fv(pos, textcurs[3]);
+ immEnd();
set_inverted_drawing(0);
ED_view3d_polygon_offset(rv3d, 0.0);
+ immUnbindProgram();
}
-static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static void draw_editfont(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
Curve *cu = ob->data;
@@ -6473,17 +7489,19 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
draw_editfont_textcurs(rv3d, ef->textcurs);
if (cu->flag & CU_FAST) {
- cpack(0xFFFFFF);
+ imm_cpack(0xFFFFFF);
set_inverted_drawing(1);
- drawDispList(scene, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
set_inverted_drawing(0);
}
else {
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
if (cu->linewidth != 0.0f) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_WIRE_EDIT);
copy_v3_v3(vec1, ob->orig);
copy_v3_v3(vec2, ob->orig);
vec1[0] += cu->linewidth;
@@ -6491,31 +7509,35 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
vec1[1] += cu->linedist * cu->fsize;
vec2[1] -= cu->lines * cu->linedist * cu->fsize;
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex2fv(vec1);
- glVertex2fv(vec2);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex2fv(pos, vec1);
+ immVertex2fv(pos, vec2);
+ immEnd();
setlinestyle(0);
+ immUnbindProgram();
}
setlinestyle(3);
for (int i = 0; i < cu->totbox; i++) {
if (cu->tb[i].w != 0.0f) {
- UI_ThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE);
vec1[0] = cu->xof + cu->tb[i].x;
vec1[1] = cu->yof + cu->tb[i].y + cu->fsize;
vec1[2] = 0.001;
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec1);
+ immBegin(GWN_PRIM_LINE_STRIP, 5);
+ immVertex3fv(pos, vec1);
vec1[0] += cu->tb[i].w;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[1] -= cu->tb[i].h;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[0] -= cu->tb[i].w;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[1] += cu->tb[i].h;
- glVertex3fv(vec1);
- glEnd();
+ immVertex3fv(pos, vec1);
+ immEnd();
+ immUnbindProgram();
}
}
setlinestyle(0);
@@ -6524,7 +7546,9 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
if (ef->selboxes && ef->selboxes_len) {
float selboxw;
- cpack(0xffffff);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ imm_cpack(0xffffff);
set_inverted_drawing(1);
for (int i = 0; i < ef->selboxes_len; i++) {
EditFontSelBox *sb = &ef->selboxes[i];
@@ -6543,20 +7567,20 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
/* fill in xy below */
tvec[2] = 0.001;
- glBegin(GL_QUADS);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
if (sb->rot == 0.0f) {
copy_v2_fl2(tvec, sb->x, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x + selboxw, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x + selboxw, sb->y + sb->h);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x, sb->y + sb->h);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
}
else {
float mat[2][2];
@@ -6564,84 +7588,87 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
angle_to_mat2(mat, sb->rot);
copy_v2_fl2(tvec, sb->x, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, selboxw, 0.0f);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, selboxw, sb->h);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, 0.0f, sb->h);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
}
- glEnd();
+ immEnd();
}
set_inverted_drawing(0);
+ immUnbindProgram();
}
}
/* draw a sphere for use as an empty drawtype */
-static void draw_empty_sphere(float size)
-{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glPushMatrix();
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- glRotatef(90, 0, 1, 0);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- glRotatef(90, 1, 0, 0);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- gluDeleteQuadric(qobj);
-
- glPopMatrix();
- glEndList();
- }
-
- glScalef(size, size, size);
- glCallList(displist);
- glScalef(1.0f / size, 1.0f / size, 1.0f / size);
+static void draw_empty_sphere(float size, unsigned pos)
+{
+#define NSEGMENTS 16
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = size * cosf(angle);
+ p[i][1] = size * sinf(angle);
+ }
+
+ immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], p[i][1], 0.0f);
+ immEnd();
+ immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ immEnd();
+ immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, 0.0f, p[i][0], p[i][1]);
+ immEnd();
+#undef NSEGMENTS
}
/* draw a cone for use as an empty drawtype */
-static void draw_empty_cone(float size)
+static void draw_empty_cone(float size, unsigned pos)
{
- const float radius = size;
+#define NSEGMENTS 8
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = size * cosf(angle);
+ p[i][1] = size * sinf(angle);
+ }
- GLUquadricObj *qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
- glPushMatrix();
-
- glScalef(radius, size * 2.0f, radius);
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
+ /* cone sides */
+ immBegin(GWN_PRIM_LINES, NSEGMENTS * 2);
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ immVertex3f(pos, 0.0f, 2.0f * size, 0.0f);
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ }
+ immEnd();
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
+ /* end ring */
+ immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ immEnd();
+#undef NSEGMENTS
}
-static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
+static void drawspiral(unsigned int pos, const float cent[3], float rad, float tmat[4][4], int start)
{
float vec[3], vx[3], vy[3];
const float tot_inv = 1.0f / (float)CIRCLE_RESOL;
@@ -6657,11 +7684,11 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
mul_v3_v3fl(vx, tmat[0], rad);
mul_v3_v3fl(vy, tmat[1], rad);
- glBegin(GL_LINE_STRIP);
+ immBegin(GWN_PRIM_LINE_STRIP, CIRCLE_RESOL + 1);
if (inverse == 0) {
copy_v3_v3(vec, cent);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
for (a = 0; a < CIRCLE_RESOL; a++) {
if (a + start >= CIRCLE_RESOL)
@@ -6675,7 +7702,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
}
}
else {
@@ -6687,7 +7714,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
for (a = 0; a < CIRCLE_RESOL; a++) {
if (a + start >= CIRCLE_RESOL)
@@ -6700,79 +7727,79 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[0] = cent[0] + (x * vx[0] + y * vy[0]);
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
}
}
- glEnd();
+ immEnd();
}
/* draws a circle on x-z plane given the scaling of the circle, assuming that
* all required matrices have been set (used for drawing empties) */
-static void drawcircle_size(float size)
+static void drawcircle_size(float size, unsigned pos)
{
- glBegin(GL_LINE_LOOP);
+ immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL);
/* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */
for (short degrees = 0; degrees < CIRCLE_RESOL; degrees++) {
float x = cosval[degrees];
float y = sinval[degrees];
-
- glVertex3f(x * size, 0.0f, y * size);
+
+ immVertex3f(pos, x * size, 0.0f, y * size);
}
-
- glEnd();
+ immEnd();
}
/* needs fixing if non-identity matrix used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[4][4])
+static void imm_drawtube(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos)
{
float cur[3];
- drawcircball(GL_LINE_LOOP, vec, radius, tmat);
+ imm_drawcircball(vec, radius, tmat, pos);
copy_v3_v3(cur, vec);
cur[2] += height;
- drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+ imm_drawcircball(cur, radius, tmat, pos);
- glBegin(GL_LINES);
- glVertex3f(vec[0] + radius, vec[1], vec[2]);
- glVertex3f(cur[0] + radius, cur[1], cur[2]);
- glVertex3f(vec[0] - radius, vec[1], vec[2]);
- glVertex3f(cur[0] - radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1] + radius, vec[2]);
- glVertex3f(cur[0], cur[1] + radius, cur[2]);
- glVertex3f(vec[0], vec[1] - radius, vec[2]);
- glVertex3f(cur[0], cur[1] - radius, cur[2]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 8);
+ immVertex3f(pos, vec[0] + radius, vec[1], vec[2]);
+ immVertex3f(pos, cur[0] + radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0] - radius, vec[1], vec[2]);
+ immVertex3f(pos, cur[0] - radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1] + radius, vec[2]);
+ immVertex3f(pos, cur[0], cur[1] + radius, cur[2]);
+ immVertex3f(pos, vec[0], vec[1] - radius, vec[2]);
+ immVertex3f(pos, cur[0], cur[1] - radius, cur[2]);
+ immEnd();
}
/* needs fixing if non-identity matrix used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[4][4])
+static void imm_drawcone(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos)
{
float cur[3];
copy_v3_v3(cur, vec);
cur[2] += height;
- drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+ imm_drawcircball(cur, radius, tmat, pos);
- glBegin(GL_LINES);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0] + radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0] - radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0], cur[1] + radius, cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0], cur[1] - radius, cur[2]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 8);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0] + radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0] - radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0], cur[1] + radius, cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0], cur[1] - radius, cur[2]);
+ immEnd();
}
/* return true if nothing was drawn */
-static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static bool drawmball(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
MetaElem *ml;
@@ -6785,15 +7812,13 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if ((G.f & G_PICKSEL) == 0) {
unsigned char wire_col[4];
UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col);
- glColor3ubv(wire_col);
-
- drawDispList(scene, v3d, rv3d, base, dt, dflag, wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
}
ml = mb->editelems->first;
}
else {
- if ((base->flag & OB_FROMDUPLI) == 0) {
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ if ((base->flag_legacy & OB_FROMDUPLI) == 0) {
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
ml = mb->elems.first;
}
@@ -6810,20 +7835,25 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
normalize_v3(imat[0]);
normalize_v3(imat[1]);
+#if 0 /* no purpose? */
if (mb->editelems == NULL) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
glColor3ubv(ob_wire_col);
}
}
-
+#endif
+
glLineWidth(1.0f);
+ const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
while (ml) {
/* draw radius */
if (mb->editelems) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) cpack(0xA0A0F0);
- else cpack(0x3030A0);
+ if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0A0F0);
+ else imm_cpack(0x3030A0);
}
if (G.f & G_PICKSEL) {
@@ -6831,24 +7861,26 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
GPU_select_load_id(code++);
}
}
- drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat);
+ imm_drawcircball(&(ml->x), ml->rad, imat, pos);
/* draw stiffness */
if (mb->editelems) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) cpack(0xA0F0A0);
- else cpack(0x30A030);
+ if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0F0A0);
+ else imm_cpack(0x30A030);
}
if (G.f & G_PICKSEL) {
ml->selcol2 = code;
GPU_select_load_id(code++);
}
- drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat);
+ imm_drawcircball(&(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat, pos);
}
ml = ml->next;
}
+
+ immUnbindProgram();
return false;
}
@@ -6858,6 +7890,7 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
PartDeflect *pd = ob->pd;
float imat[4][4], tmat[4][4];
float vec[3] = {0.0, 0.0, 0.0};
+ float draw_color[3] = {0.0f, 0.0f, 0.0f};
/* scale size of circle etc with the empty drawsize */
const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
@@ -6867,35 +7900,53 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */
normalize_v3(imat[1]);
#endif
+
+ const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3fv(draw_color);
if (pd->forcefield == PFIELD_WIND) {
float force_val = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
unit_m4(tmat);
force_val *= 0.1f;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 0.5f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 1.0f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 1.5f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 0.0f; /* reset vec for max dist circle */
-
}
else if (pd->forcefield == PFIELD_FORCE) {
float ffall_val = pd->f_power;
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
- drawcircball(GL_LINE_LOOP, vec, size, imat);
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val));
- drawcircball(GL_LINE_LOOP, vec, size * 1.5f, imat);
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val));
- drawcircball(GL_LINE_LOOP, vec, size * 2.0f, imat);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size, imat, pos);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val), draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size * 1.5f, imat, pos);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val), draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size * 2.0f, imat, pos);
}
else if (pd->forcefield == PFIELD_VORTEX) {
float force_val = pd->f_strength;
@@ -6903,16 +7954,17 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
unit_m4(tmat);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f, draw_color);
+ immUniformColor3fv(draw_color);
}
if (force_val < 0) {
- drawspiral(vec, size, tmat, 1);
- drawspiral(vec, size, tmat, 16);
+ drawspiral(pos, vec, size, tmat, 1);
+ drawspiral(pos, vec, size, tmat, 16);
}
else {
- drawspiral(vec, size, tmat, -1);
- drawspiral(vec, size, tmat, -16);
+ drawspiral(pos, vec, size, tmat, -1);
+ drawspiral(pos, vec, size, tmat, -16);
}
}
else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) {
@@ -6922,18 +7974,19 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
float mindist = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
/* path end */
setlinestyle(3);
where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL);
- drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
+ imm_drawcircball(guidevec1, mindist, imat, pos);
/* path beginning */
setlinestyle(0);
where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL);
- drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
+ imm_drawcircball(guidevec1, mindist, imat, pos);
copy_v3_v3(vec, guidevec1); /* max center */
}
@@ -6942,16 +7995,19 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
setlinestyle(3);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
if (pd->falloff == PFIELD_FALL_SPHERE) {
/* as last, guide curve alters it */
- if (pd->flag & PFIELD_USEMAX)
- drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat);
+ if ((pd->flag & PFIELD_USEMAX) != 0) {
+ imm_drawcircball(vec, pd->maxdist, imat, pos);
+ }
- if (pd->flag & PFIELD_USEMIN)
- drawcircball(GL_LINE_LOOP, vec, pd->mindist, imat);
+ if ((pd->flag & PFIELD_USEMIN) != 0) {
+ imm_drawcircball(vec, pd->mindist, imat, pos);
+ }
}
else if (pd->falloff == PFIELD_FALL_TUBE) {
float radius, distance;
@@ -6964,16 +8020,18 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
vec[2] = distance;
distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance;
- if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR))
- drawtube(vec, radius, distance, tmat);
+ if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+ imm_drawtube(vec, radius, distance, tmat, pos);
+ }
radius = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
vec[2] = distance;
distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance;
- if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR))
- drawtube(vec, radius, distance, tmat);
+ if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+ imm_drawtube(vec, radius, distance, tmat, pos);
+ }
}
else if (pd->falloff == PFIELD_FALL_CONE) {
float radius, distance;
@@ -6984,46 +8042,54 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
- drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos);
if ((pd->flag & PFIELD_POSZ) == 0)
- drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos);
}
radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
- drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos);
if ((pd->flag & PFIELD_POSZ) == 0)
- drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos);
}
}
setlinestyle(0);
+
+ immUnbindProgram();
}
-static void draw_box(const float vec[8][3], bool solid)
+static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos)
{
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vec);
-
if (solid) {
- const GLubyte indices[24] = {0,1,2,3,7,6,5,4,4,5,1,0,3,2,6,7,3,7,4,0,1,5,6,2};
- glDrawRangeElements(GL_QUADS, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
+ /* Adpated from "Optimizing Triangle Strips for Fast Rendering" by F. Evans, S. Skiena and A. Varshney
+ * (http://www.cs.umd.edu/gvil/papers/av_ts.pdf). */
+ static const GLubyte tris_strip_indices[14] = {0,1,3,2,6,1,5,0,4,3,7,6,4,5};
+ immBegin(GWN_PRIM_TRI_STRIP, 14);
+ for (int i = 0; i < 14; ++i) {
+ immVertex3fv(pos, vec[tris_strip_indices[i]]);
+ }
+ immEnd();
}
else {
- const GLubyte indices[24] = {0,1,1,2,2,3,3,0,0,4,4,5,5,6,6,7,7,4,1,5,2,6,3,7};
- glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
+ static const GLubyte line_indices[24] = {0,1,1,2,2,3,3,0,0,4,4,5,5,6,6,7,7,4,1,5,2,6,3,7};
+ immBegin(GWN_PRIM_LINES, 24);
+ for (int i = 0; i < 24; ++i) {
+ immVertex3fv(pos, vec[line_indices[i]]);
+ }
+ immEnd();
}
- glDisableClientState(GL_VERTEX_ARRAY);
}
-static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
+static void imm_draw_bb(BoundBox *bb, char type, bool around_origin, const unsigned char ob_wire_col[4])
{
float size[3], cent[3];
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ Gwn_Batch *sphere = GPU_batch_preset_sphere_wire(0);
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) GWN_batch_uniform_4f(sphere, "color", ob_wire_col[0] / 255.0f, ob_wire_col[1] / 255.0f, ob_wire_col[2] / 255.0f, 1.0f);
BKE_boundbox_calc_size_aabb(bb, size);
@@ -7034,40 +8100,51 @@ static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
BKE_boundbox_calc_center_aabb(bb, cent);
}
- glPushMatrix();
+ gpuPushMatrix();
+
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
if (type == OB_BOUND_SPHERE) {
float scale = MAX3(size[0], size[1], size[2]);
- glTranslate3fv(cent);
- glScalef(scale, scale, scale);
- gluSphere(qobj, 1.0, 8, 5);
+ gpuTranslate3fv(cent);
+ gpuRotateAxis(90, 'X');
+ gpuScaleUniform(scale);
+ GWN_batch_draw(sphere);
}
else if (type == OB_BOUND_CYLINDER) {
float radius = size[0] > size[1] ? size[0] : size[1];
- glTranslatef(cent[0], cent[1], cent[2] - size[2]);
- glScalef(radius, radius, 2.0f * size[2]);
- gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]);
+ gpuScale3f(radius, radius, 2.0f * size[2]);
+ imm_draw_cylinder_wire_3d(pos, 1.0f, 1.0f, 1.0f, 8, 1);
}
else if (type == OB_BOUND_CONE) {
float radius = size[0] > size[1] ? size[0] : size[1];
- glTranslatef(cent[0], cent[1], cent[2] - size[2]);
- glScalef(radius, radius, 2.0f * size[2]);
- gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]);
+ gpuScale3f(radius, radius, 2.0f * size[2]);
+ imm_draw_cylinder_wire_3d(pos, 1.0f, 0.0f, 1.0f, 8, 1);
+
}
else if (type == OB_BOUND_CAPSULE) {
float radius = size[0] > size[1] ? size[0] : size[1];
float length = size[2] > radius ? 2.0f * (size[2] - radius) : 0.0f;
- glTranslatef(cent[0], cent[1], cent[2] - length * 0.5f);
- gluCylinder(qobj, radius, radius, length, 8, 1);
- gluSphere(qobj, radius, 8, 4);
- glTranslatef(0.0, 0.0, length);
- gluSphere(qobj, radius, 8, 4);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - length * 0.5f);
+ imm_draw_cylinder_wire_3d(pos, radius, radius, length, 8, 1);
+
+ gpuRotateAxis(90, 'X');
+ gpuScaleUniform(radius);
+ GWN_batch_draw(sphere);
+
+ gpuTranslate3f(0.0f, length / radius, 0.0f);
+ GWN_batch_draw(sphere);
}
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
+
+ gpuPopMatrix();
+ immUnbindProgram();
}
-static void draw_bounding_volume(Object *ob, char type)
+void draw_bounding_volume(Object *ob, char type, const unsigned char ob_wire_col[4])
{
BoundBox bb_local;
BoundBox *bb = NULL;
@@ -7097,12 +8174,16 @@ static void draw_bounding_volume(Object *ob, char type)
if (bb == NULL)
return;
-
+
if (ob->gameflag & OB_BOUNDS) { /* bounds need to be drawn around origin for game engine */
if (type == OB_BOUND_BOX) {
float vec[8][3], size[3];
-
+
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
BKE_boundbox_calc_size_aabb(bb, size);
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
@@ -7112,21 +8193,31 @@ static void draw_bounding_volume(Object *ob, char type)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec, false);
+ imm_draw_box(vec, false, pos);
+
+ immUnbindProgram();
}
else {
- draw_bb_quadric(bb, type, true);
+ imm_draw_bb(bb, type, true, ob_wire_col);
}
}
else {
- if (type == OB_BOUND_BOX)
- draw_box(bb->vec, false);
+ if (type == OB_BOUND_BOX) {
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
+ imm_draw_box(bb->vec, false, pos);
+
+ immUnbindProgram();
+ }
else
- draw_bb_quadric(bb, type, false);
+ imm_draw_bb(bb, type, false, ob_wire_col);
}
+
}
-static void drawtexspace(Object *ob)
+static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3])
{
float vec[8][3], loc[3], size[3];
@@ -7156,26 +8247,38 @@ static void drawtexspace(Object *ob)
setlinestyle(2);
- draw_box(vec, false);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ if (ob_wire_col) {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ }
+
+ imm_draw_box(vec, false, pos);
+
+ immUnbindProgram();
setlinestyle(0);
}
/* draws wire outline */
static void draw_object_selected_outline(
- Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const unsigned char ob_wire_col[4])
{
RegionView3D *rv3d = ar->regiondata;
Object *ob = base->object;
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
bool has_faces = false;
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, ob);
+ ensure_curve_cache(eval_ctx, scene, ob);
#endif
DerivedMesh *dm = ob->derivedFinal;
@@ -7193,46 +8296,41 @@ static void draw_object_selected_outline(
if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
if (dm) {
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
else {
/* only draw 'solid' parts of the display list as wire. */
- drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF));
+ drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF), ob_wire_col);
}
}
}
else if (ob->type == OB_MBALL) {
if (BKE_mball_is_basis(ob)) {
- if ((base->flag & OB_FROMDUPLI) == 0) {
+ if ((base->flag_legacy & OB_FROMDUPLI) == 0) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, ob_wire_col);
}
}
}
else if (ob->type == OB_ARMATURE) {
- if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) {
+ if (!(ob->mode & OB_MODE_POSE && base == sl->basact)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- draw_armature(scene, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
+ draw_armature(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
}
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
{
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
-
- if (scene->obedit == ob) {
- UI_ThemeColor(TH_WIRE_EDIT);
- }
- else {
- glColor3ubv(ob_wire_col);
- }
+ unsigned char wire_edit_col[4];
+ UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_edit_col);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
- glLineWidth(1);
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
+ glLineWidth(1.0f);
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
@@ -7241,23 +8339,23 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const
drawCurveDMWired(ob);
}
else {
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
}
}
}
else if (ob->type == OB_MBALL) {
if (BKE_mball_is_basis(ob)) {
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
}
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
}
}
/* should be called in view space */
-static void draw_hooks(Object *ob)
+static void draw_hooks(Object *ob, unsigned int pos)
{
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Hook) {
@@ -7268,17 +8366,17 @@ static void draw_hooks(Object *ob)
if (hmd->object) {
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(hmd->object->obmat[3]);
- glVertex3fv(vec);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, hmd->object->obmat[3]);
+ immVertex3fv(pos, vec);
+ immEnd();
setlinestyle(0);
}
- glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex3fv(vec);
- glEnd();
+ glPointSize(3.0f);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
}
}
}
@@ -7289,9 +8387,16 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
const char *axis_str[3] = {"px", "py", "pz"};
float mat[4][4];
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
eul_to_mat4(mat, &data->axX);
glLineWidth(4.0f);
setlinestyle(2);
+
+ immBegin(GWN_PRIM_LINES, 6);
for (int axis = 0; axis < 3; axis++) {
float dir[3] = {0, 0, 0};
float v[3];
@@ -7299,12 +8404,10 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
copy_v3_v3(v, &data->pivX);
dir[axis] = 1.0f;
- glBegin(GL_LINES);
mul_m4_v3(mat, dir);
add_v3_v3(v, dir);
- glVertex3fv(&data->pivX);
- glVertex3fv(v);
- glEnd();
+ immVertex3fv(pos, &data->pivX);
+ immVertex3fv(pos, v);
/* when const color is set wirecolor is NULL - we could get the current color but
* with selection and group instancing its not needed to draw the text */
@@ -7312,11 +8415,15 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
view3d_cached_text_draw_add(v, axis_str[axis], 2, 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
}
}
+ immEnd();
setlinestyle(0);
+ glLineWidth(1.0f);
+
+ immUnbindProgram();
}
-static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_wire_col[4])
+void draw_object_wire_color(Scene *scene, SceneLayer *sl, Base *base, unsigned char r_ob_wire_col[4])
{
Object *ob = base->object;
int colindex = 0;
@@ -7330,23 +8437,23 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
if ((scene->obedit == NULL) &&
(G.moving & G_TRANSFORM_OBJ) &&
- (base->flag & (SELECT + BA_WAS_SEL)))
+ ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)))
{
theme_id = TH_TRANSFORM;
}
else {
/* Sets the 'colindex' */
if (ID_IS_LINKED(ob)) {
- colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 2 : 1;
+ colindex = ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) ? 2 : 1;
}
/* Sets the 'theme_id' or fallback to wire */
else {
- if (ob->flag & OB_FROMGROUP) {
- if (base->flag & (SELECT + BA_WAS_SEL)) {
+ if ((ob->flag & OB_FROMGROUP) != 0) {
+ if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
/* uses darker active color for non-active + selected */
theme_id = TH_GROUP_ACTIVE;
- if (scene->basact != base) {
+ if (sl->basact != base) {
theme_shade = -32;
}
}
@@ -7355,8 +8462,8 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
}
}
else {
- if (base->flag & (SELECT + BA_WAS_SEL)) {
- theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT;
+ if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
+ theme_id = sl->basact == base ? TH_ACTIVE : TH_SELECT;
}
else {
if (ob->type == OB_LAMP) theme_id = TH_LAMP;
@@ -7410,10 +8517,11 @@ static void draw_object_matcap_check(View3D *v3d, Object *ob)
v3d->flag2 |= V3D_SHOW_SOLID_MATCAP;
}
-static void draw_rigidbody_shape(Object *ob)
+void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4])
{
BoundBox *bb = NULL;
float size[3], vec[8][3];
+ unsigned int pos;
if (ob->type == OB_MESH) {
bb = BKE_mesh_boundbox_get(ob);
@@ -7426,6 +8534,10 @@ static void draw_rigidbody_shape(Object *ob)
case RB_SHAPE_BOX:
BKE_boundbox_calc_size_aabb(bb, size);
+ pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0];
vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1];
@@ -7433,19 +8545,20 @@ static void draw_rigidbody_shape(Object *ob)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec, false);
+ imm_draw_box(vec, false, pos);
+ immUnbindProgram();
break;
case RB_SHAPE_SPHERE:
- draw_bb_quadric(bb, OB_BOUND_SPHERE, true);
+ imm_draw_bb(bb, OB_BOUND_SPHERE, true, ob_wire_col);
break;
case RB_SHAPE_CONE:
- draw_bb_quadric(bb, OB_BOUND_CONE, true);
+ imm_draw_bb(bb, OB_BOUND_CONE, true, ob_wire_col);
break;
case RB_SHAPE_CYLINDER:
- draw_bb_quadric(bb, OB_BOUND_CYLINDER, true);
+ imm_draw_bb(bb, OB_BOUND_CYLINDER, true, ob_wire_col);
break;
case RB_SHAPE_CAPSULE:
- draw_bb_quadric(bb, OB_BOUND_CAPSULE, true);
+ imm_draw_bb(bb, OB_BOUND_CAPSULE, true, ob_wire_col);
break;
}
}
@@ -7454,17 +8567,18 @@ static void draw_rigidbody_shape(Object *ob)
* main object drawing function, draws in selection
* \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
*/
-void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
+ Base *base, const short dflag)
{
ModifierData *md = NULL;
Object *ob = base->object;
Curve *cu;
RegionView3D *rv3d = ar->regiondata;
- unsigned int col = 0;
unsigned char _ob_wire_col[4]; /* dont initialize this */
const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
bool zbufoff = false, is_paint = false, empty_object = false;
- const bool is_obact = (ob == OBACT);
+ const bool is_obact = (ob == OBACT(sl));
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
@@ -7504,7 +8618,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
- if (((base->flag & OB_FROMDUPLI) == 0) &&
+ if (((base->flag_legacy & OB_FROMDUPLI) == 0) &&
(md = modifiers_findByType(ob, eModifierType_Smoke)) &&
(modifier_isEnabled(scene, md, eModifierMode_Realtime)))
{
@@ -7528,7 +8642,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* xray delay? */
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* don't do xray in particle mode, need the z-buffer */
if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
/* xray and transp are set when it is drawing the 2nd/3rd pass */
@@ -7581,10 +8695,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
ED_view3d_project_base(ar, base);
- draw_object_wire_color(scene, base, _ob_wire_col);
+ draw_object_wire_color(scene, sl, base, _ob_wire_col);
ob_wire_col = _ob_wire_col;
- glColor3ubv(ob_wire_col);
+ //glColor3ubv(ob_wire_col);
}
/* maximum drawtype */
@@ -7636,15 +8750,22 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* draw outline for selected objects, mesh does itself */
if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) {
if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
- if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
- draw_object_selected_outline(scene, v3d, ar, base, ob_wire_col);
+ if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
+ draw_object_selected_outline(eval_ctx, scene, sl, v3d, ar, base, ob_wire_col);
}
}
}
+ /* TODO Viewport: draw only for selection */
+ if ((dflag & DRAW_PICKING) == 0) {
+ if ((dt == OB_BOUNDBOX) || ELEM(ob->type, OB_EMPTY, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
+ goto afterdraw;
+ }
+ }
+
switch (ob->type) {
case OB_MESH:
- empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ empty_object = draw_mesh_object(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* mesh draws wire itself */
dtx &= ~OB_DRAWWIRE;
@@ -7654,18 +8775,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
case OB_FONT:
cu = ob->data;
if (cu->editfont) {
- draw_editfont(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ draw_editfont(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && v3d->drawtype >= OB_WIRE) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
@@ -7675,18 +8796,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (cu->editnurb) {
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- draw_editnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
+ draw_editnurb(eval_ctx, scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
case OB_MBALL:
@@ -7694,17 +8815,17 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
MetaBall *mb = ob->data;
if (mb->editelems)
- drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawmball(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else
- empty_object = drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawmball(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
break;
}
case OB_EMPTY:
@@ -7713,7 +8834,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
draw_empty_image(ob, dflag, ob_wire_col, v3d->multiview_eye);
}
else {
- drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
+ drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, ob_wire_col);
}
}
break;
@@ -7731,7 +8852,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
break;
case OB_SPEAKER:
if (!render_override)
- drawspeaker(scene, v3d, rv3d, ob, dflag);
+ drawspeaker(ob_wire_col);
break;
case OB_LATTICE:
if (!render_override) {
@@ -7739,13 +8860,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(scene, ob);
+ ensure_curve_cache(eval_ctx, scene, ob);
#endif
- drawlattice(v3d, ob);
+ drawlattice(v3d, ob, dflag, ob_wire_col);
}
}
break;
@@ -7755,21 +8876,33 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE)))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else {
+ unsigned char arm_col[4];
glLineWidth(1.0f);
- empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, false);
+
+ if (ob_wire_col == NULL) {
+ float fcol[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ rgba_float_to_uchar(arm_col, fcol);
+ }
+ else
+ copy_v4_v4_uchar(arm_col, ob_wire_col);
+
+ empty_object = draw_armature(eval_ctx, scene, sl, v3d, ar, base, dt, dflag, arm_col, false);
}
}
break;
default:
if (!render_override) {
- drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS);
+ drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS, ob_wire_col);
}
break;
}
+ /* TODO Viewport: some elements are being drawn for object selection only */
+afterdraw:
+
if (!render_override) {
if (ob->soft /*&& dflag & OB_SBMOTION*/) {
float mrt[3][3], msc[3][3], mtr[3][3];
@@ -7778,12 +8911,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((sb = ob->soft)) {
if (sb->solverflags & SBSO_ESTIMATEIPO) {
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
copy_m3_m3(msc, sb->lscale);
copy_m3_m3(mrt, sb->lrot);
mul_m3_m3m3(mtr, mrt, msc);
ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
}
}
@@ -7800,35 +8933,28 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
{
ParticleSystem *psys;
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- /* for visibility, also while wpaint */
- if (col || (ob->flag & SELECT)) {
- cpack(0xFFFFFF);
- }
- }
//glDepthMask(GL_FALSE);
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
view3d_cached_text_draw_begin();
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
/* run this so that possible child particles get cached */
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
- PTCacheEdit *edit = PE_create_current(scene, ob);
+ PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit && edit->psys == psys)
- draw_update_ptcache_edit(scene, ob, edit);
+ draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit);
}
- draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
+ draw_new_particle_system(eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag);
}
invert_m4_m4(ob->imat, ob->obmat);
view3d_cached_text_draw_end(v3d, ar, 0);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
//glDepthMask(GL_TRUE);
- if (col) cpack(col);
}
/* draw edit particles last so that they can draw over child particles */
@@ -7837,12 +8963,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
{
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
- PTCacheEdit *edit = PE_create_current(scene, ob);
+ PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit) {
- glLoadMatrixf(rv3d->viewmat);
- draw_update_ptcache_edit(scene, ob, edit);
+ gpuLoadMatrix(rv3d->viewmat);
+ draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit);
draw_ptcache_edit(scene, v3d, edit);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
}
}
@@ -7850,21 +8976,25 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* draw code for smoke, only draw domains */
if (smd && smd->domain) {
SmokeDomainSettings *sds = smd->domain;
+ const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe);
float viewnormal[3];
- glLoadMatrixf(rv3d->viewmat);
- glMultMatrixf(ob->obmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ gpuMultMatrix(ob->obmat);
if (!render_override) {
BoundBox bb;
float p0[3], p1[3];
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
/* draw max domain bounds */
if ((sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN)) {
VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res);
VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res);
BKE_boundbox_init_from_minmax(&bb, p0, p1);
- draw_box(bb.vec, false);
+ imm_draw_box(bb.vec, false, pos);
}
/* draw a single voxel to hint the user about the resolution of the fluid */
@@ -7878,11 +9008,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
BKE_boundbox_init_from_minmax(&bb, p0, p1);
- draw_box(bb.vec, false);
+ imm_draw_box(bb.vec, false, pos);
+
+ immUnbindProgram();
}
/* don't show smoke before simulation starts, this could be made an option in the future */
- if (sds->fluid && CFRA >= sds->point_cache[0]->startframe) {
+ if (sds->fluid && show_smoke) {
float p0[3], p1[3];
/* get view vector */
@@ -7934,29 +9066,37 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((ob->gameflag & OB_BOUNDS) && (ob->mode == OB_MODE_OBJECT)) {
if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) {
setlinestyle(2);
- draw_bounding_volume(ob, ob->collision_boundtype);
+ draw_bounding_volume(ob, ob->collision_boundtype, ob_wire_col);
setlinestyle(0);
}
}
if (ob->rigidbody_object) {
- draw_rigidbody_shape(ob);
+ draw_rigidbody_shape(ob, ob_wire_col);
}
/* draw extra: after normal draw because of makeDispList */
if (dtx && (G.f & G_RENDER_OGL) == 0) {
if (dtx & OB_AXIS) {
- drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ /* prevent random colors being used */
+ drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, ob_wire_col);
+ }
+ else {
+ drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, NULL);
+ }
}
if (dtx & OB_DRAWBOUNDOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
if (dtx & OB_TEXSPACE) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* prevent random colors being used */
- glColor3ubv(ob_wire_col);
+ drawtexspace(ob, ob_wire_col);
+ }
+ else {
+ drawtexspace(ob, NULL);
}
- drawtexspace(ob);
}
if (dtx & OB_DRAWNAME) {
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
@@ -7983,16 +9123,21 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
{
float imat[4][4], vec[3] = {0.0f, 0.0f, 0.0f};
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
invert_m4_m4(imat, rv3d->viewmatob);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* prevent random colors being used */
- glColor3ubv(ob_wire_col);
+ immUniformColor3ubv(ob_wire_col);
}
setlinestyle(2);
- drawcircball(GL_LINE_LOOP, vec, ob->inertia, imat);
+ imm_drawcircball(vec, ob->inertia, imat, pos);
setlinestyle(0);
+
+ immUnbindProgram();
}
}
@@ -8002,13 +9147,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* return warning, clear temp flag */
v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
if (zbufoff) {
glDisable(GL_DEPTH_TEST);
}
- if ((base->flag & OB_FROMDUPLI) || render_override) {
+ if ((base->flag_legacy & OB_FROMDUPLI) || render_override) {
ED_view3d_clear_mats_rv3d(rv3d);
return;
}
@@ -8022,7 +9167,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
else if (is_obact)
do_draw_center = ACTIVE;
- else if (base->flag & SELECT)
+ else if (base->flag & BASE_SELECTED)
do_draw_center = SELECT;
else if (empty_object || (v3d->flag & V3D_DRAW_CENTERS))
do_draw_center = DESELECT;
@@ -8033,10 +9178,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((base->sx != IS_CLIPPED) &&
(U.obcenter_dia != 0.0))
{
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ /* TODO: short term, use DEPTH_ONLY shader or set appropriate color */
+ /* TODO: long term, solve picking & selection problem better */
glPointSize(U.obcenter_dia);
- glBegin(GL_POINTS);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
+ immUnbindProgram();
}
}
else if ((dflag & DRAW_CONSTCOLOR) == 0) {
@@ -8057,18 +9207,24 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
ListBase *list;
RigidBodyCon *rbc = ob->rigidbody_constraint;
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+
/* draw hook center and offset line */
if (ob != scene->obedit)
- draw_hooks(ob);
+ draw_hooks(ob, pos);
/* help lines and so */
- if (ob != scene->obedit && ob->parent && (ob->parent->lay & v3d->lay)) {
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(ob->orig);
- glEnd();
- setlinestyle(0);
+ if (ob != scene->obedit && ob->parent) {
+ if (BKE_object_is_visible(ob->parent)) {
+ setlinestyle(3);
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, ob->orig);
+ immEnd();
+ setlinestyle(0);
+ }
}
/* Drawing the constraint lines */
@@ -8081,7 +9237,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
UI_GetThemeColor3ubv(TH_GRID, col1);
UI_make_axis_color(col1, col2, 'Z');
- glColor3ubv(col2);
+ immUniformColor3ubv(col2);
cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
@@ -8106,10 +9262,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (camob) {
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(camob->obmat[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, camob->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
setlinestyle(0);
}
}
@@ -8125,15 +9281,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
for (ct = targets.first; ct; ct = ct->next) {
/* calculate target's matrix */
if (cti->get_target_matrix)
- cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene));
+ cti->get_target_matrix(eval_ctx, curcon, cob, ct, BKE_scene_frame_get(scene));
else
unit_m4(ct->matrix);
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(ct->matrix[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex3fv(pos, ct->matrix[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
setlinestyle(0);
}
@@ -8146,21 +9302,24 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
BKE_constraints_clear_evalob(cob);
}
/* draw rigid body constraint lines */
- if (rbc) {
- UI_ThemeColor(TH_WIRE);
+ if (rbc && (rbc->ob1 || rbc->ob2)) {
+ immUniformThemeColor(TH_WIRE);
+
setlinestyle(3);
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, ((int)((bool)rbc->ob1) + (int)((bool)rbc->ob2)) * 2);
if (rbc->ob1) {
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(rbc->ob1->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, rbc->ob1->obmat[3]);
}
if (rbc->ob2) {
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(rbc->ob2->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, rbc->ob2->obmat[3]);
}
- glEnd();
+ immEnd();
setlinestyle(0);
}
+
+ immUnbindProgram();
}
ED_view3d_clear_mats_rv3d(rv3d);
@@ -8171,10 +9330,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
* Drawing for selection picking,
* caller must have called 'GPU_select_load_id(base->selcode)' first.
*/
-void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object_select(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
+ Base *base, const short dflag)
{
BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR);
- draw_object(scene, ar, v3d, base, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag);
/* we draw duplicators for selection too */
if ((base->object->transflag & OB_DUPLI)) {
@@ -8182,13 +9343,11 @@ void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, cons
DupliObject *dob;
Base tbase;
- tbase.flag = OB_FROMDUPLI;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+ tbase.flag_legacy = OB_FROMDUPLI;
+ lb = object_duplilist(eval_ctx, scene, base->object);
for (dob = lb->first; dob; dob = dob->next) {
float omat[4][4];
- char dt;
- short dtx;
tbase.object = dob->ob;
copy_m4_m4(omat, dob->ob->obmat);
@@ -8196,10 +9355,10 @@ void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, cons
/* extra service: draw the duplicator in drawtype of parent */
/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
- dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
- dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
+ char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
+ short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
- draw_object(scene, ar, v3d, &tbase, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, &tbase, dflag);
tbase.object->dt = dt;
tbase.object->dtx = dtx;
@@ -8212,6 +9371,7 @@ void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, cons
/* ***************** BACKBUF SEL (BBS) ********* */
+#ifdef USE_MESH_DM_SELECT
static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -8219,8 +9379,10 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const floa
MVert *mv = &data->mvert[index];
if (!(mv->flag & ME_HIDE)) {
- GPU_select_index_set(data->offset + index);
- glVertex3fv(co);
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, co);
}
}
@@ -8231,12 +9393,36 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
MVert *mvert = me->mvert;
data.mvert = mvert;
data.offset = offset;
+
+ const int imm_len = dm->getNumVerts(dm);
+
+ if (imm_len == 0) return;
+
+ Gwn_VertFormat *format = immVertexFormat();
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(GWN_PRIM_POINTS, imm_len);
dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
+#else
+static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *UNUSED(dm), int offset)
+{
+ Mesh *me = ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -8244,97 +9430,223 @@ static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3]
BMVert *eve = BM_vert_at_index(data->bm, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(data->offset + index);
- glVertex3fv(co);
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, co);
}
}
static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
{
- drawBMOffset_userData data = {em->bm, offset};
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+ data.offset = offset;
+ Gwn_VertFormat *format = immVertexFormat();
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(GWN_PRIM_POINTS, em->bm->totvert);
dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
+#else
+static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
-static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index)
+#ifdef USE_MESH_DM_SELECT
+static void bbs_mesh_wire__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
{
drawBMOffset_userData *data = userData;
BMEdge *eed = BM_edge_at_index(data->bm, index);
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(data->offset + index);
- return DM_DRAW_OPTION_NORMAL;
- }
- else {
- return DM_DRAW_OPTION_SKIP;
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, v0co);
+ immVertex3fv(data->pos, v1co);
}
}
+
static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
{
- drawBMOffset_userData data = {em->bm, offset};
- dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, &data);
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+ data.offset = offset;
+
+ Gwn_VertFormat *format = immVertexFormat();
+
+ const int imm_len = dm->getNumEdges(dm) * 2;
+
+ if (imm_len == 0) return;
+
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ immBeginAtMost(GWN_PRIM_LINES, imm_len);
+ dm->foreachMappedEdge(dm, bbs_mesh_wire__mapFunc, &data);
+ immEnd();
+
+ immUnbindProgram();
}
+#else
+static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-/**
- * dont set #GPU_framebuffer_index_set. just use to mask other
- */
-static DMDrawOption bbs_mesh_mask__setSolidDrawOptions(void *userData, int index)
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+
+#ifdef USE_MESH_DM_SELECT
+static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select)
{
- BMFace *efa = BM_face_at_index(userData, index);
-
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- return DM_DRAW_OPTION_NORMAL;
+ UNUSED_VARS(dm);
+
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+
+ const int tri_len = em->tottri;
+ const int imm_len = tri_len * 3;
+ const char hflag_skip = use_select ? BM_ELEM_HIDDEN : (BM_ELEM_HIDDEN | BM_ELEM_SELECT);
+
+ if (imm_len == 0) return;
+
+ Gwn_VertFormat *format = immVertexFormat();
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
+ immBeginAtMost(GWN_PRIM_TRIS, imm_len);
+
+ if (use_select == false) {
+ int selcol;
+ GPU_select_index_get(0, &selcol);
+ immAttrib1u(data.col, selcol);
}
- else {
- return DM_DRAW_OPTION_SKIP;
+
+ int index = 0;
+ while (index < tri_len) {
+ const BMFace *f = em->looptris[index][0]->f;
+ const int ntris = f->len - 2;
+ if (!BM_elem_flag_test(f, hflag_skip)) {
+ if (use_select) {
+ int selcol;
+ GPU_select_index_get(BM_elem_index_get(f) + 1, &selcol);
+ immAttrib1u(data.col, selcol);
+ }
+ for (int t = 0; t < ntris; t++) {
+ immVertex3fv(data.pos, em->looptris[index][0]->v->co);
+ immVertex3fv(data.pos, em->looptris[index][1]->v->co);
+ immVertex3fv(data.pos, em->looptris[index][2]->v->co);
+ index++;
+ }
+ }
+ else {
+ index += ntris;
+ }
}
-}
+ immEnd();
-static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index)
+ immUnbindProgram();
+}
+#else
+static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select)
{
- BMFace *efa = BM_face_at_index(userData, index);
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch;
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(index + 1);
- return DM_DRAW_OPTION_NORMAL;
+ if (use_select) {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
}
else {
- return DM_DRAW_OPTION_SKIP;
+ int selcol;
+ GPU_select_index_get(0, &selcol);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GWN_batch_uniform_1i(batch, "color", selcol);
+ GWN_batch_draw(batch);
}
}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
{
+ drawBMOffset_userData *data = (drawBMOffset_userData *)userData;
BMFace *efa = BM_face_at_index(userData, index);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(index + 1);
-
- glVertex3fv(cent);
+ int selcol;
+ GPU_select_index_get(index + 1, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, cent);
}
}
+static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
+{
+ drawBMOffset_userData data; /* don't use offset */
+ data.bm = em->bm;
+ Gwn_VertFormat *format = immVertexFormat();
+ data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
+ glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
+
+ immBeginAtMost(GWN_PRIM_POINTS, em->bm->totface);
+ dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, &data, DM_FOREACH_NOP);
+ immEnd();
+
+ immUnbindProgram();
+}
+#else
+static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm))
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+
/* two options, facecolors or black */
static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
Object *ob, DerivedMesh *dm, bool use_faceselect)
{
- cpack(0);
-
if (use_faceselect) {
- dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE);
+ bbs_mesh_face(em, dm, true);
if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
- glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
-
- glBegin(GL_POINTS);
- dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, em->bm, DM_FOREACH_NOP);
- glEnd();
+ bbs_mesh_face_dot(em, dm);
}
-
}
else {
- dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT | DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE);
+ bbs_mesh_face(em, dm, false);
}
}
@@ -8349,7 +9661,6 @@ static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index)
Mesh *me = userData;
if (!(me->mpoly[index].flag & ME_HIDE)) {
- GPU_select_index_set(index + 1);
return DM_DRAW_OPTION_NORMAL;
}
else {
@@ -8357,6 +9668,7 @@ static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index)
}
}
+#ifdef USE_MESH_DM_SELECT
/* must have called GPU_framebuffer_index_set beforehand */
static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
{
@@ -8370,11 +9682,10 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
}
}
-static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
+static void bbs_mesh_solid_verts(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
Mesh *me = ob->data;
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- glColor3ub(0, 0, 0);
+ DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
DM_update_materials(dm, ob);
@@ -8390,29 +9701,53 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
bm_vertoffs = me->totvert + 1;
dm->release(dm);
}
-
-static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
+#else
+static void bbs_mesh_solid_verts(const EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *ob)
{
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
Mesh *me = ob->data;
-
- glColor3ub(0, 0, 0);
- DM_update_materials(dm, ob);
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ const int G_f_orig = G.f;
+ G.f &= ~G_BACKBUFSEL;
- if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, NULL, NULL, me, DM_DRAW_SKIP_HIDDEN);
- else
- dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0);
+ {
+ int selcol;
+ Gwn_Batch *batch;
+ GPU_select_index_get(0, &selcol);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GWN_batch_uniform_1i(batch, "color", selcol);
+ GWN_batch_draw(batch);
+ }
- dm->release(dm);
+ G.f |= (G_f_orig & G_BACKBUFSEL);
+
+ bbs_obmode_mesh_verts(ob, NULL, 1);
+ bm_vertoffs = me->totvert + 1;
}
+#endif
-void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
+{
+ Mesh *me = ob->data;
+ UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts);
+ Gwn_Batch *batch;
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
+ }
+ else {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
+ }
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+
+void draw_object_backbufsel(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
ToolSettings *ts = scene->toolsettings;
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
@@ -8423,7 +9758,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
- DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
+ DerivedMesh *dm = editbmesh_get_derived_cage(eval_ctx, scene, ob, em, CD_MASK_BAREMESH);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
@@ -8460,7 +9795,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* currently vertex select supports weight paint and vertex paint*/
((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
{
- bbs_mesh_solid_verts(scene, ob);
+ bbs_mesh_solid_verts(eval_ctx, scene, ob);
}
else {
bbs_mesh_solid_faces(scene, ob);
@@ -8472,7 +9807,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
break;
}
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
@@ -8480,8 +9815,9 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* assumes all matrices/etc set OK */
/* helper function for drawing object instances - meshes */
-static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Object *ob, const short dt, int outline)
+static void draw_object_mesh_instance(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
+ Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4])
{
Mesh *me = ob->data;
DerivedMesh *dm = NULL, *edm = NULL;
@@ -8491,11 +9827,12 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
DM_update_materials(edm, ob);
}
else {
- dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
DM_update_materials(dm, ob);
}
if (dt <= OB_WIRE) {
+ glColor4ubv(ob_wire_col);
if (dm)
dm->drawEdges(dm, 1, 0);
else if (edm)
@@ -8503,11 +9840,11 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
}
else {
if (outline)
- draw_mesh_object_outline(v3d, ob, dm ? dm : edm);
+ draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col);
if (dm) {
- bool glsl = draw_glsl_material(scene, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -8526,23 +9863,153 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
if (dm) dm->release(dm);
}
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline)
+void draw_object_instance(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4])
{
if (ob == NULL)
return;
+ unsigned char bcol[4];
+ rgba_float_to_uchar(bcol, wire_col);
+
switch (ob->type) {
case OB_MESH:
- draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outline);
+ draw_object_mesh_instance(eval_ctx, scene, sl, v3d, rv3d, ob, dt, outline, bcol);
break;
case OB_EMPTY:
if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
- /* CONSTCOLOR == no wire outline */
- draw_empty_image(ob, DRAW_CONSTCOLOR, NULL, v3d->multiview_eye);
+ draw_empty_image(ob, 0, bcol, v3d->multiview_eye);
}
else {
- drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
+ drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, bcol);
}
break;
}
}
+
+void ED_draw_object_facemap(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, const float col[4], const int facemap)
+{
+ DerivedMesh *dm = NULL;
+
+ /* happens on undo */
+ if (ob->type != OB_MESH || !ob->data)
+ return;
+
+ /* Temporary, happens on undo, would resolve but will eventually move away from DM. */
+ if (ob->derivedFinal == NULL) {
+ return;
+ }
+
+ dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
+ if (!dm || !CustomData_has_layer(&dm->polyData, CD_FACEMAP))
+ return;
+
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+#if 0
+ DM_update_materials(dm, ob);
+
+ /* add polygon offset so we draw above the original surface */
+ glPolygonOffset(1.0, 1.0);
+
+ GPU_facemap_setup(dm);
+
+ glColor4fv(col);
+
+ gpuPushAttrib(GL_ENABLE_BIT);
+ glEnable(GL_BLEND);
+ glDisable(GL_LIGHTING);
+
+ /* always draw using backface culling */
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ if (dm->drawObject->facemapindices) {
+ glDrawElements(GL_TRIANGLES, dm->drawObject->facemap_count[facemap] * 3, GL_UNSIGNED_INT,
+ (int *)NULL + dm->drawObject->facemap_start[facemap] * 3);
+ }
+ gpuPopAttrib();
+
+ GPU_buffers_unbind();
+
+ glPolygonOffset(0.0, 0.0);
+
+#else
+
+ /* Just to create the data to pass to immediate mode, grr! */
+ Mesh *me = ob->data;
+ const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ if (facemap_data) {
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(col);
+
+ /* XXX, alpha isn't working yet, not sure why. */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ MVert *mvert;
+
+ MPoly *mpoly;
+ int mpoly_len;
+
+ MLoop *mloop;
+ int mloop_len;
+
+ if (dm && CustomData_has_layer(&dm->polyData, CD_FACEMAP)) {
+ mvert = dm->getVertArray(dm);
+ mpoly = dm->getPolyArray(dm);
+ mloop = dm->getLoopArray(dm);
+
+ mpoly_len = dm->getNumPolys(dm);
+ mloop_len = dm->getNumLoops(dm);
+
+ facemap_data = CustomData_get_layer(&dm->polyData, CD_FACEMAP);
+ }
+ else {
+ mvert = me->mvert;
+ mpoly = me->mpoly;
+ mloop = me->mloop;
+
+ mpoly_len = me->totpoly;
+ mloop_len = me->totloop;
+
+ facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ }
+
+ /* use gawain immediate mode fore now */
+ const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
+ immBeginAtMost(GWN_PRIM_TRIS, looptris_len * 3);
+
+ MPoly *mp;
+ int i;
+ for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
+ if (facemap_data[i] == facemap) {
+ /* Weak, fan-fill, use until we have derived-mesh replaced. */
+ const MLoop *ml_start = &mloop[mp->loopstart];
+ const MLoop *ml_a = ml_start + 1;
+ const MLoop *ml_b = ml_start + 2;
+ for (int j = 2; j < mp->totloop; j++) {
+ immVertex3fv(pos, mvert[ml_start->v].co);
+ immVertex3fv(pos, mvert[ml_a->v].co);
+ immVertex3fv(pos, mvert[ml_b->v].co);
+
+ ml_a++;
+ ml_b++;
+ }
+ }
+ }
+ immEnd();
+
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
+ }
+#endif
+
+ dm->release(dm);
+}
+
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
index 3f23d4aa09a..14708ca67bc 100644
--- a/source/blender/editors/space_view3d/drawsimdebug.c
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -40,102 +40,137 @@
#include "BKE_effect.h"
-#include "view3d_intern.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
-#include "BIF_gl.h"
+#include "view3d_intern.h"
static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4])
{
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ /* count element types */
GHashIterator iter;
+ int num_dots = 0;
+ int num_circles = 0;
+ int num_lines = 0;
+ int num_vectors = 0;
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ switch (elem->type) {
+ case SIM_DEBUG_ELEM_DOT: ++num_dots; break;
+ case SIM_DEBUG_ELEM_CIRCLE: ++num_circles; break;
+ case SIM_DEBUG_ELEM_LINE: ++num_lines; break;
+ case SIM_DEBUG_ELEM_VECTOR: ++num_vectors; break;
+ }
+ }
/**** dots ****/
glPointSize(3.0f);
- glBegin(GL_POINTS);
+ immBegin(GWN_PRIM_POINTS, num_dots);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_DOT)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
}
- glEnd();
+ immEnd();
/**** circles ****/
{
- float circle[16][2] = {
+#define CIRCLERES 16
+ float circle[CIRCLERES][2] = {
{0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683},
{1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880},
{-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684},
{-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} };
+
+ immBegin(GWN_PRIM_LINES, num_circles * CIRCLERES * 2);
+
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
float radius = elem->v2[0];
- float co[3];
+ float co[3], nco[3];
int i;
if (elem->type != SIM_DEBUG_ELEM_CIRCLE)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glBegin(GL_LINE_LOOP);
- for (i = 0; i < 16; ++i) {
- co[0] = radius * circle[i][0];
- co[1] = radius * circle[i][1];
- co[2] = 0.0f;
- mul_mat3_m4_v3(imat, co);
- add_v3_v3(co, elem->v1);
+ immAttrib3fv(color, elem->color);
+ zero_v3(co);
+ for (i = 0; i <= CIRCLERES; ++i) {
+ int ni = i % CIRCLERES;
+ nco[0] = radius * circle[ni][0];
+ nco[1] = radius * circle[ni][1];
+ nco[2] = 0.0f;
+ mul_mat3_m4_v3(imat, nco);
+ add_v3_v3(nco, elem->v1);
- glVertex3f(co[0], co[1], co[2]);
+ if (i > 0) {
+ immVertex3fv(pos, co);
+ immVertex3fv(pos, nco);
+ }
+
+ copy_v3_v3(co, nco);
}
- glEnd();
}
+
+ immEnd();
+#undef CIRCLERES
}
/**** lines ****/
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, num_lines * 2);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_LINE)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
- glVertex3f(elem->v2[0], elem->v2[1], elem->v2[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
+ immVertex3fv(pos, elem->v2);
}
- glEnd();
+ immEnd();
/**** vectors ****/
glPointSize(2.0f);
- glBegin(GL_POINTS);
+ immBegin(GWN_PRIM_POINTS, num_vectors);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_VECTOR)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
}
- glEnd();
+ immEnd();
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, num_vectors * 2);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
float t[3];
if (elem->type != SIM_DEBUG_ELEM_VECTOR)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
add_v3_v3v3(t, elem->v1, elem->v2);
- glVertex3f(t[0], t[1], t[2]);
+ immVertex3fv(pos, t);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
/**** strings ****/
@@ -163,18 +198,12 @@ void draw_sim_debug_data(Scene *UNUSED(scene), View3D *v3d, ARegion *ar)
invert_m4_m4(imat, rv3d->viewmatob);
-// glDepthMask(GL_FALSE);
-// glEnable(GL_BLEND);
-
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
view3d_cached_text_draw_begin();
draw_sim_debug_elements(_sim_debug_data, imat);
view3d_cached_text_draw_end(v3d, ar, false);
- glPopMatrix();
-
-// glDepthMask(GL_TRUE);
-// glDisable(GL_BLEND);
+ gpuPopMatrix();
}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index c076bfb4aa4..3a80624acd9 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -48,7 +48,6 @@
#include "BIF_gl.h"
-#include "GPU_debug.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -160,7 +159,7 @@ static GPUTexture *create_field_texture(SmokeDomainSettings *sds)
default: return NULL;
}
- return GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, field);
+ return GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1, GPU_R8, field, NULL);
}
typedef struct VolumeSlicer {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 996506a9cf7..e1e78fd8ff1 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -43,22 +43,27 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
+#include "BKE_curve.h"
#include "BKE_icons.h"
+#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mball.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_workspace.h"
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "ED_transform.h"
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
#include "GPU_material.h"
-
-#include "BIF_gl.h"
+#include "GPU_viewport.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -250,7 +255,7 @@ void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
/* we have to multiply instead of loading viewmatob to make
* it work with duplis using displists, otherwise it will
* override the dupli-matrix */
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
#ifdef DEBUG
@@ -304,7 +309,7 @@ void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa)
}
else if (scene->obedit != NULL && scene->obedit->type == OB_MESH) {
/* Tag mesh to load edit data. */
- DAG_id_tag_update(scene->obedit->data, 0);
+ DEG_id_tag_update(scene->obedit->data, 0);
}
}
@@ -340,9 +345,10 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->near = 0.01f;
v3d->far = 1000.0f;
- v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
+ v3d->twflag |= U.manipulator_flag & V3D_MANIPULATOR_DRAW;
v3d->twtype = V3D_MANIP_TRANSLATE;
v3d->around = V3D_AROUND_CENTER_MEAN;
+ v3d->custom_orientation_index = -1;
v3d->bundle_size = 0.2f;
v3d->bundle_drawtype = OB_PLAINAXES;
@@ -404,17 +410,6 @@ static SpaceLink *view3d_new(const bContext *C)
static void view3d_free(SpaceLink *sl)
{
View3D *vd = (View3D *) sl;
- BGpic *bgpic;
-
- for (bgpic = vd->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- if (bgpic->source == V3D_BGPIC_IMAGE) {
- id_us_min((ID *)bgpic->ima);
- }
- else if (bgpic->source == V3D_BGPIC_MOVIE) {
- id_us_min((ID *)bgpic->clip);
- }
- }
- BLI_freelistN(&vd->bgpicbase);
if (vd->localvd) MEM_freeN(vd->localvd);
@@ -445,7 +440,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
View3D *v3do = (View3D *)sl;
View3D *v3dn = MEM_dupallocN(sl);
- BGpic *bgpic;
/* clear or remove stuff from old */
@@ -462,16 +456,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
v3dn->defmaterial = NULL;
- BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
- for (bgpic = v3dn->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- if (bgpic->source == V3D_BGPIC_IMAGE) {
- id_us_plus((ID *)bgpic->ima);
- }
- else if (bgpic->source == V3D_BGPIC_MOVIE) {
- id_us_plus((ID *)bgpic->clip);
- }
- }
-
v3dn->properties_storage = NULL;
if (v3dn->fx_settings.dof)
v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof);
@@ -487,6 +471,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
+ if (ar->manipulator_map == NULL) {
+ ar->manipulator_map = WM_manipulatormap_new_from_type(
+ &(const struct wmManipulatorMapType_Params) {SPACE_VIEW3D, RGN_TYPE_WINDOW});
+ }
+
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* object ops. */
/* important to be before Pose keymap since they can both be enabled at once */
@@ -582,6 +573,12 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
GPU_fx_compositor_destroy(rv3d->compositor);
rv3d->compositor = NULL;
}
+
+ if (rv3d->viewport) {
+ GPU_viewport_free(rv3d->viewport);
+ MEM_freeN(rv3d->viewport);
+ rv3d->viewport = NULL;
+ }
}
static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
@@ -712,6 +709,26 @@ static void view3d_dropboxes(void)
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
+static void view3d_widgets(void)
+{
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(
+ &(const struct wmManipulatorMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW});
+
+ WM_manipulatorgrouptype_append_and_link(mmap_type, TRANSFORM_WGT_manipulator);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_spot);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_area);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_target);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline);
+
+ WM_manipulatorgrouptype_append(VIEW3D_WGT_xform_cage);
+
+ WM_manipulatorgrouptype_append(VIEW3D_WGT_ruler);
+ WM_manipulatortype_append(VIEW3D_WT_ruler_item);
+}
/* type callback, not region itself */
@@ -739,6 +756,10 @@ static void view3d_main_region_free(ARegion *ar)
if (rv3d->compositor) {
GPU_fx_compositor_destroy(rv3d->compositor);
}
+ if (rv3d->viewport) {
+ GPU_viewport_free(rv3d->viewport);
+ MEM_freeN(rv3d->viewport);
+ }
MEM_freeN(rv3d);
ar->regiondata = NULL;
@@ -763,32 +784,22 @@ static void *view3d_main_region_duplicate(void *poin)
new->sms = NULL;
new->smooth_timer = NULL;
new->compositor = NULL;
+ new->viewport = NULL;
return new;
}
return NULL;
}
-static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene)
+static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene))
{
wmWindow *win = wmn->wm->winactive;
- ScrArea *sa;
unsigned int lay_used = 0;
- Base *base;
if (!win) return;
- base = scene->base.first;
- while (base) {
- lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */
-
- if (lay_used == (1 << 20) - 1)
- break;
-
- base = base->next;
- }
-
- for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_VIEW3D) {
if (BLI_findindex(&sa->regionbase, ar) != -1) {
View3D *v3d = sa->spacedata.first;
@@ -799,13 +810,21 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
}
}
-static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *wmn)
+static void view3d_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar,
+ wmNotifier *wmn, const Scene *scene)
{
- Scene *scene = sc->scene;
View3D *v3d = sa->spacedata.first;
-
+ RegionView3D *rv3d = ar->regiondata;
+ wmManipulatorMap *mmap = ar->manipulator_map;
+
/* context changes */
switch (wmn->category) {
+ case NC_WM:
+ if (ELEM(wmn->data, ND_UNDO)) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
case NC_ANIMATION:
switch (wmn->data) {
case ND_KEYFRAME_PROP:
@@ -825,21 +844,32 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
break;
case NC_SCENE:
switch (wmn->data) {
+ case ND_SCENEBROWSE:
case ND_LAYER_CONTENT:
if (wmn->reference)
view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
+ break;
+ case ND_LAYER:
+ if (wmn->reference) {
+ BKE_screen_view3d_sync(v3d, wmn->reference);
+ }
+ ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
- case ND_FRAME:
- case ND_TRANSFORM:
case ND_OB_ACTIVE:
case ND_OB_SELECT:
+ DEG_id_tag_update((ID *)&scene->id, DEG_TAG_COPY_ON_WRITE);
+ ATTR_FALLTHROUGH;
+ case ND_FRAME:
+ case ND_TRANSFORM:
case ND_OB_VISIBLE:
- case ND_LAYER:
case ND_RENDER_OPTIONS:
case ND_MARKERS:
case ND_MODE:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
@@ -847,7 +877,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (scene == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -872,6 +901,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_POINTCACHE:
case ND_LOD:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
switch (wmn->action) {
@@ -882,9 +912,30 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
break;
case NC_GEOM:
switch (wmn->data) {
+ case ND_SELECT:
+ {
+ WM_manipulatormap_tag_refresh(mmap);
+
+ if (scene->obedit) {
+ Object *ob = scene->obedit;
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ // case OB_FONT: /* handled by text_update_edited */
+ case OB_CURVE:
+ case OB_SURF:
+ BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ case OB_LATTICE:
+ BKE_lattice_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ }
+ }
+ ATTR_FALLTHROUGH;
+ }
case ND_DATA:
case ND_VERTEX_GROUP:
- case ND_SELECT:
ED_region_tag_redraw(ar);
break;
}
@@ -899,7 +950,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (v3d->camera->data == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -928,21 +978,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
switch (wmn->data) {
case ND_SHADING:
case ND_NODES:
- {
-#ifdef WITH_LEGACY_DEPSGRAPH
- Object *ob = OBACT;
- if ((v3d->drawtype == OB_MATERIAL) ||
- (ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) ||
- (v3d->drawtype == OB_TEXTURE &&
- (scene->gm.matmode == GAME_MAT_GLSL ||
- BKE_scene_use_new_shading_nodes(scene))) ||
- !DEG_depsgraph_use_legacy())
-#endif
- {
- ED_region_tag_redraw(ar);
- }
+ /* TODO(sergey) This is a bit too much updates, but needed to
+ * have proper material drivers update in the viewport.
+ *
+ * How to solve?
+ */
+ ED_region_tag_redraw(ar);
break;
- }
case ND_SHADING_DRAW:
case ND_SHADING_LINKS:
ED_region_tag_redraw(ar);
@@ -954,20 +996,23 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_WORLD_DRAW:
/* handled by space_view3d_listener() for v3d access */
break;
+ case ND_WORLD:
+ /* Needed for updating world materials */
+ ED_region_tag_redraw(ar);
+ break;
}
break;
case NC_LAMP:
switch (wmn->data) {
case ND_LIGHTING:
- if ((v3d->drawtype == OB_MATERIAL) ||
- (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)) ||
- !DEG_depsgraph_use_legacy())
- {
- ED_region_tag_redraw(ar);
- }
+ /* TODO(sergey): This is a bit too much, but needed to
+ * handle updates from new depsgraph.
+ */
+ ED_region_tag_redraw(ar);
break;
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
break;
@@ -987,10 +1032,10 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_SPACE:
if (wmn->data == ND_SPACE_VIEW3D) {
if (wmn->subtype == NS_VIEW3D_GPU) {
- RegionView3D *rv3d = ar->regiondata;
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
}
break;
case NC_ID:
@@ -1003,15 +1048,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_SKETCH:
ED_region_tag_redraw(ar);
break;
- case ND_SCREENBROWSE:
- case ND_SCREENDELETE:
- case ND_SCREENSET:
- /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
- /* updates used layers only for View3D in active screen */
- if (wmn->reference) {
- bScreen *sc_ref = wmn->reference;
- view3d_recalc_used_layers(ar, wmn, sc_ref->scene);
- }
+ case ND_LAYOUTBROWSE:
+ case ND_LAYOUTDELETE:
+ case ND_LAYOUTSET:
+ WM_manipulatormap_tag_refresh(mmap);
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_LAYER:
ED_region_tag_redraw(ar);
break;
}
@@ -1028,7 +1071,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
/* concept is to retrieve cursor type context-less */
static void view3d_main_region_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
{
- Scene *scene = win->screen->scene;
+ const Scene *scene = WM_window_get_active_scene(win);
if (scene->obedit) {
WM_cursor_set(win, CURSOR_EDIT);
@@ -1053,7 +1096,9 @@ static void view3d_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void view3d_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1099,7 +1144,9 @@ static void view3d_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void view3d_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_buttons_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1205,7 +1252,9 @@ static void view3d_tools_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, CTX_data_mode_string(C), -1, true);
}
-static void view3d_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_props_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1225,7 +1274,9 @@ static void view3d_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
}
/* area (not region) level listener */
-static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn)
+static void space_view3d_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn, Scene *UNUSED(scene),
+ WorkSpace *UNUSED(workspace))
{
View3D *v3d = sa->spacedata.first;
@@ -1260,8 +1311,6 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot
}
const char *view3d_context_dir[] = {
- "selected_objects", "selected_bases", "selected_editable_objects",
- "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"active_base", "active_object", NULL
};
@@ -1272,109 +1321,27 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, view3d_context_dir);
}
- else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selected_objects = CTX_data_equals(member, "selected_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (selected_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (0 == BKE_object_is_libdata(base->object)) {
- if (selected_editable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool visible_objects = CTX_data_equals(member, "visible_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & lay) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (visible_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & lay) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
- if (selectable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
else if (CTX_data_equals(member, "active_base")) {
- View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- if (scene->basact && (scene->basact->lay & lay)) {
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (sl->basact) {
+ Object *ob = sl->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
+ if ((sl->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, sl->basact);
+ }
}
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- if (scene->basact && (scene->basact->lay & lay)) {
- Object *ob = scene->basact->object;
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
- CTX_data_id_pointer_set(result, &scene->basact->object->id);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (sl->basact) {
+ Object *ob = sl->basact->object;
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ if ((sl->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+ CTX_data_id_pointer_set(result, &ob->id);
+ }
}
return 1;
@@ -1424,21 +1391,6 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i
v3d->ob_centre_bone[0] = '\0';
}
}
-
- if (ELEM(GS(old_id->name), ID_IM, ID_MC)) {
- for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- if ((ID *)bgpic->ima == old_id) {
- bgpic->ima = (Image *)new_id;
- id_us_min(old_id);
- id_us_plus(new_id);
- }
- if ((ID *)bgpic->clip == old_id) {
- bgpic->clip = (MovieClip *)new_id;
- id_us_min(old_id);
- id_us_plus(new_id);
- }
- }
- }
}
if (is_local) {
@@ -1464,6 +1416,7 @@ void ED_spacetype_view3d(void)
st->operatortypes = view3d_operatortypes;
st->keymap = view3d_keymap;
st->dropboxes = view3d_dropboxes;
+ st->manipulators = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 0c67776693d..ac808487dd2 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -55,13 +55,14 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
#include "BKE_deform.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -776,18 +777,18 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
return;
}
else {
- Scene *scene = CTX_data_scene(C);
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = sl->basact->object;
ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
}
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT(sl);
if (ob && (BKE_object_is_in_editmode_vgroup(ob) ||
BKE_object_is_in_wpaint_select_vert(ob)))
{
@@ -805,7 +806,8 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
{
uiBlock *block = uiLayoutAbsoluteBlock(pa->layout);
Scene *scene = CTX_data_scene(C);
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = sl->basact->object;
MDeformVert *dv;
@@ -1095,9 +1097,9 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
{
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- Object *ob = OBACT;
+ Object *ob = OBACT(sl);
switch (event) {
@@ -1108,7 +1110,7 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
case B_OBJECTPANELMEDIAN:
if (ob) {
v3d_editvertex_buts(NULL, v3d, ob, 1.0);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
break;
}
@@ -1119,16 +1121,17 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
static int view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Scene *scene = CTX_data_scene(C);
- return (scene->basact != NULL);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ return (sl->basact != NULL);
}
static void view3d_panel_transform(const bContext *C, Panel *pa)
{
uiBlock *block;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
- Object *ob = scene->basact->object;
+ Object *ob = sl->basact->object;
uiLayout *col;
block = uiLayoutGetBlock(pa->layout);
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index f717f1c0a43..9b07593e576 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -54,8 +54,9 @@
#include "BLI_utildefines.h"
#include "BKE_object.h"
+#include "BKE_context.h"
-#include "BKE_depsgraph.h" /* for object updating */
+#include "DEG_depsgraph.h"
#include "ED_screen.h"
@@ -137,10 +138,13 @@ Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl)
* the view for first-person style navigation.
*/
struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
- Scene *scene, View3D *v3d, RegionView3D *rv3d,
+ const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d,
const bool use_parent_root)
{
View3DCameraControl *vctrl;
+ EvaluationContext eval_ctx;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__);
@@ -177,7 +181,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
/* store the original camera loc and rot */
vctrl->obtfm = BKE_object_tfm_backup(ob_back);
- BKE_object_where_is_calc(scene, v3d->camera);
+ BKE_object_where_is_calc(&eval_ctx, scene, v3d->camera);
negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]);
rv3d->dist = 0.0;
@@ -242,7 +246,7 @@ void ED_view3d_cameracontrol_update(
ob_update = v3d->camera->parent;
while (ob_update) {
- DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob_update->id, OB_RECALC_OB);
ob_update = ob_update->parent;
}
@@ -264,7 +268,7 @@ void ED_view3d_cameracontrol_update(
BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
- DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
+ DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
copy_v3_v3(v3d->camera->size, size_back);
@@ -299,7 +303,7 @@ void ED_view3d_cameracontrol_release(
/* store the original camera loc and rot */
BKE_object_tfm_restore(ob_back, vctrl->obtfm);
- DAG_id_tag_update(&ob_back->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob_back->id, OB_RECALC_OB);
}
else {
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
@@ -311,7 +315,7 @@ void ED_view3d_cameracontrol_release(
rv3d->dist = vctrl->dist_backup;
}
else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */
- DAG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB);
+ DEG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB);
/* always, is set to zero otherwise */
copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 56508ea989a..475e9cd07bf 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -28,948 +28,282 @@
* \ingroup spview3d
*/
-#include <string.h>
-#include <stdio.h>
#include <math.h>
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_customdata_types.h"
-#include "DNA_object_types.h"
-#include "DNA_group_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_world_types.h"
-#include "DNA_brush_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_jitter.h"
-#include "BLI_utildefines.h"
-#include "BLI_endian_switch.h"
+#include "BLI_rect.h"
+#include "BLI_string.h"
#include "BLI_threads.h"
+#include "BLI_jitter.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
-#include "BKE_anim.h"
#include "BKE_camera.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_image.h"
+#include "BKE_global.h"
#include "BKE_key.h"
-#include "BKE_main.h"
+#include "BKE_scene.h"
#include "BKE_object.h"
-#include "BKE_global.h"
#include "BKE_paint.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "BKE_movieclip.h"
-
-#include "RE_engine.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-#include "IMB_colormanagement.h"
+#include "BLF_api.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "BLT_translation.h"
-#include "WM_api.h"
+#include "DNA_armature_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
-#include "BLF_api.h"
-#include "BLT_translation.h"
+#include "DRW_engine.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
-#include "ED_space_api.h"
-#include "ED_screen_types.h"
#include "ED_transform.h"
-#include "UI_interface.h"
-#include "UI_interface_icons.h"
-#include "UI_resources.h"
+#include "DEG_depsgraph_query.h"
#include "GPU_draw.h"
-#include "GPU_framebuffer.h"
+#include "GPU_matrix.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "GPU_material.h"
+#include "GPU_viewport.h"
#include "GPU_compositing.h"
-#include "GPU_extensions.h"
-#include "GPU_select.h"
-
-#include "view3d_intern.h" /* own include */
-
-/* prototypes */
-static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect);
-static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- float winmat[4][4], const char *viewname);
-
-/* 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]);
-extern void bl_debug_color_set(const unsigned int col);
-#endif
-
-void circf(float x, float y, float rad)
-{
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
-
- glPushMatrix();
-
- glTranslatef(x, y, 0.0);
-
- gluDisk(qobj, 0.0, rad, 32, 1);
-
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
-}
-
-void circ(float x, float y, float rad)
-{
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
- glPushMatrix();
-
- glTranslatef(x, y, 0.0);
-
- gluDisk(qobj, 0.0, rad, 32, 1);
-
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
-}
-
-/* ********* custom clipping *********** */
-
-static void view3d_draw_clipping(RegionView3D *rv3d)
-{
- BoundBox *bb = rv3d->clipbb;
-
- if (bb) {
- const unsigned int clipping_index[6][4] = {
- {0, 1, 2, 3},
- {0, 4, 5, 1},
- {4, 7, 6, 5},
- {7, 3, 2, 6},
- {1, 5, 6, 2},
- {7, 4, 0, 3}
- };
-
- /* fill in zero alpha for rendering & re-projection [#31530] */
- unsigned char col[4];
- UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
- glColor4ubv(col);
-
- glEnable(GL_BLEND);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, bb->vec);
- glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_BLEND);
- }
-}
+#include "MEM_guardedalloc.h"
-void ED_view3d_clipping_set(RegionView3D *rv3d)
-{
- double plane[4];
- const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
- unsigned int a;
-
- for (a = 0; a < tot; a++) {
- copy_v4db_v4fl(plane, rv3d->clip[a]);
- glClipPlane(GL_CLIP_PLANE0 + a, plane);
- glEnable(GL_CLIP_PLANE0 + a);
- }
-}
+#include "UI_interface.h"
+#include "UI_resources.h"
-/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
-void ED_view3d_clipping_disable(void)
-{
- unsigned int a;
+#include "RE_engine.h"
- for (a = 0; a < 6; a++) {
- glDisable(GL_CLIP_PLANE0 + a);
- }
-}
-void ED_view3d_clipping_enable(void)
-{
- unsigned int a;
+#include "WM_api.h"
+#include "WM_types.h"
- for (a = 0; a < 6; a++) {
- glEnable(GL_CLIP_PLANE0 + a);
- }
-}
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
-static bool view3d_clipping_test(const float co[3], const float clip[6][4])
-{
- 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)
- return false;
+#include "view3d_intern.h" /* own include */
- return true;
-}
+/* ******************** general functions ***************** */
-/* for 'local' ED_view3d_clipping_local must run first
- * then all comparisons can be done in localspace */
-bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
+static bool use_depth_doit(Scene *scene, View3D *v3d)
{
- return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
-}
-
-/* ********* end custom clipping *********** */
-
-
-static void drawgrid_draw(ARegion *ar, double wx, double wy, double x, double y, double dx)
-{
- double verts[2][2];
-
- x += (wx);
- y += (wy);
-
- /* set fixed 'Y' */
- verts[0][1] = 0.0f;
- verts[1][1] = (double)ar->winy;
+ if (v3d->drawtype > OB_WIRE)
+ return true;
- /* iter over 'X' */
- verts[0][0] = verts[1][0] = x - dx * floor(x / dx);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_DOUBLE, 0, verts);
-
- while (verts[0][0] < ar->winx) {
- glDrawArrays(GL_LINES, 0, 2);
- verts[0][0] = verts[1][0] = verts[0][0] + dx;
- }
-
- /* set fixed 'X' */
- verts[0][0] = 0.0f;
- verts[1][0] = (double)ar->winx;
-
- /* iter over 'Y' */
- verts[0][1] = verts[1][1] = y - dx * floor(y / dx);
- while (verts[0][1] < ar->winy) {
- glDrawArrays(GL_LINES, 0, 2);
- verts[0][1] = verts[1][1] = verts[0][1] + dx;
+ /* special case (depth for wire color) */
+ if (v3d->drawtype <= OB_WIRE) {
+ if (scene->obedit && scene->obedit->type == OB_MESH) {
+ Mesh *me = scene->obedit->data;
+ if (me->drawflag & ME_DRAWEIGHT) {
+ return true;
+ }
+ }
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
+ return false;
}
-#define GRID_MIN_PX_D 6.0
-#define GRID_MIN_PX_F 6.0f
-
-static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+/**
+ * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
+ */
+void ED_view3d_update_viewmat(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar,
+ float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
- /* extern short bgpicmode; */
RegionView3D *rv3d = ar->regiondata;
- double wx, wy, x, y, fw, fx, fy, dx;
- double vec4[4];
- unsigned char col[3], col2[3];
-
- fx = rv3d->persmat[3][0];
- fy = rv3d->persmat[3][1];
- fw = rv3d->persmat[3][3];
-
- wx = (ar->winx / 2.0); /* because of rounding errors, grid at wrong location */
- wy = (ar->winy / 2.0);
-
- x = (wx) * fx / fw;
- y = (wy) * fy / fw;
-
- vec4[0] = vec4[1] = v3d->grid;
-
- vec4[2] = 0.0;
- vec4[3] = 1.0;
- mul_m4_v4d(rv3d->persmat, vec4);
- fx = vec4[0];
- fy = vec4[1];
- fw = vec4[3];
-
- dx = fabs(x - (wx) * fx / fw);
- if (dx == 0) dx = fabs(y - (wy) * fy / fw);
-
- glLineWidth(1.0f);
- glDepthMask(GL_FALSE); /* disable write in zbuffer */
-
- /* check zoom out */
- UI_ThemeColor(TH_GRID);
-
- if (unit->system) {
- /* Use GRID_MIN_PX * 2 for units because very very small grid
- * items are less useful when dealing with units */
- const void *usys;
- int len, i;
- double dx_scalar;
- float blend_fac;
- bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
-
- if (usys) {
- i = len;
- while (i--) {
- double scalar = bUnit_GetScaler(usys, i);
-
- dx_scalar = dx * scalar / (double)unit->scale_length;
- if (dx_scalar < (GRID_MIN_PX_D * 2.0))
- continue;
+ /* setup window matrices */
+ if (winmat)
+ copy_m4_m4(rv3d->winmat, winmat);
+ else
+ view3d_winmatrix_set(ar, v3d, rect);
- /* Store the smallest drawn grid size units name so users know how big each grid cell is */
- if (*grid_unit == NULL) {
- *grid_unit = bUnit_GetNameDisplay(usys, i);
- rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
- }
- blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
+ /* setup view matrix */
+ if (viewmat)
+ copy_m4_m4(rv3d->viewmat, viewmat);
+ else
+ view3d_viewmatrix_set(eval_ctx, scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
- /* tweak to have the fade a bit nicer */
- blend_fac = (blend_fac * blend_fac) * 2.0f;
- CLAMP(blend_fac, 0.3f, 1.0f);
+ /* update utility matrices */
+ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ /* calculate GLSL view dependent values */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac);
+ /* store window coordinates scaling/offset */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ rctf cameraborder;
+ 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);
- drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
- }
- }
+ rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
+ rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
}
else {
- const double sublines = v3d->gridsubdiv;
- const float sublines_fl = v3d->gridsubdiv;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
- if (dx < GRID_MIN_PX_D) {
- /* pass */
- }
- else {
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx);
- }
- }
- else { /* start blending out */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
-
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
- }
- }
- else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
-
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
- }
- }
- else {
- if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines_fl;
- dx /= sublines;
- if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines_fl;
- dx /= sublines;
- if (dx > (GRID_MIN_PX_D * 10.0)) {
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx);
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
+ rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
+ rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
+ /* calculate pixelsize factor once, is used for lamps and obcenters */
+ {
+ /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
+ * because of float point precision problems at large values [#23908] */
+ float v1[3], v2[3];
+ float len_px, len_sc;
- x += (wx);
- y += (wy);
- UI_GetThemeColor3ubv(TH_GRID, col);
-
- setlinestyle(0);
-
- /* center cross */
- /* horizontal line */
- if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
- UI_make_axis_color(col, col2, 'Y');
- else UI_make_axis_color(col, col2, 'X');
- glColor3ubv(col2);
-
- fdrawline(0.0, y, (float)ar->winx, y);
-
- /* vertical line */
- if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
- UI_make_axis_color(col, col2, 'Y');
- else UI_make_axis_color(col, col2, 'Z');
- glColor3ubv(col2);
-
- fdrawline(x, 0.0, x, (float)ar->winy);
-
- glDepthMask(GL_TRUE); /* enable write in zbuffer */
-}
-#undef GRID_MIN_PX
+ v1[0] = rv3d->persmat[0][0];
+ v1[1] = rv3d->persmat[1][0];
+ v1[2] = rv3d->persmat[2][0];
-/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
-float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
-{
- /* apply units */
- if (scene->unit.system) {
- const void *usys;
- int len;
+ v2[0] = rv3d->persmat[0][1];
+ v2[1] = rv3d->persmat[1][1];
+ v2[2] = rv3d->persmat[2][1];
- bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
+ len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
+ len_sc = (float)MAX2(ar->winx, ar->winy);
- if (usys) {
- int i = bUnit_GetBaseUnit(usys);
- if (grid_unit)
- *grid_unit = bUnit_GetNameDisplay(usys, i);
- return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
- }
+ rv3d->pixsize = len_px / len_sc;
}
-
- 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);
}
-static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
+static void view3d_main_region_setup_view(
+ const EvaluationContext *eval_ctx, Scene *scene,
+ View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
- 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);
- grid = gridlines * grid_scale;
-
- if (!write_depth)
- glDepthMask(GL_FALSE);
-
- UI_GetThemeColor3ubv(TH_GRID, col_grid);
-
- glLineWidth(1);
-
- /* draw the Y axis and/or grid lines */
- if (v3d->gridflag & V3D_SHOW_FLOOR) {
- const int sublines = v3d->gridsubdiv;
- float vert[4][3] = {{0.0f}};
- unsigned char col_bg[3];
- unsigned char col_grid_emphasise[3], col_grid_light[3];
- int a;
- int prev_emphasise = -1;
-
- 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,
- (((col_grid[0] + col_grid[1] + col_grid[2]) + 30) >
- (col_bg[0] + col_bg[1] + col_bg[2])) ? 20 : -10);
-
- /* set fixed axis */
- vert[0][0] = vert[2][1] = grid;
- vert[1][0] = vert[3][1] = -grid;
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vert);
-
- for (a = -gridlines; a <= gridlines; a++) {
- const float line = a * grid_scale;
- const int is_emphasise = (a % sublines) == 0;
-
- if (is_emphasise != prev_emphasise) {
- glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light);
- prev_emphasise = is_emphasise;
- }
-
- /* set variable axis */
- vert[0][1] = vert[1][1] = vert[2][0] = vert[3][0] = line;
+ RegionView3D *rv3d = ar->regiondata;
- glDrawArrays(GL_LINES, 0, 4);
- }
+ ED_view3d_update_viewmat(eval_ctx, scene, v3d, ar, viewmat, winmat, rect);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
-
- /* draw the Z axis line */
- /* check for the 'show Z axis' preference */
- if (v3d->gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
- glBegin(GL_LINES);
- int axis;
- 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);
- }
- }
- glEnd();
- }
-
- glDepthMask(GL_TRUE);
+ /* set for opengl */
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
-
-static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
+static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- int co[2];
-
- /* we don't want the clipping for cursor */
- if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- const float f5 = 0.25f * U.widget_unit;
- const float f10 = 0.5f * U.widget_unit;
- const float f20 = U.widget_unit;
-
- glLineWidth(1);
- setlinestyle(0);
- cpack(0xFF);
- circ((float)co[0], (float)co[1], f10);
- setlinestyle(4);
- cpack(0xFFFFFF);
- circ((float)co[0], (float)co[1], f10);
- setlinestyle(0);
-
- UI_ThemeColor(TH_VIEW_OVERLAY);
- 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);
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ return false;
}
-}
-
-/* Draw a live substitute of the view icon, which is always shown
- * colors copied from transform_manipulator.c, we should keep these matching. */
-static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
-{
- const float k = U.rvisize * U.pixelsize; /* axis size */
- const float toll = 0.5; /* used to see when view is quasi-orthogonal */
- float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
- float starty = k + 1.0f;
- float ydisp = 0.0; /* vertical displacement to allow obj info text */
- int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
- float vec[3];
- float dx, dy;
-
- int axis_order[3] = {0, 1, 2};
- int axis_i;
- startx += rect->xmin;
- starty += rect->ymin;
-
- axis_sort_v3(rv3d->viewinv[2], axis_order);
-
- /* thickness of lines is proportional to k */
- glLineWidth(2);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- for (axis_i = 0; axis_i < 3; axis_i++) {
- int i = axis_order[axis_i];
- const char axis_text[2] = {'x' + i, '\0'};
-
- 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);
-
- /* BLF_draw_default disables blending */
- glEnable(GL_BLEND);
- }
+ if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
+ return false;
}
- glDisable(GL_BLEND);
-}
-
-#ifdef WITH_INPUT_NDOF
-/* draw center and axis of rotation for ongoing 3D mouse navigation */
-static void draw_rotation_guide(RegionView3D *rv3d)
-{
- float o[3]; /* center of rotation */
- float end[3]; /* endpoints for drawing */
-
- float color[4] = {0.0f, 0.4235f, 1.0f, 1.0f}; /* bright blue so it matches device LEDs */
-
- negate_v3_v3(o, rv3d->ofs);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPointSize(5);
- glEnable(GL_POINT_SMOOTH);
- glDepthMask(0); /* don't overwrite zbuf */
-
- if (rv3d->rot_angle != 0.0f) {
- /* -- draw rotation axis -- */
- float scaled_axis[3];
- const float scale = rv3d->dist;
- mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
-
-
- glBegin(GL_LINE_STRIP);
- color[3] = 0.0f; /* more transparent toward the ends */
- glColor4fv(color);
- add_v3_v3v3(end, o, scaled_axis);
- glVertex3fv(end);
-
-#if 0
- color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
- /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
-#endif
-
- color[3] = 0.5f; /* more opaque toward the center */
- glColor4fv(color);
- glVertex3fv(o);
-
- color[3] = 0.0f;
- glColor4fv(color);
- sub_v3_v3v3(end, o, scaled_axis);
- glVertex3fv(end);
- glEnd();
-
- /* -- draw ring around rotation center -- */
- {
-#define ROT_AXIS_DETAIL 13
-
- const float s = 0.05f * scale;
- const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
- float angle;
- int i;
-
- float q[4]; /* rotate ring so it's perpendicular to axis */
- const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
- if (!upright) {
- const float up[3] = {0.0f, 0.0f, 1.0f};
- float vis_angle, vis_axis[3];
-
- cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
- vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
- axis_angle_to_quat(q, vis_axis, vis_angle);
+ switch (v3d->stereo3d_camera) {
+ case STEREO_MONO_ID:
+ return false;
+ 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;
}
-
- color[3] = 0.25f; /* somewhat faint */
- glColor4fv(color);
- glBegin(GL_LINE_LOOP);
- for (i = 0, angle = 0.0f; i < ROT_AXIS_DETAIL; ++i, angle += step) {
- float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
-
- if (!upright) {
- mul_qt_v3(q, p);
- }
-
- add_v3_v3(p, o);
- glVertex3fv(p);
+ if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
+ !BKE_scene_multiview_is_stereo3d(&scene->r))
+ {
+ return false;
}
- glEnd();
-
-#undef ROT_AXIS_DETAIL
- }
-
- color[3] = 1.0f; /* solid dot */
- }
- else
- color[3] = 0.5f; /* see-through dot */
-
- /* -- draw rotation center -- */
- glColor4fv(color);
- glBegin(GL_POINTS);
- glVertex3fv(o);
- glEnd();
-
-#if 0
- /* find screen coordinates for rotation center, then draw pretty icon */
- mul_m4_v3(rv3d->persinv, rot_center);
- UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
- /* ^^ just playing around, does not work */
-#endif
-
- glDisable(GL_BLEND);
- glDisable(GL_POINT_SMOOTH);
- glDepthMask(1);
-}
-#endif /* WITH_INPUT_NDOF */
-
-static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
-{
- BIFIconID icon;
-
- 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;
- else return;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
-
- glDisable(GL_BLEND);
-}
-
-static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
-{
- const char *name = NULL;
-
- switch (rv3d->view) {
- case RV3D_VIEW_FRONT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
- else name = IFACE_("Front Persp");
- break;
- case RV3D_VIEW_BACK:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
- else name = IFACE_("Back Persp");
- break;
- case RV3D_VIEW_TOP:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
- else name = IFACE_("Top Persp");
- break;
- case RV3D_VIEW_BOTTOM:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
- else name = IFACE_("Bottom Persp");
- break;
- case RV3D_VIEW_RIGHT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
- else name = IFACE_("Right Persp");
break;
- case RV3D_VIEW_LEFT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
- else name = IFACE_("Left Persp");
- break;
-
+ /* We always need the stereo calculation for left and right cameras. */
+ case STEREO_LEFT_ID:
+ case STEREO_RIGHT_ID:
default:
- if (rv3d->persp == RV3D_CAMOB) {
- if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
- Camera *cam;
- cam = v3d->camera->data;
- if (cam->type == CAM_PERSP) {
- name = IFACE_("Camera Persp");
- }
- else if (cam->type == CAM_ORTHO) {
- name = IFACE_("Camera Ortho");
- }
- else {
- BLI_assert(cam->type == CAM_PANO);
- name = IFACE_("Camera Pano");
- }
- }
- else {
- name = IFACE_("Object as Camera");
- }
- }
- else {
- name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
- }
break;
}
-
- return name;
+ return true;
}
-static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
- const char *name = view3d_get_name(v3d, rv3d);
- /* increase size for unicode languages (Chinese in utf-8...) */
-#ifdef WITH_INTERNATIONAL
- char tmpstr[96];
-#else
- char tmpstr[32];
-#endif
- if (v3d->localvd) {
- BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
- name = tmpstr;
- }
+/* setup the view and win matrices for the multiview cameras
+ *
+ * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
+ * we have no winmatrix (i.e., projection matrix) defined at that time.
+ * Since the camera and the camera shift are needed for the winmat calculation
+ * we do a small hack to replace it temporarily so we don't need to change the
+ * view3d)main_region_setup_view() code to account for that.
+ */
+static void view3d_stereo3d_setup(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+{
+ bool is_left;
+ const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
+ const char *viewname;
- UI_ThemeColor(TH_TEXT_HI);
-#ifdef WITH_INTERNATIONAL
- BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
-#else
- BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
-#endif
-}
+ /* show only left or right camera */
+ if (v3d->stereo3d_camera != STEREO_3D_ID)
+ v3d->multiview_eye = v3d->stereo3d_camera;
-/* draw info beside axes in bottom left-corner:
- * framenum, object name, bone name (if available), marker name (if available)
- */
+ is_left = v3d->multiview_eye == STEREO_LEFT_ID;
+ viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
-static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
-{
- const int cfra = CFRA;
- const char *msg_pin = " (Pinned)";
- const char *msg_sep = " : ";
+ /* 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;
- char info[300];
- const char *markern;
- char *s = info;
- short offset = 1.5f * UI_UNIT_X + rect->xmin;
+ data = (Camera *)v3d->camera->data;
+ shiftx = data->shiftx;
- s += sprintf(s, "(%d)", cfra);
+ BLI_lock_thread(LOCK_VIEW3D);
+ data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
- /*
- * 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)
- */
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
- /* get name of marker on current frame (if available) */
- markern = BKE_scene_find_marker_name(scene, cfra);
-
- /* check if there is an object */
- if (ob) {
- *s++ = ' ';
- s += BLI_strcpy_rlen(s, ob->id.name + 2);
+ data->shiftx = shiftx;
+ BLI_unlock_thread(LOCK_VIEW3D);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *view_ob = v3d->camera;
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
- /* name(s) to display depends on type of object */
- if (ob->type == OB_ARMATURE) {
- bArmature *arm = ob->data;
-
- /* show name of active bone too (if possible) */
- if (arm->edbo) {
- if (arm->act_edbone) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_edbone->name);
- }
- }
- else if (ob->mode & OB_MODE_POSE) {
- if (arm->act_bone) {
+ BLI_lock_thread(LOCK_VIEW3D);
+ v3d->camera = camera;
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
- else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
- Key *key = NULL;
- KeyBlock *kb = NULL;
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
- /* try to display active bone and active shapekey too (if they exist) */
+ v3d->camera = view_ob;
+ BLI_unlock_thread(LOCK_VIEW3D);
+ }
+}
- if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
- Object *armobj = BKE_object_pose_armature_get(ob);
- if (armobj && armobj->mode & OB_MODE_POSE) {
- bArmature *arm = armobj->data;
- if (arm->act_bone) {
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
+/**
+ * Set the correct matrices
+ */
+void ED_view3d_draw_setup_view(
+ wmWindow *win, const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d,
+ float viewmat[4][4], float winmat[4][4], const rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
- key = BKE_key_from_object(ob);
- if (key) {
- kb = BLI_findlink(&key->block, ob->shapenr - 1);
- if (kb) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, kb->name);
- if (ob->shapeflag & OB_SHAPE_LOCK) {
- s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
- }
- }
- }
- }
-
- /* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
- UI_ThemeColor(TH_TIME_KEYFRAME);
- else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
- UI_ThemeColor(TH_TIME_GP_KEYFRAME);
- else
- UI_ThemeColor(TH_TEXT_HI);
+ /* Setup the view matrix. */
+ if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, rect);
}
else {
- /* no object */
- if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
- UI_ThemeColor(TH_TIME_GP_KEYFRAME);
- else
- UI_ThemeColor(TH_TEXT_HI);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, rect);
}
-
- if (markern) {
- s += sprintf(s, " <%s>", markern);
- }
-
- if (U.uiflag & USER_SHOW_ROTVIEWICON)
- offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
-
- BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
+/* ******************** view border ***************** */
+
static void view3d_camera_border(
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
rctf *r_viewborder, const bool no_shift, const bool no_zoom)
@@ -1023,7 +357,7 @@ void ED_view3d_calc_camera_border(
view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
}
-static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
+static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
{
float x3, y3, x4, y4;
@@ -1032,29 +366,33 @@ static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float f
x4 = x1 + (1.0f - fac) * (x2 - x1);
y4 = y1 + (1.0f - fac) * (y2 - y1);
- glBegin(GL_LINES);
- glVertex2f(x1, y3);
- glVertex2f(x2, y3);
+ immBegin(GWN_PRIM_LINES, 8);
+
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
- glVertex2f(x1, y4);
- glVertex2f(x2, y4);
+ immVertex2f(shdr_pos, x1, y4);
+ immVertex2f(shdr_pos, x2, y4);
- glVertex2f(x3, y1);
- glVertex2f(x3, y2);
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
- glVertex2f(x4, y1);
- glVertex2f(x4, y2);
- glEnd();
+ immVertex2f(shdr_pos, x4, y1);
+ immVertex2f(shdr_pos, x4, y2);
+
+ immEnd();
}
/* harmonious triangle */
-static void drawviewborder_triangle(float x1, float x2, float y1, float y2, const char golden, const char dir)
+static void drawviewborder_triangle(
+ uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
{
float ofs;
float w = x2 - x1;
float h = y2 - y1;
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 6);
+
if (w > h) {
if (golden) {
ofs = w * (1.0f - (1.0f / 1.61803399f));
@@ -1064,14 +402,14 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons
}
if (dir == 'B') SWAP(float, y1, y2);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- glVertex2f(x2, y1);
- glVertex2f(x1 + (w - ofs), y2);
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1 + (w - ofs), y2);
- glVertex2f(x1, y2);
- glVertex2f(x1 + ofs, y1);
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x1 + ofs, y1);
}
else {
if (golden) {
@@ -1082,16 +420,17 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons
}
if (dir == 'B') SWAP(float, x1, x2);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- glVertex2f(x2, y1);
- glVertex2f(x1, y1 + ofs);
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1, y1 + ofs);
- glVertex2f(x1, y2);
- glVertex2f(x2, y1 + (h - ofs));
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1 + (h - ofs));
}
- glEnd();
+
+ immEnd();
}
static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
@@ -1128,58 +467,76 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
y1i = (int)(y1 - 1.0001f);
x2i = (int)(x2 + (1.0f - 0.0001f));
y2i = (int)(y2 + (1.0f - 0.0001f));
-
- /* passepartout, specified in camera edit buttons */
- if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
- const float winx = (ar->winx + 1);
- const float winy = (ar->winy + 1);
- if (ca->passepartalpha == 1.0f) {
- glColor3f(0, 0, 0);
+ uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ /* First, solid lines. */
+ {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* passepartout, specified in camera edit buttons */
+ if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
+ const float winx = (ar->winx + 1);
+ const float winy = (ar->winy + 1);
+
+ float alpha = 1.0f;
+
+ if (ca->passepartalpha != 1.0f) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ alpha = ca->passepartalpha;
+ }
+
+ immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
+
+ if (x1i > 0.0f)
+ immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
+ if (x2i < winx)
+ immRectf(shdr_pos, x2i, winy, winx, 0.0f);
+ if (y2i < winy)
+ immRectf(shdr_pos, x1i, winy, x2i, y2i);
+ if (y2i > 0.0f)
+ immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
+
+ glDisable(GL_BLEND);
}
- else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glColor4f(0, 0, 0, ca->passepartalpha);
+
+ immUniformThemeColor(TH_BACK);
+ imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
+
+#ifdef VIEW3D_CAMERA_BORDER_HACK
+ if (view3d_camera_border_hack_test == true) {
+ immUniformColor3ubv(view3d_camera_border_hack_col);
+ imm_draw_box_wire_2d(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
+ view3d_camera_border_hack_test = false;
}
+#endif
- if (x1i > 0.0f)
- glRectf(0.0, winy, x1i, 0.0);
- if (x2i < winx)
- glRectf(x2i, winy, winx, 0.0);
- if (y2i < winy)
- glRectf(x1i, winy, x2i, y2i);
- if (y2i > 0.0f)
- glRectf(x1i, y1i, x2i, 0.0);
-
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
- setlinestyle(0);
+ /* And now, the dashed lines! */
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- UI_ThemeColor(TH_BACK);
-
- fdrawbox(x1i, y1i, x2i, y2i);
+ {
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
-#ifdef VIEW3D_CAMERA_BORDER_HACK
- if (view3d_camera_border_hack_test == true) {
- glColor3ubv(view3d_camera_border_hack_col);
- fdrawbox(x1i + 1, y1i + 1, x2i - 1, y2i - 1);
- view3d_camera_border_hack_test = false;
- }
-#endif
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- setlinestyle(3);
+ /* outer line not to confuse with object selection */
+ if (v3d->flag2 & V3D_LOCK_CAMERA) {
+ immUniformThemeColor(TH_REDALERT);
+ imm_draw_box_wire_2d(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
+ }
- /* outer line not to confuse with object selecton */
- if (v3d->flag2 & V3D_LOCK_CAMERA) {
- UI_ThemeColor(TH_REDALERT);
- fdrawbox(x1i - 1, y1i - 1, x2i + 1, y2i + 1);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
}
- UI_ThemeColor(TH_VIEW_OVERLAY);
- fdrawbox(x1i, y1i, x2i, y2i);
-
/* border */
if (scene->r.mode & R_BORDER) {
float x3, y3, x4, y4;
@@ -1189,82 +546,76 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
- cpack(0x4040FF);
- sdrawbox(x3, y3, x4, y4);
+ immUniformColor3f(1.0f, 0.25f, 0.25f);
+ imm_draw_box_wire_2d(shdr_pos, x3, y3, x4, y4);
}
/* safety border */
if (ca) {
+ immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
+
if (ca->dtx & CAM_DTX_CENTER) {
float x3, y3;
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
-
x3 = x1 + 0.5f * (x2 - x1);
y3 = y1 + 0.5f * (y2 - y1);
- glBegin(GL_LINES);
- glVertex2f(x1, y3);
- glVertex2f(x2, y3);
+ immBegin(GWN_PRIM_LINES, 4);
- glVertex2f(x3, y1);
- glVertex2f(x3, y2);
- glEnd();
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
+
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
+
+ immEnd();
}
if (ca->dtx & CAM_DTX_CENTER_DIAG) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
+ immBegin(GWN_PRIM_LINES, 4);
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- glVertex2f(x1, y2);
- glVertex2f(x2, y1);
- glEnd();
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1);
+
+ immEnd();
}
if (ca->dtx & CAM_DTX_THIRDS) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f / 3.0f);
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
}
if (ca->dtx & CAM_DTX_GOLDEN) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'A');
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'B');
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'A');
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
}
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
UI_draw_safe_areas(
- x1, x2, y1, y2,
- scene->safe_areas.title,
- scene->safe_areas.action);
+ shdr_pos, 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);
+ shdr_pos, x1, x2, y1, y2,
+ scene->safe_areas.title_center, scene->safe_areas.action_center);
}
}
@@ -1300,1776 +651,1294 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
}
/* draw */
- UI_ThemeColorShade(TH_VIEW_OVERLAY, 100);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
+ immUniformThemeColorShade(TH_VIEW_OVERLAY, 100);
+
+ /* TODO Was using UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color).
+ * We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
+ * 2.0f round corner effect was nearly not visible anyway... */
+ imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
}
- setlinestyle(0);
+ immUnbindProgram();
+ /* end dashed lines */
/* camera name - draw in highlighted text color */
if (ca && (ca->flag & CAM_SHOWNAME)) {
- UI_ThemeColor(TH_TEXT_HI);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
BLF_draw_default(
x1i, y1i - (0.7f * U.widget_unit), 0.0f,
v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
}
}
-/* *********************** backdraw for selection *************** */
+static void drawrenderborder(ARegion *ar, View3D *v3d)
+{
+ /* use the same program for everything */
+ uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ glLineWidth(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ imm_draw_box_wire_2d(shdr_pos,
+ v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
+ v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
+
+ immUnbindProgram();
+}
-static void backdrawview3d(Scene *scene, wmWindow *win, ARegion *ar, View3D *v3d)
+void ED_view3d_draw_depth(
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d, bool alphaoverride)
{
+ struct bThemeState theme_state;
+ Scene *scene = DEG_get_evaluated_scene(graph);
RegionView3D *rv3d = ar->regiondata;
- struct Base *base = scene->basact;
- int multisample_enabled;
- BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
+ 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;
- if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
- BKE_paint_select_face_test(base->object)))
- {
- /* do nothing */
- }
- /* texture paint mode sampling */
- else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
- (v3d->drawtype > OB_WIRE))
- {
- /* do nothing */
- }
- else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
- V3D_IS_ZBUF(v3d))
- {
- /* do nothing */
- }
- else if (scene->obedit &&
- V3D_IS_ZBUF(v3d))
- {
- /* do nothing */
- }
- else {
- v3d->flag &= ~V3D_INVALID_BACKBUF;
- return;
- }
+ /* Tools may request depth outside of regular drawing code. */
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
- if (!(v3d->flag & V3D_INVALID_BACKBUF))
- return;
+ ED_view3d_draw_setup_view(NULL, eval_ctx, scene, ar, v3d, NULL, NULL, NULL);
-#if 0
- if (test) {
- if (qtest()) {
- addafterqueue(ar->win, BACKBUFDRAW, 1);
- return;
- }
- }
-#endif
+ glClear(GL_DEPTH_BUFFER_BIT);
- if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
-
- /* dithering and AA break color coding, so disable */
- glDisable(GL_DITHER);
-
- multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
- if (multisample_enabled)
- glDisable(GL_MULTISAMPLE);
-
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- /* 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) {
- if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
- GPU_offscreen_height(rv3d->gpuoffscreen) != h)
- {
- GPU_offscreen_free(rv3d->gpuoffscreen);
- rv3d->gpuoffscreen = NULL;
- }
- }
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+ /* get surface depth without bias */
+ rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
- if (!rv3d->gpuoffscreen) {
- rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, error);
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
- if (!rv3d->gpuoffscreen)
- fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
- }
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ /* temp, calls into view3d_draw_legacy.c */
+ ED_view3d_draw_depth_loop(scene, ar, v3d);
}
-
- if (rv3d->gpuoffscreen)
- GPU_offscreen_bind(rv3d->gpuoffscreen, true);
else
- glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- if (v3d->zbuf) {
- glEnable(GL_DEPTH_TEST);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+#endif /* WITH_OPENGL_LEGACY */
+ {
+ DRW_draw_depth_loop(graph, ar, v3d);
}
- else {
- glClear(GL_COLOR_BUFFER_BIT);
- glDisable(GL_DEPTH_TEST);
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
}
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_set(rv3d);
-
- G.f |= G_BACKBUFSEL;
-
- if (base && (base->lay & v3d->lay))
- draw_object_backbufsel(scene, v3d, rv3d, base->object);
-
- if (rv3d->gpuoffscreen)
- GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
- else
- ar->swap = 0; /* mark invalid backbuf for wm draw */
+ rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
- v3d->flag &= ~V3D_INVALID_BACKBUF;
+ v3d->zbuf = zbuf;
+ if (!v3d->zbuf) glDisable(GL_DEPTH_TEST);
- G.f &= ~G_BACKBUFSEL;
- v3d->zbuf = false;
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_DITHER);
- if (multisample_enabled)
- glEnable(GL_MULTISAMPLE);
+ U.glalphaclip = glalphaclip;
+ v3d->flag = flag;
+ U.obcenter_dia = obcenter_dia;
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
+ UI_Theme_Restore(&theme_state);
}
-void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+/* ******************** background plates ***************** */
+
+static void view3d_draw_background_gradient(void)
{
- RegionView3D *rv3d = ar->regiondata;
+ /* TODO: finish 2D API & draw background with that */
- if (rv3d->gpuoffscreen) {
- GPU_offscreen_bind(rv3d->gpuoffscreen, true);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glReadPixels(x, y, w, h, format, type, data);
- GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
- }
- else {
- glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
- }
-}
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ unsigned char col_hi[3], col_lo[3];
-/* 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)
-{
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
-}
+ UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
+ UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
-void ED_view3d_backbuf_validate(ViewContext *vc)
-{
- if (vc->v3d->flag & V3D_INVALID_BACKBUF)
- backdrawview3d(vc->scene, vc->win, vc->ar, vc->v3d);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
+ immAttrib3ubv(color, col_lo);
+ immVertex2f(pos, -1.0f, -1.0f);
+ immVertex2f(pos, 1.0f, -1.0f);
+
+ immAttrib3ubv(color, col_hi);
+ immVertex2f(pos, 1.0f, 1.0f);
+ immVertex2f(pos, -1.0f, 1.0f);
+ immEnd();
+
+ immUnbindProgram();
}
-/**
- * allow for small values [0.5 - 2.5],
- * and large values, FLT_MAX by clamping by the area size
- */
-int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
+static void view3d_draw_background_none(void)
{
- return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+ UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
}
-/* samples a single pixel (copied from vpaint) */
-unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y)
+static void view3d_draw_background_world(Scene *scene, RegionView3D *rv3d)
{
- unsigned int col;
-
- if (x >= vc->ar->winx || y >= vc->ar->winy) {
- return 0;
- }
+ if (scene->world) {
+ GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
- ED_view3d_backbuf_validate(vc);
+ /* calculate full shader for background */
+ GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac);
+
+ if (GPU_material_bound(gpumat)) {
+ /* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode,
+ * we can't get rid of the following code without a bigger refactor
+ * or we dropping this functionality. */
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2f(-1.0f, -1.0f);
+ glVertex2f(1.0f, -1.0f);
+ glVertex2f(-1.0f, 1.0f);
+ glVertex2f(1.0f, 1.0f);
+ glEnd();
- view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
- glReadBuffer(GL_BACK);
-
- if (ENDIAN_ORDER == B_ENDIAN) {
- BLI_endian_switch_uint32(&col);
+ GPU_material_unbind(gpumat);
+ return;
+ }
}
-
- return GPU_select_to_index(col);
-}
-/* reads full rect, converts indices */
-ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
-{
- struct ImBuf *ibuf_clip;
- /* clip */
- 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)))
- {
- return NULL;
- }
+ /* if any of the above fails */
+ view3d_draw_background_none();
+}
- ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
+/* ******************** other elements ***************** */
- ED_view3d_backbuf_validate(vc);
- view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
+#define DEBUG_GRID 0
- glReadBuffer(GL_BACK);
+static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count)
+{
+ /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
+ * x0 is gridline 0, the axis in screen space
+ * Area covers [0 .. max) pixels */
- if (ENDIAN_ORDER == B_ENDIAN) {
- IMB_convert_rgba_to_abgr(ibuf_clip);
- }
+ int first = (int)ceil(-x0 / dx);
+ int last = (int)floor((max - x0) / dx);
- GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]);
-
- if ((clip.xmin == xmin) &&
- (clip.xmax == xmax) &&
- (clip.ymin == ymin) &&
- (clip.ymax == ymax))
- {
- return ibuf_clip;
+ if (first <= last) {
+ *r_first = first;
+ *r_count = last - first + 1;
}
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;
+ *r_first = 0;
+ *r_count = 0;
}
+
+#if DEBUG_GRID
+ printf(" first %d * dx = %f\n", first, x0 + first * dx);
+ printf(" last %d * dx = %f\n", last, x0 + last * dx);
+ printf(" count = %d\n", *count_out);
+#endif
}
-/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-unsigned int ED_view3d_backbuf_sample_rect(
- ViewContext *vc, const int mval[2], int size,
- unsigned int min, unsigned int max, float *r_dist)
+static int gridline_count(ARegion *ar, double x0, double y0, double dx)
{
- struct ImBuf *buf;
- const unsigned int *bufmin, *bufmax, *tbuf;
- int minx, miny;
- int a, b, rc, nr, amount, dirvec[4][2];
- unsigned int index = 0;
+ /* x0 & y0 establish the "phase" of the grid within this 2D region
+ * dx is the frequency, shared by x & y directions
+ * pass in dx of smallest (highest precision) grid we want to draw */
- amount = (size - 1) / 2;
+#if DEBUG_GRID
+ printf(" %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx);
+#endif
- minx = mval[0] - (amount + 1);
- miny = mval[1] - (amount + 1);
- buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1);
- if (!buf) return 0;
+ int first, x_ct, y_ct;
- rc = 0;
-
- 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;
-
- bufmin = buf->rect;
- tbuf = buf->rect;
- bufmax = buf->rect + size * size;
- tbuf += amount * size + amount;
-
- for (nr = 1; nr <= size; nr++) {
-
- for (a = 0; a < 2; a++) {
- for (b = 0; b < nr; b++) {
- if (*tbuf && *tbuf >= min && *tbuf < max) {
- /* we got a hit */
-
- /* get x,y pixel coords from the offset
- * (manhatten distance in keeping with other screen-based selection) */
- *r_dist = (float)(
- abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
- abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
-
- /* indices start at 1 here */
- index = (*tbuf - min) + 1;
- goto exit;
- }
-
- tbuf += (dirvec[rc][0] + dirvec[rc][1]);
-
- if (tbuf < bufmin || tbuf >= bufmax) {
- goto exit;
- }
- }
- rc++;
- rc &= 3;
- }
- }
+ gridline_range(x0, dx, ar->winx, &first, &x_ct);
+ gridline_range(y0, dx, ar->winy, &first, &y_ct);
-exit:
- IMB_freeImBuf(buf);
- return index;
-}
+ int total_ct = x_ct + y_ct;
+#if DEBUG_GRID
+ printf(" %d + %d = %d gridlines\n", x_ct, y_ct, total_ct);
+#endif
-/* ************************************************************* */
+ return total_ct;
+}
-static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
+static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3])
{
- if (BKE_image_is_stereo(ima)) {
- iuser->flag |= IMA_SHOW_STEREO;
+ /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
+ * always skip exact x0 & y0 axes; they will be drawn later in color
+ *
+ * set grid color once, just before the first line is drawn
+ * it's harmless to set same color for every line, or every vertex
+ * but if no lines are drawn, color must not be set! */
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- iuser->multiview_eye = STEREO_LEFT_ID;
- }
- else if (v3d->stereo3d_camera != STEREO_3D_ID) {
- /* show only left or right camera */
- iuser->multiview_eye = v3d->stereo3d_camera;
- }
+#if DEBUG_GRID
+ printf(" %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod);
+#endif
- BKE_image_multiview_index(ima, iuser);
- }
- else {
- iuser->flag &= ~IMA_SHOW_STEREO;
- }
-}
+ const float x_max = (float)ar->winx;
+ const float y_max = (float)ar->winy;
-static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
-{
- RegionView3D *rv3d = ar->regiondata;
- BGpic *bgpic;
- int fg_flag = do_foreground ? V3D_BGPIC_FOREGROUND : 0;
+ int first, ct;
+ int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
+ int lines_skipped_for_next_unit = 0;
- for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- bgpic->iuser.scene = scene; /* Needed for render results. */
+ /* draw vertical lines */
+ gridline_range(x0, dx, x_max, &first, &ct);
- if ((bgpic->flag & V3D_BGPIC_FOREGROUND) != fg_flag)
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
continue;
+ }
- if ((bgpic->view == 0) || /* zero for any */
- (bgpic->view & (1 << rv3d->view)) || /* check agaist flags */
- (rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA)))
- {
- float image_aspect[2];
- float fac, asp, zoomx, zoomy;
- float x1, y1, x2, y2, centx, centy;
-
- ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
- void *lock;
- rctf clip_rect;
-
- Image *ima = NULL;
- MovieClip *clip = NULL;
-
- /* disable individual images */
- if ((bgpic->flag & V3D_BGPIC_DISABLED))
- continue;
-
- freeibuf = NULL;
- releaseibuf = NULL;
- if (bgpic->source == V3D_BGPIC_IMAGE) {
- ima = bgpic->ima;
- if (ima == NULL)
- continue;
- BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0);
- if (ima->source == IMA_SRC_SEQUENCE && !(bgpic->iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
- ibuf = NULL; /* frame is out of range, dont show */
- }
- else {
- view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
- ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
- releaseibuf = ibuf;
- }
+ if (x_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
- image_aspect[0] = ima->aspx;
- image_aspect[1] = ima->aspy;
- }
- else if (bgpic->source == V3D_BGPIC_MOVIE) {
- /* TODO: skip drawing when out of frame range (as image sequences do above) */
+ float x = (float)(x0 + i * dx);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, y_max);
+ ++x_ct;
+ }
- if (bgpic->flag & V3D_BGPIC_CAMERACLIP) {
- if (scene->camera)
- clip = BKE_object_movieclip_get(scene, scene->camera, true);
- }
- else {
- clip = bgpic->clip;
- }
+ /* draw horizontal lines */
+ gridline_range(y0, dx, y_max, &first, &ct);
- if (clip == NULL)
- continue;
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
+ continue;
+ }
- BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
- ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+ if (x_ct + y_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
- image_aspect[0] = clip->aspx;
- image_aspect[1] = clip->aspy;
+ float y = (float)(y0 + i * dx);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, x_max, y);
+ ++y_ct;
+ }
- /* working with ibuf from image and clip has got different workflow now.
- * ibuf acquired from clip is referenced by cache system and should
- * be dereferenced after usage. */
- freeibuf = ibuf;
- }
- else {
- /* perhaps when loading future files... */
- BLI_assert(0);
- copy_v2_fl(image_aspect, 1.0f);
- }
+#if DEBUG_GRID
+ int total_ct = x_ct + y_ct;
+ printf(" %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit);
+#endif
- if (ibuf == NULL)
- continue;
+ return lines_skipped_for_next_unit > 0;
+}
- if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
+#define GRID_MIN_PX_D 6.0
+#define GRID_MIN_PX_F 6.0f
- continue;
- }
+static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+{
+ RegionView3D *rv3d = ar->regiondata;
- if (ibuf->rect == NULL)
- IMB_rect_from_float(ibuf);
+#if DEBUG_GRID
+ printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy);
+#endif
- if (rv3d->persp == RV3D_CAMOB) {
+ double fx = rv3d->persmat[3][0];
+ double fy = rv3d->persmat[3][1];
+ double fw = rv3d->persmat[3][3];
- if (do_camera_frame) {
- rctf vb;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
- x1 = vb.xmin;
- y1 = vb.ymin;
- x2 = vb.xmax;
- y2 = vb.ymax;
- }
- else {
- x1 = ar->winrct.xmin;
- y1 = ar->winrct.ymin;
- x2 = ar->winrct.xmax;
- y2 = ar->winrct.ymax;
- }
+ const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */
+ const double wy = 0.5 * ar->winy;
- /* 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_ */
- {
- const float max_dim = max_ff(x2 - x1, y2 - y1);
- 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;
- }
+ double x = wx * fx / fw;
+ double y = wy * fy / fw;
- centx = (x1 + x2) / 2.0f;
- centy = (y1 + y2) / 2.0f;
+ double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 };
+ mul_m4_v4d(rv3d->persmat, vec4);
+ fx = vec4[0];
+ fy = vec4[1];
+ fw = vec4[3];
- /* aspect correction */
- if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) {
- /* apply aspect from clip */
- const float w_src = ibuf->x * image_aspect[0];
- const float h_src = ibuf->y * image_aspect[1];
+ double dx = fabs(x - wx * fx / fw);
+ if (dx == 0) dx = fabs(y - wy * fy / fw);
- /* destination aspect is already applied from the camera frame */
- const float w_dst = x1 - x2;
- const float h_dst = y1 - y2;
+ x += wx;
+ y += wy;
- const float asp_src = w_src / h_src;
- const float asp_dst = w_dst / h_dst;
+ /* now x, y, and dx have their final values
+ * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space
+ * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */
- 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;
- x1 = ((x1 - centx) * div) + centx;
- x2 = ((x2 - centx) * div) + centx;
- }
- else {
- /* fit Y */
- const float div = asp_dst / asp_src;
- y1 = ((y1 - centy) * div) + centy;
- y2 = ((y2 - centy) * div) + centy;
- }
- }
- }
- }
- else {
- float tvec[3];
- float sco[2];
- const float mval_f[2] = {1.0f, 0.0f};
- const float co_zero[3] = {0};
- float zfac;
-
- /* calc window coord */
- zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
- ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
- fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
- fac = 1.0f / fac;
-
- asp = (float)ibuf->y / (float)ibuf->x;
-
- zero_v3(tvec);
- ED_view3d_project_float_v2_m4(ar, tvec, sco, rv3d->persmat);
-
- 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);
-
- centx = (x1 + x2) / 2.0f;
- centy = (y1 + y2) / 2.0f;
- }
-
- /* complete clip? */
- BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
- if (bgpic->rotation) {
- BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
- }
+ glLineWidth(1.0f);
- if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
+#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer */
+#endif
- continue;
- }
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
- zoomx = (x2 - x1) / ibuf->x;
- zoomy = (y2 - y1) / ibuf->y;
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
- if (zoomx < 1.0f || zoomy < 1.0f) {
- float tzoom = min_ff(zoomx, zoomy);
- int mip = 0;
+ unsigned char col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
- if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
- IMB_remakemipmap(ibuf, 0);
- ibuf->userflags &= ~IB_MIPMAP_INVALID;
- }
- else if (ibuf->mipmap[0] == NULL)
- IMB_makemipmap(ibuf, 0);
-
- while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
- tzoom *= 2.0f;
- zoomx *= 2.0f;
- zoomy *= 2.0f;
- mip++;
- }
- if (mip > 0)
- ibuf = ibuf->mipmap[mip - 1];
- }
+ if (unit->system) {
+ const void *usys;
+ int len;
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- glDepthMask(0);
+ bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ bool first = true;
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- ED_region_pixelspace(ar);
+ if (usys) {
+ int i = len;
+ while (i--) {
+ double scalar = bUnit_GetScaler(usys, i);
- glTranslatef(centx, centy, 0.0);
- glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
+ double dx_scalar = dx * scalar / (double)unit->scale_length;
+ if (dx_scalar < (GRID_MIN_PX_D * 2.0)) {
+ /* very very small grid items are less useful when dealing with units */
+ continue;
+ }
- if (bgpic->flag & V3D_BGPIC_FLIP_X) {
- zoomx *= -1.0f;
- x1 = x2;
- }
- if (bgpic->flag & V3D_BGPIC_FLIP_Y) {
- zoomy *= -1.0f;
- y1 = y2;
- }
- glPixelZoom(zoomx, zoomy);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
+ if (first) {
+ first = false;
- /* could not use glaDrawPixelsAuto because it could fallback to
- * glaDrawPixelsSafe in some cases, which will end up in missing
- * alpha transparency for the background image (sergey)
- */
- glaDrawPixelsTex(x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
+ /* Store the smallest drawn grid size units name so users know how big each grid cell is */
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
- glPixelZoom(1.0, 1.0);
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+ int gridline_ct = gridline_count(ar, x, y, dx_scalar);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ immBegin(GWN_PRIM_LINES, gridline_ct * 2);
+ }
- glDisable(GL_BLEND);
+ float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
+ /* tweak to have the fade a bit nicer */
+ blend_fac = (blend_fac * blend_fac) * 2.0f;
+ CLAMP(blend_fac, 0.3f, 1.0f);
- glDepthMask(1);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2);
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
+ const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar);
+#if DEBUG_GRID
+ printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar);
+ if (i > 0)
+ printf("next unit is %d times larger\n", skip_mod);
+ else
+ printf("largest unit\n");
+#endif
+ if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2))
+ break;
+ }
}
}
-}
+ else {
+ const double sublines = v3d->gridsubdiv;
+ const float sublines_fl = v3d->gridsubdiv;
-static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
-{
- RegionView3D *rv3d = ar->regiondata;
+ int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */
- if ((v3d->flag & V3D_DISPBGPICS) == 0)
- return;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1;
+ }
+ }
+ }
+ else {
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) {
+ grids_to_draw = 1;
+ }
+ }
+ }
+ }
- /* 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
- if (v3d->flag2 & V3D_RENDER_OVERRIDE)
- return;
-#endif
+ int gridline_ct = gridline_count(ar, x, y, dx);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
- if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
- if (rv3d->persp == RV3D_CAMOB) {
- view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ immBegin(GWN_PRIM_LINES, gridline_ct * 2);
+
+ if (grids_to_draw == 2) {
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
+ if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2))
+ drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
+ }
+ else if (grids_to_draw == 1) {
+ drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
}
}
- else {
- view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+
+ /* draw visible axes */
+ /* horizontal line */
+ if (0 <= y && y < ar->winy) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, (float)ar->winx, y);
+ }
+
+ /* vertical line */
+ if (0 <= x && x < ar->winx) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, (float)ar->winy);
}
-}
-/* ****************** View3d afterdraw *************** */
+ immEnd();
-typedef struct View3DAfter {
- struct View3DAfter *next, *prev;
- struct Base *base;
- short dflag;
-} View3DAfter;
+drawgrid_cleanup:
+ immUnbindProgram();
-/* temp storage of Objects that need to be drawn as last */
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag)
-{
- View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
- BLI_assert((base->flag & OB_FROMDUPLI) == 0);
- BLI_addtail(lb, v3da);
- v3da->base = base;
- v3da->dflag = dflag;
+#if 0 /* depth write is left enabled above */
+ glDepthMask(GL_TRUE); /* enable write in zbuffer */
+#endif
}
-/* disables write in zbuffer and draws it over */
-static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
-{
- View3DAfter *v3da;
-
- glDepthMask(GL_FALSE);
- v3d->transp = true;
-
- while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
- }
- v3d->transp = false;
-
- glDepthMask(GL_TRUE);
-
-}
+#undef DEBUG_GRID
+#undef GRID_MIN_PX_D
+#undef GRID_MIN_PX_F
-/* clears zbuffer and draws it over */
-static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
+static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
{
- View3DAfter *v3da;
+ /* draw only if there is something to draw */
+ if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
+ /* draw how many lines?
+ * trunc(v3d->gridlines / 2) * 4
+ * + 2 for xy axes (possibly with special colors)
+ * + 1 for z axis (the only line not in xy plane)
+ * even v3d->gridlines are honored, odd rounded down */
+ const int gridlines = v3d->gridlines / 2;
+ const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ const float grid = gridlines * grid_scale;
- if (*clear && v3d->zbuf) {
- glClear(GL_DEPTH_BUFFER_BIT);
- *clear = false;
- }
+ const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
- v3d->xray = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
- }
- v3d->xray = false;
-}
+ bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
+ bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
+ bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
+ unsigned char col_grid[3], col_axis[3];
-/* clears zbuffer and draws it over */
-static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
-{
- View3DAfter *v3da;
+ glLineWidth(1.0f);
- if (clear && v3d->zbuf)
- glClear(GL_DEPTH_BUFFER_BIT);
+ UI_GetThemeColor3ubv(TH_GRID, col_grid);
- v3d->xray = true;
- v3d->transp = true;
-
- glDepthMask(GL_FALSE);
+ if (!write_depth)
+ glDepthMask(GL_FALSE);
- while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
- }
+ if (show_floor) {
+ const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
+ const int sublines = v3d->gridsubdiv;
- v3d->transp = false;
- v3d->xray = false;
+ unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
- glDepthMask(GL_TRUE);
-}
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
-/* 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);
- }
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
- View3DAfter *v3da;
- if (*clear && v3d->zbuf) {
- glClear(GL_DEPTH_BUFFER_BIT);
- *clear = false;
- }
+ immBegin(GWN_PRIM_LINES, vertex_ct);
- 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;
-}
+ /* draw normal grid lines */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
-/* *********************** */
+ for (int a = 1; a <= gridlines; a++) {
+ /* skip emphasised divider lines */
+ if (a % sublines != 0) {
+ const float line = a * grid_scale;
-/*
- * 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
- */
+ immAttrib3ubv(color, col_grid_light);
-#if 0
-int dupli_ob_sort(void *arg1, void *arg2)
-{
- void *p1 = ((DupliObject *)arg1)->ob;
- void *p2 = ((DupliObject *)arg2)->ob;
- int val = 0;
- if (p1 < p2) val = -1;
- else if (p1 > p2) val = 1;
- return val;
-}
-#endif
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
+ }
+ }
-static DupliObject *dupli_step(DupliObject *dob)
-{
- while (dob && dob->no_draw)
- dob = dob->next;
- return dob;
-}
+ /* draw emphasised grid lines */
+ UI_GetThemeColor3ubv(TH_BACK, col_bg);
+ /* emphasise division lines lighter instead of darker, if background is darker than grid */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
+ (col_grid[0] + col_grid[1] + col_grid[2] + 30 >
+ col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
-static void draw_dupli_objects_color(
- Scene *scene, ARegion *ar, View3D *v3d, Base *base,
- const short dflag, const int color)
-{
- RegionView3D *rv3d = ar->regiondata;
- ListBase *lb;
- LodLevel *savedlod;
- DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
- Base tbase = {NULL};
- BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
- GLuint displist = 0;
- unsigned char color_rgb[3];
- const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
- short transflag;
- bool use_displist = false; /* -1 is initialize */
- char dt;
- short dtx;
- DupliApplyData *apply_data;
-
- if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
- if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
-
- if (dflag & DRAW_CONSTCOLOR) {
- BLI_assert(color == TH_UNDEFINED);
- }
- else {
- UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
- }
+ if (sublines <= gridlines) {
+ immAttrib3ubv(color, col_grid_emphasise);
+
+ for (int a = sublines; a <= gridlines; a += sublines) {
+ const float line = a * grid_scale;
+
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
- tbase.flag = OB_FROMDUPLI | base->flag;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
- // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
+ }
+ }
- apply_data = duplilist_apply(base->object, scene, lb);
+ /* draw X axis */
+ if (show_axis_x) {
+ show_axis_x = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
+ }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
- dob = dupli_step(lb->first);
- if (dob) dob_next = dupli_step(dob->next);
+ immVertex2f(pos, -grid, 0.0f);
+ immVertex2f(pos, +grid, 0.0f);
- for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
- bool testbb = false;
+ /* draw Y axis */
+ if (show_axis_y) {
+ show_axis_y = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
- tbase.object = dob->ob;
+ immVertex2f(pos, 0.0f, -grid);
+ immVertex2f(pos, 0.0f, +grid);
- /* Make sure lod is updated from dupli's position */
- savedlod = dob->ob->currentlod;
+ immEnd();
+ immUnbindProgram();
-#ifdef WITH_GAMEENGINE
- if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
+ /* done with XY plane */
}
-#endif
- /* 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);
+ if (show_axis_x || show_axis_y || show_axis_z) {
+ /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
- /* 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;
- if (tbase.object->dt != OB_BOUNDBOX)
- tbase.object->dtx = base->object->dtx;
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
- /* negative scale flag has to propagate */
- transflag = tbase.object->transflag;
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+ immBegin(GWN_PRIM_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
- if (is_negative_m4(dob->mat))
- tbase.object->transflag |= OB_NEG_SCALE;
- else
- tbase.object->transflag &= ~OB_NEG_SCALE;
-
- /* should move outside the loop but possible color is set in draw_object still */
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(color_rgb);
- }
-
- /* generate displist, test for new object */
- if (dob_prev && dob_prev->ob != dob->ob) {
- if (use_displist == true)
- glDeleteLists(displist, 1);
-
- use_displist = false;
- }
-
- if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
- bb = *bb_tmp; /* must make a copy */
- testbb = true;
- }
+ if (show_axis_x) {
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, -grid, 0.0f, 0.0f);
+ immVertex3f(pos, +grid, 0.0f, 0.0f);
+ }
- if (!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 */
- (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) ||
- (v3d->flag2 & V3D_SOLID_MATCAP) != 0)
- {
- // 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);
- }
+ if (show_axis_y) {
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, -grid, 0.0f);
+ immVertex3f(pos, 0.0f, +grid, 0.0f);
}
-
- if (use_displist) {
- glPushMatrix();
- glMultMatrixf(dob->mat);
- glCallList(displist);
- glPopMatrix();
- }
- else {
- copy_m4_m4(dob->ob->obmat, dob->mat);
- GPU_begin_dupli_object(dob);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
- GPU_end_dupli_object();
+
+ if (show_axis_z) {
+ UI_make_axis_color(col_grid, col_axis, 'Z');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, 0.0f, -grid);
+ immVertex3f(pos, 0.0f, 0.0f, +grid);
}
+
+ immEnd();
+ immUnbindProgram();
}
-
- tbase.object->dt = dt;
- tbase.object->dtx = dtx;
- tbase.object->transflag = transflag;
- tbase.object->currentlod = savedlod;
+
+ if (!write_depth)
+ glDepthMask(GL_TRUE);
}
+}
+
+/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
+float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
+{
+ /* apply units */
+ if (scene->unit.system) {
+ const void *usys;
+ int len;
+
+ bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
- if (apply_data) {
- duplilist_restore(lb, apply_data);
- duplilist_free_apply_data(apply_data);
+ if (usys) {
+ int i = bUnit_GetBaseUnit(usys);
+ if (grid_unit)
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
+ }
}
- free_object_duplilist(lb);
-
- if (use_displist)
- glDeleteLists(displist, 1);
+ return 1.0f;
}
-static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
+float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
{
- /* define the color here so draw_dupli_objects_color can be called
- * from the set loop */
-
- int color = (base->flag & SELECT) ? TH_SELECT : TH_WIRE;
- /* debug */
- if (base->object->dup_group && base->object->dup_group->id.us < 1)
- color = TH_REDALERT;
-
- draw_dupli_objects_color(scene, ar, v3d, base, 0, color);
+ return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
-/* XXX warning, not using gpu offscreen here */
-void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
+static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
{
- int x, y, w, h;
- rcti r;
- /* clamp rect by region */
+ Object *ob = OBACT(sl);
- r.xmin = 0;
- r.xmax = ar->winx - 1;
- r.ymin = 0;
- r.ymax = ar->winy - 1;
+ /* 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, sl);
- /* Constrain rect to depth bounds */
- BLI_rcti_isect(&r, rect, rect);
+ if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
+ if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
+ return true;
+ }
+ }
+ }
- /* assign values to compare with the ViewDepths */
- x = rect->xmin;
- y = rect->ymin;
+ /* no exception met? then don't draw cursor! */
+ return false;
+ }
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
+ return true;
+}
- if (w <= 0 || h <= 0) {
- if (d->depths)
- MEM_freeN(d->depths);
- d->depths = NULL;
+static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ int co[2];
- d->damaged = false;
- }
- 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;
+ /* we don't want the clipping for cursor */
+ if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ const float f5 = 0.25f * U.widget_unit;
+ const float f10 = 0.5f * U.widget_unit;
+ const float f20 = U.widget_unit;
+
+ glLineWidth(1.0f);
- if (d->depths)
- MEM_freeN(d->depths);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
-
- d->damaged = true;
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- if (d->damaged) {
- /* 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);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
- d->damaged = false;
- }
-}
+ const int segments = 16;
-/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
-void ED_view3d_depth_update(ARegion *ar)
-{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Create storage for, and, if necessary, copy depth buffer */
- if (!rv3d->depths) rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
- if (rv3d->depths) {
- ViewDepths *d = rv3d->depths;
- if (d->w != ar->winx ||
- d->h != ar->winy ||
- !d->depths)
- {
- d->w = ar->winx;
- d->h = ar->winy;
- if (d->depths)
- MEM_freeN(d->depths);
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
- d->damaged = true;
- }
-
- if (d->damaged) {
- view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
-
- d->damaged = false;
- }
- }
-}
+ immBegin(GWN_PRIM_LINE_LOOP, segments);
-/* utility function to find the closest Z value, use for autodepth */
-float view3d_depth_near(ViewDepths *d)
-{
- /* convert to float for comparisons */
- const float near = (float)d->depth_range[0];
- const float far_real = (float)d->depth_range[1];
- float far = far_real;
-
- const float *depths = d->depths;
- float depth = FLT_MAX;
- int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
-
- /* far is both the starting 'far' value
- * and the closest value found. */
- while (i--) {
- depth = *depths++;
- if ((depth < far) && (depth > near)) {
- far = depth;
+ for (int i = 0; i < segments; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)segments);
+ float x = co[0] + f10 * cosf(angle);
+ float y = co[1] + f10 * sinf(angle);
+
+ if (i % 2 == 0)
+ immAttrib3ub(color, 255, 0, 0);
+ else
+ immAttrib3ub(color, 255, 255, 255);
+
+ immVertex2f(pos, x, y);
}
- }
+ immEnd();
- return far == far_real ? FLT_MAX : far;
-}
+ immUnbindProgram();
-void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
-{
- short zbuf = v3d->zbuf;
- RegionView3D *rv3d = ar->regiondata;
+ GWN_vertformat_clear(format);
+ pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- /* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glClear(GL_DEPTH_BUFFER_BIT);
+ unsigned char crosshair_color[3];
+ UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
+ immUniformColor3ubv(crosshair_color);
- v3d->zbuf = true;
- glEnable(GL_DEPTH_TEST);
+ immBegin(GWN_PRIM_LINES, 8);
+ immVertex2f(pos, co[0] - f20, co[1]);
+ immVertex2f(pos, co[0] - f5, co[1]);
+ immVertex2f(pos, co[0] + f5, co[1]);
+ immVertex2f(pos, co[0] + f20, co[1]);
+ immVertex2f(pos, co[0], co[1] - f20);
+ immVertex2f(pos, co[0], co[1] - f5);
+ immVertex2f(pos, co[0], co[1] + f5);
+ immVertex2f(pos, co[0], co[1] + f20);
+ immEnd();
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- ED_gpencil_draw_view3d(NULL, scene, v3d, ar, true);
+ immUnbindProgram();
}
-
- v3d->zbuf = zbuf;
}
-static void view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
+static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
- Base *base;
-
- /* no need for color when drawing depth buffer */
- const short dflag_depth = DRAW_CONSTCOLOR;
-
- /* draw set first */
- if (scene->set) {
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
- if (v3d->lay & base->lay) {
- 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);
- }
- }
- }
- }
-
- 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_color(scene, ar, v3d, base, dflag_depth, TH_UNDEFINED);
- }
- draw_object(scene, ar, v3d, base, dflag_depth);
- }
+ const float k = U.rvisize * U.pixelsize; /* axis size */
+ const int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
+
+ const float startx = rect->xmin + k + 1.0f; /* axis center in screen coordinates, x=y */
+ const float starty = rect->ymin + k + 1.0f;
+
+ float axis_pos[3][2];
+ unsigned char axis_col[3][4];
+
+ int axis_order[3] = {0, 1, 2};
+ axis_sort_v3(rv3d->viewinv[2], axis_order);
+
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
+
+ /* get position of each axis tip on screen */
+ float vec[3] = { 0.0f };
+ vec[i] = 1.0f;
+ mul_qt_v3(rv3d->viewquat, vec);
+ axis_pos[i][0] = startx + vec[0] * k;
+ axis_pos[i][1] = starty + vec[1] * k;
+
+ /* get color of each axis */
+ UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
+ axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
}
-
- /* this isn't that nice, draw xray objects as if they are normal */
- if (v3d->afterdraw_transp.first ||
- v3d->afterdraw_xray.first ||
- v3d->afterdraw_xraytransp.first)
- {
- View3DAfter *v3da;
- int mask_orig;
- v3d->xray = true;
-
- /* transp materials can change the depth mask, see #21388 */
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+ /* draw axis lines */
+ glLineWidth(2.0f);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
- glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
- for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- }
- glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(GWN_PRIM_LINES, 6);
- /* draw 3 passes, transp/xray/xraytransp */
- v3d->xray = false;
- v3d->transp = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
- }
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
- v3d->xray = true;
- v3d->transp = false;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
- }
+ immAttrib4ubv(col, axis_col[i]);
+ immVertex2f(pos, startx, starty);
+ immVertex2fv(pos, axis_pos[i]);
+ }
- v3d->xray = true;
- v3d->transp = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
- }
+ immEnd();
+ immUnbindProgram();
+ glDisable(GL_LINE_SMOOTH);
-
- v3d->xray = false;
- v3d->transp = false;
+ /* draw axis names */
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
- glDepthMask(mask_orig);
+ const char axis_text[2] = {'x' + i, '\0'};
+ BLF_color4ubv(BLF_default(), axis_col[i]);
+ BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
}
}
-void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
+#ifdef WITH_INPUT_NDOF
+/* draw center and axis of rotation for ongoing 3D mouse navigation */
+static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
{
- struct bThemeState theme_state;
- 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;
-
- /* Tools may request depth outside of regular drawing code. */
- UI_Theme_Store(&theme_state);
- UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
+ float o[3]; /* center of rotation */
+ float end[3]; /* endpoints for drawing */
- /* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
-
- glClear(GL_DEPTH_BUFFER_BIT);
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
- /* get surface depth without bias */
- rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
+ GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
- v3d->zbuf = true;
- glEnable(GL_DEPTH_TEST);
+ negate_v3_v3(o, rv3d->ofs);
- view3d_draw_depth_loop(scene, ar, v3d);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthMask(GL_FALSE); /* don't overwrite zbuf */
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
- rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
-
- v3d->zbuf = zbuf;
- if (!v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- U.glalphaclip = glalphaclip;
- v3d->flag = flag;
- U.obcenter_dia = obcenter_dia;
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
- UI_Theme_Restore(&theme_state);
-}
+ if (rv3d->rot_angle != 0.0f) {
+ /* -- draw rotation axis -- */
+ float scaled_axis[3];
+ const float scale = rv3d->dist;
+ mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
-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;
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+ color[3] = 0; /* more transparent toward the ends */
+ immAttrib4ubv(col, color);
+ add_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & v3d->lay) {
+#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
- if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
- (use_obedit_skip && (scene->obedit->data == base->object->data)))
- {
- base->selcol = 0;
- }
- else {
- base->selcol = code;
+ color[3] = 127; /* more opaque toward the center */
+ immAttrib4ubv(col, color);
+ immVertex3fv(pos, o);
- 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++;
- }
+ color[3] = 0;
+ immAttrib4ubv(col, color);
+ sub_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
+ immEnd();
+
+ /* -- draw ring around rotation center -- */
+ {
+#define ROT_AXIS_DETAIL 13
+
+ const float s = 0.05f * scale;
+ const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
+
+ float q[4]; /* rotate ring so it's perpendicular to axis */
+ const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
+ if (!upright) {
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ float vis_angle, vis_axis[3];
+
+ cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
+ vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
+ axis_angle_to_quat(q, vis_axis, vis_angle);
}
- }
- if (use_nearest) {
- bool xrayclear = true;
- if (v3d->afterdraw_xray.first) {
- view3d_draw_xray_select(scene, ar, v3d, &xrayclear);
+ immBegin(GWN_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
+ color[3] = 63; /* somewhat faint */
+ immAttrib4ubv(col, color);
+ float angle = 0.0f;
+ for (int i = 0; i < ROT_AXIS_DETAIL; ++i, angle += step) {
+ float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
+
+ if (!upright) {
+ mul_qt_v3(q, p);
+ }
+
+ add_v3_v3(p, o);
+ immVertex3fv(pos, p);
}
+ immEnd();
+
+#undef ROT_AXIS_DETAIL
}
+
+ color[3] = 255; /* solid dot */
}
+ else
+ color[3] = 127; /* see-through dot */
+
+ immUnbindProgram();
+
+ /* -- draw rotation center -- */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ glPointSize(5.0f);
+ immBegin(GWN_PRIM_POINTS, 1);
+ immAttrib4ubv(col, color);
+ immVertex3fv(pos, o);
+ immEnd();
+ immUnbindProgram();
+
+#if 0
+ /* find screen coordinates for rotation center, then draw pretty icon */
+ mul_m4_v3(rv3d->persinv, rot_center);
+ UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
+ /* ^^ just playing around, does not work */
+#endif
+
+ glDisable(GL_BLEND);
+ glDepthMask(GL_TRUE);
}
+#endif /* WITH_INPUT_NDOF */
-typedef struct View3DShadow {
- struct View3DShadow *next, *prev;
- GPULamp *lamp;
-} View3DShadow;
+/* ******************** info ***************** */
-static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
- Object *ob, Object *par,
- float obmat[4][4], unsigned int lay,
- ListBase *shadows, SceneRenderLayer *srl)
+/**
+* Render and camera border
+*/
+static void view3d_draw_border(const bContext *C, ARegion *ar)
{
- GPULamp *lamp;
- Lamp *la = (Lamp *)ob->data;
- View3DShadow *shadow;
- unsigned int layers;
-
- lamp = GPU_lamp_from_blender(scene, ob, par);
-
- if (lamp) {
- GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
- GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
-
- layers = lay & v3d->lay;
- if (srl)
- layers &= srl->lay;
-
- if (layers &&
- GPU_lamp_has_shadow_buffer(lamp) &&
- /* keep last, may do string lookup */
- GPU_lamp_visible(lamp, srl, NULL))
- {
- shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
- shadow->lamp = lamp;
- BLI_addtail(shadows, shadow);
- }
+ Scene *scene = CTX_data_scene(C);
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ drawviewborder(scene, ar, v3d);
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ drawrenderborder(ar, v3d);
}
}
-static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
+/**
+* Grease Pencil
+*/
+static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
{
- ListBase shadows;
- View3DShadow *shadow;
- Scene *sce_iter;
- Base *base;
- Object *ob;
- World *world = scene->world;
- SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL;
-
- BLI_listbase_clear(&shadows);
-
- /* update lamp transform and gather shadow lamps */
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
-
- if (ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows, srl);
-
- if (ob->transflag & OB_DUPLI) {
- DupliObject *dob;
- ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
-
- for (dob = lb->first; dob; dob = dob->next)
- if (dob->ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows, srl);
-
- free_object_duplilist(lb);
- }
- }
-
- /* render shadows after updating all lamps, nested object_duplilist
- * don't work correct since it's replacing object matrices */
- for (shadow = shadows.first; shadow; shadow = shadow->next) {
- /* this needs to be done better .. */
- float viewmat[4][4], winmat[4][4];
- int drawtype, lay, winsize, flag2 = v3d->flag2;
- ARegion ar = {NULL};
- RegionView3D rv3d = {{{0}}};
-
- drawtype = v3d->drawtype;
- lay = v3d->lay;
-
- v3d->drawtype = OB_SOLID;
- v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
- v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
- v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
-
- GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
-
- ar.regiondata = &rv3d;
- ar.regiontype = RGN_TYPE_WINDOW;
- rv3d.persp = RV3D_CAMOB;
- copy_m4_m4(rv3d.winmat, winmat);
- copy_m4_m4(rv3d.viewmat, viewmat);
- invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
- mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
- invert_m4_m4(rv3d.persinv, rv3d.viewinv);
-
- /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(
- scene, v3d, &ar, winsize, winsize, viewmat, winmat,
- false, false, true,
- NULL, NULL, NULL, NULL);
- GPU_lamp_shadow_buffer_unbind(shadow->lamp);
-
- v3d->drawtype = drawtype;
- v3d->lay = lay;
- v3d->flag2 = flag2;
- }
-
- BLI_freelistN(&shadows);
-
- /* 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);
- GPU_zenith_update_color(&world->zenr);
- }
+ /* TODO viewport */
}
-/* *********************** customdata **************** */
-CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
+/**
+* Viewport Name
+*/
+static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
{
- CustomDataMask mask = 0;
- const int drawtype = view3d_effective_drawtype(v3d);
+ const char *name = NULL;
- if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL) ||
- ((drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX)))
- {
- mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
+ switch (rv3d->view) {
+ case RV3D_VIEW_FRONT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
+ else name = IFACE_("Front Persp");
+ break;
+ case RV3D_VIEW_BACK:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
+ else name = IFACE_("Back Persp");
+ break;
+ case RV3D_VIEW_TOP:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
+ else name = IFACE_("Top Persp");
+ break;
+ case RV3D_VIEW_BOTTOM:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
+ else name = IFACE_("Bottom Persp");
+ break;
+ case RV3D_VIEW_RIGHT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
+ else name = IFACE_("Right Persp");
+ break;
+ case RV3D_VIEW_LEFT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
+ else name = IFACE_("Left Persp");
+ break;
- if (BKE_scene_use_new_shading_nodes(scene)) {
- if (drawtype == OB_MATERIAL)
- mask |= CD_MASK_ORCO;
- }
- else {
- if ((scene->gm.matmode == GAME_MAT_GLSL && drawtype == OB_TEXTURE) ||
- (drawtype == OB_MATERIAL))
- {
- mask |= CD_MASK_ORCO;
+ default:
+ if (rv3d->persp == RV3D_CAMOB) {
+ if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
+ Camera *cam;
+ cam = v3d->camera->data;
+ if (cam->type == CAM_PERSP) {
+ name = IFACE_("Camera Persp");
+ }
+ else if (cam->type == CAM_ORTHO) {
+ name = IFACE_("Camera Ortho");
+ }
+ else {
+ BLI_assert(cam->type == CAM_PANO);
+ name = IFACE_("Camera Pano");
+ }
+ }
+ else {
+ name = IFACE_("Object as Camera");
+ }
+ }
+ else {
+ name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
}
- }
}
- return mask;
+ return name;
}
-/* goes over all modes and view3d settings */
-CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
+static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
- const Scene *scene = screen->scene;
- CustomDataMask mask = CD_MASK_BAREMESH;
- const ScrArea *sa;
-
- /* check if we need tfaces & mcols due to view mode */
- for (sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_VIEW3D) {
- mask |= ED_view3d_datamask(scene, sa->spacedata.first);
- }
+ RegionView3D *rv3d = ar->regiondata;
+ const char *name = view3d_get_name(v3d, rv3d);
+ /* increase size for unicode languages (Chinese in utf-8...) */
+#ifdef WITH_INTERNATIONAL
+ char tmpstr[96];
+#else
+ char tmpstr[32];
+#endif
+
+ if (v3d->localvd) {
+ BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
+ name = tmpstr;
}
- return mask;
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#else
+ BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#endif
}
/**
- * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
+ * draw info beside axes in bottom left-corner:
+ * framenum, object name, bone name (if available), marker name (if available)
*/
-void ED_view3d_update_viewmat(
- Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
- /* setup window matrices */
- if (winmat)
- copy_m4_m4(rv3d->winmat, winmat);
- else
- view3d_winmatrix_set(ar, v3d, rect);
+static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
+{
+ const int cfra = CFRA;
+ const char *msg_pin = " (Pinned)";
+ const char *msg_sep = " : ";
- /* setup view matrix */
- if (viewmat)
- copy_m4_m4(rv3d->viewmat, viewmat);
- else
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+ const int font_id = BLF_default();
- /* update utility matrices */
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
-
- /* calculate GLSL view dependent values */
+ char info[300];
+ char *s = info;
+ short offset = 1.5f * UI_UNIT_X + rect->xmin;
- /* store window coordinates scaling/offset */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- rctf cameraborder;
- 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;
- }
+ s += sprintf(s, "(%d)", cfra);
- /**
- * 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.
+ /*
+ * 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)
*/
- {
- /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
- * because of float point precision problems at large values [#23908] */
- float v1[3], v2[3];
- float len_px, len_sc;
-
- v1[0] = rv3d->persmat[0][0];
- v1[1] = rv3d->persmat[1][0];
- v1[2] = rv3d->persmat[2][0];
- v2[0] = rv3d->persmat[0][1];
- v2[1] = rv3d->persmat[1][1];
- v2[2] = rv3d->persmat[2][1];
-
- len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
- len_sc = (float)MAX2(ar->winx, ar->winy);
-
- rv3d->pixsize = len_px / len_sc;
- }
-}
+ /* get name of marker on current frame (if available) */
+ const char *markern = BKE_scene_find_marker_name(scene, cfra);
-/**
- * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects
- *
- * \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,
- const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
-{
- RegionView3D *rv3d = ar->regiondata;
- Base *base;
- const bool do_camera_frame = !draw_offscreen;
- const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
- 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 */
- const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
- bool do_composite_xray = false;
- bool xrayclear = true;
-
- if (!draw_offscreen) {
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
- }
+ /* check if there is an object */
+ if (ob) {
+ *s++ = ' ';
+ s += BLI_strcpy_rlen(s, ob->id.name + 2);
- if (rv3d->rflag & RV3D_CLIPPING)
- view3d_draw_clipping(rv3d);
+ /* name(s) to display depends on type of object */
+ if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
- /* set zbuffer after we draw clipping region */
- if (v3d->drawtype > OB_WIRE) {
- v3d->zbuf = true;
- }
- else {
- v3d->zbuf = false;
- }
+ /* show name of active bone too (if possible) */
+ if (arm->edbo) {
+ if (arm->act_edbone) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_edbone->name);
+ }
+ }
+ else if (ob->mode & OB_MODE_POSE) {
+ if (arm->act_bone) {
- /* 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 (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
+ }
}
}
- }
-
- if (v3d->zbuf) {
- glEnable(GL_DEPTH_TEST);
- }
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
+ /* try to display active bone and active shapekey too (if they exist) */
- /* 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) {
- /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
- rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
+ Object *armobj = BKE_object_pose_armature_get(ob);
+ if (armobj && armobj->mode & OB_MODE_POSE) {
+ bArmature *arm = armobj->data;
+ if (arm->act_bone) {
+ if (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
+ }
+ }
+ }
- 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);
- }
- else if (!draw_grids_after) {
- drawfloor(scene, v3d, grid_unit, true);
+ Key *key = BKE_key_from_object(ob);
+ if (key) {
+ KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
+ if (kb) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, kb->name);
+ if (ob->shapeflag & OB_SHAPE_LOCK) {
+ s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
+ }
+ }
+ }
}
- }
- /* important to do before clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame);
+ /* color depends on whether there is a keyframe */
+ if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
+ UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
+ else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ else
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
}
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
+ else {
+ /* no object */
+ if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ else
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
}
- /* draw set first */
- if (scene->set) {
- const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET;
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
- if (v3d->lay & base->lay) {
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(scene, ar, v3d, base, dflag);
-
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(scene, ar, v3d, base, dflag, TH_UNDEFINED);
- }
- }
- }
-
- /* Transp and X-ray afterdraw stuff for sets is done later */
+ if (markern) {
+ s += sprintf(s, " <%s>", markern);
}
+ if (U.uiflag & USER_SHOW_ROTVIEWICON)
+ offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
- 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);
+ BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
+}
- draw_object(scene, ar, v3d, base, 0);
- }
- }
- }
- else {
- unsigned int lay_used = 0;
+/* ******************** view loop ***************** */
- /* then draw not selected and the duplis, but skip editmode object */
- for (base = scene->base.first; base; base = base->next) {
- lay_used |= base->lay;
+/**
+* Information drawn on top of the solid plates and composed data
+*/
+void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
- if (v3d->lay & base->lay) {
+ /* correct projection matrix */
+ ED_region_pixelspace(ar);
- /* 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);
- }
- }
- }
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ rcti rect;
+ ED_region_visible_rect(ar, &rect);
- /* mask out localview */
- v3d->lay_used = lay_used & ((1 << 20) - 1);
+ /* Leave room for previously drawn info. */
+ rect.ymax -= offset;
- /* 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);
- }
- }
- }
+ view3d_draw_border(C, ar);
+ view3d_draw_grease_pencil(C);
+
+ if (U.uiflag & USER_SHOW_ROTVIEWICON) {
+ draw_view_axis(rv3d, &rect);
}
- /* perspective floor goes last to use scene depth and avoid writing to depth buffer */
- if (draw_grids_after) {
- drawfloor(scene, v3d, grid_unit, false);
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
+ ED_scene_draw_fps(scene, &rect);
+ }
+ else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
+ draw_viewport_name(ar, v3d, &rect);
}
- /* must be before xray draw which clears the depth buffer */
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL;
-
- /* must be before xray draw which clears the depth buffer */
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- ED_gpencil_draw_view3d(wm, scene, v3d, ar, true);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if (U.uiflag & USER_DRAWVIEWINFO) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT(sl);
+ draw_selected_name(scene, ob, &rect);
}
+#if 0 /* TODO */
+ if (grid_unit) { /* draw below the viewport name */
+ char numstr[32] = "";
- /* transp and X-ray afterdraw stuff */
- if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ if (v3d->grid != 1.0f) {
+ BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
+ }
- /* always do that here to cleanup depth buffers if none needed */
- if (fx) {
- do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
- GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
+ numstr[0] ? numstr : grid_unit, sizeof(numstr));
}
+#endif
+}
- if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
+static void view3d_draw_view(const bContext *C, ARegion *ar)
+{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
- if (fx && do_composite_xray) {
- GPU_fx_compositor_XRay_resolve(fx);
- }
+ ED_view3d_draw_setup_view(CTX_wm_window(C), &eval_ctx, CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL);
- if (!draw_offscreen) {
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- }
+ /* Only 100% compliant on new spec goes bellow */
+ DRW_draw_view(C);
+}
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
+void view3d_main_region_draw(const bContext *C, ARegion *ar)
+{
+ Scene *scene = CTX_data_scene(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
+ ViewRender *view_render = BKE_viewrender_get(scene, workspace);
+ RenderEngineType *type = RE_engines_find(view_render->engine_id);
- /* important to do after clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
+ /* Provisory Blender Internal drawing */
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
+ view3d_main_region_draw_legacy(C, ar);
+ return;
}
- if (!draw_offscreen) {
- BIF_draw_manipulator(C);
+ if (!rv3d->viewport) {
+ rv3d->viewport = GPU_viewport_create();
}
- /* cleanup */
- if (v3d->zbuf) {
- v3d->zbuf = false;
- glDisable(GL_DEPTH_TEST);
- }
+ GPU_viewport_bind(rv3d->viewport, &ar->winrct);
+ view3d_draw_view(C, ar);
+ GPU_viewport_unbind(rv3d->viewport);
- if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
- GPU_free_images_old();
- }
+ v3d->flag |= V3D_INVALID_BACKBUF;
}
-static void view3d_main_region_setup_view(
- Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
- ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect);
+/* -------------------------------------------------------------------- */
- /* set for opengl */
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
-}
+/** \name Offscreen Drawing
+ * \{ */
-/**
- * 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;
-};
-
-struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
+static void view3d_stereo3d_setup_offscreen(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar,
+ float winmat[4][4], const char *viewname)
{
- 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;
-}
+ /* 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);
-void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat)
-{
- 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;
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
+ }
+ 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);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
+ }
}
-void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
+void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d)
{
- /* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows_world(scene, v3d);
+ RenderEngineType *type = eval_ctx->engine;
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
+ /* shadow buffers, before we setup matrices */
+ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) {
+ VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d);
+ }
+ }
}
/*
@@ -3077,79 +1946,13 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
*/
static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
- if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
- RegionView3D *rv3d = ar->regiondata;
- GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
-
- /* 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);
-
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- }
-
- /* 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();
-
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
+ glClear(GL_DEPTH_BUFFER_BIT);
- GPU_material_unbind(gpumat);
-
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_DEPTH_TEST);
+ if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
+ VP_view3d_draw_background_world(scene, ar->regiondata);
}
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 {
- UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
+ VP_view3d_draw_background_none();
}
}
@@ -3157,24 +1960,20 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
* stuff like shadow buffers
*/
void ED_view3d_draw_offscreen(
- Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer,
+ View3D *v3d, ARegion *ar, int winx, int winy,
float viewmat[4][4], float winmat[4][4],
bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
GPUFX *fx, GPUFXSettings *fx_settings,
GPUOffScreen *ofs)
{
- struct bThemeState theme_state;
- int bwinx, bwiny;
- rcti brect;
bool do_compositing = false;
RegionView3D *rv3d = ar->regiondata;
- glPushMatrix();
-
/* set temporary new size */
- bwinx = ar->winx;
- bwiny = ar->winy;
- brect = ar->winrct;
+ int bwinx = ar->winx;
+ int bwiny = ar->winy;
+ rcti brect = ar->winrct;
ar->winx = winx;
ar->winy = winy;
@@ -3183,6 +1982,7 @@ void ED_view3d_draw_offscreen(
ar->winrct.xmax = winx;
ar->winrct.ymax = winy;
+ struct bThemeState theme_state;
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
@@ -3195,26 +1995,10 @@ void ED_view3d_draw_offscreen(
GPU_free_images_anim();
}
- /* setup view matrices before fx or unbinding the offscreen buffers will cause issues */
- if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
- view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
- else
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
-
- /* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && fx) {
- GPUSSAOSettings *ssao = NULL;
-
- if (v3d->drawtype < OB_SOLID) {
- ssao = v3d->fx_settings.ssao;
- v3d->fx_settings.ssao = NULL;
- }
-
- do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
-
- if (ssao)
- v3d->fx_settings.ssao = ssao;
- }
+ gpuPushProjectionMatrix();
+ gpuLoadIdentity();
+ gpuPushMatrix();
+ gpuLoadIdentity();
/* clear opengl buffers */
if (do_sky) {
@@ -3225,28 +2009,57 @@ void ED_view3d_draw_offscreen(
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
+ if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
+ view3d_stereo3d_setup_offscreen(eval_ctx, scene, v3d, ar, winmat, viewname);
+ else
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
+
/* main drawing call */
- view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+ RenderEngineType *type = eval_ctx->engine;
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
- /* post process */
- if (do_compositing) {
- if (!winmat)
- is_persp = rv3d->is_persp;
- GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
- }
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag && fx) {
+ GPUSSAOSettings *ssao = NULL;
- if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
- /* draw grease-pencil stuff */
- ED_region_pixelspace(ar);
+ if (v3d->drawtype < OB_SOLID) {
+ ssao = v3d->fx_settings.ssao;
+ v3d->fx_settings.ssao = NULL;
+ }
+ do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- ED_gpencil_draw_view3d(NULL, scene, v3d, ar, false);
+ if (ssao)
+ v3d->fx_settings.ssao = ssao;
}
- /* freeing the images again here could be done after the operator runs, leaving for now */
- GPU_free_images_anim();
+ VP_deprecated_view3d_draw_objects(NULL, eval_ctx, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+
+ /* post process */
+ if (do_compositing) {
+ if (!winmat)
+ is_persp = rv3d->is_persp;
+ GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ /* draw grease-pencil stuff */
+ ED_region_pixelspace(ar);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ ED_gpencil_draw_view3d(NULL, scene, scene_layer, v3d, ar, false);
+ }
+
+ /* freeing the images again here could be done after the operator runs, leaving for now */
+ GPU_free_images_anim();
+ }
+ }
+ else {
+ /* XXX, should take depsgraph as arg */
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, scene_layer, false);
+ BLI_assert(depsgraph != NULL);
+ DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine, ar, v3d, ofs);
}
/* restore size */
@@ -3254,7 +2067,8 @@ void ED_view3d_draw_offscreen(
ar->winy = bwiny;
ar->winrct = brect;
- glPopMatrix();
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
UI_Theme_Restore(&theme_state);
@@ -3262,37 +2076,20 @@ void ED_view3d_draw_offscreen(
}
/**
- * Set the correct matrices
- */
-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)
-{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Setup the view matrix. */
- if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
- view3d_stereo3d_setup(scene, v3d, ar, rect);
- }
- else {
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect);
- }
-}
-
-/**
* 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,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer,
+ View3D *v3d, ARegion *ar, int sizex, int sizey,
unsigned int flag, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
/* output vars */
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
- ImBuf *ibuf;
const bool draw_sky = (alpha_mode == R_ADDSKY);
/* view state */
@@ -3315,12 +2112,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
}
}
- ED_view3d_draw_offscreen_init(scene, v3d);
+ ED_view3d_draw_offscreen_init(eval_ctx, scene, scene_layer, v3d);
GPU_offscreen_bind(ofs, true);
/* read in pixels & stamp */
- ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
+ ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
@@ -3357,7 +2154,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
if ((samples && full_samples) == 0) {
/* Single-pass render, common case */
ED_view3d_draw_offscreen(
- scene, v3d, ar, sizex, sizey, NULL, winmat,
+ eval_ctx, scene, scene_layer, v3d, ar, sizex, sizey, NULL, winmat,
draw_background, draw_sky, !is_ortho, viewname,
fx, &fx_settings, ofs);
@@ -3376,25 +2173,23 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
/* 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;
BLI_jitter_init(jit_ofs, samples);
/* first sample buffer, also initializes 'rv3d->persmat' */
ED_view3d_draw_offscreen(
- scene, v3d, ar, sizex, sizey, NULL, winmat,
+ eval_ctx, scene, scene_layer, 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;
+ unsigned i = sizex * sizey * 4;
while (i--) {
accum_buffer[i] = rect_temp[i];
}
/* skip the first sample */
- for (j = 1; j < samples; j++) {
+ for (int j = 1; j < samples; j++) {
copy_m4_m4(winmat_jitter, winmat);
window_translate_m4(
winmat_jitter, rv3d->persmat,
@@ -3402,7 +2197,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
(jit_ofs[j][1] * 2.0f) / sizey);
ED_view3d_draw_offscreen(
- scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
+ eval_ctx, scene, scene_layer, 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);
@@ -3453,7 +2248,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
* \note used by the sequencer
*/
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- Scene *scene, Object *camera, int width, int height,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *scene_layer,
+ Object *camera, int width, int height,
unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
@@ -3471,13 +2267,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
v3d.lay = scene->lay;
v3d.drawtype = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
-
+
if (use_gpencil)
v3d.flag2 |= V3D_SHOW_GPENCIL;
if (use_solid_tex)
v3d.flag2 |= V3D_SOLID_TEX;
-
+
if (draw_background)
v3d.flag3 |= V3D_SHOW_WORLD;
@@ -3507,665 +2303,105 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(
- scene, &v3d, &ar, width, height, flag,
+ eval_ctx, scene, scene_layer, &v3d, &ar, width, height, flag,
draw_background, alpha_mode, samples, full_samples, viewname,
fx, ofs, err_out);
}
+/** \} */
-/**
- * \note The info that this uses is updated in #ED_refresh_viewport_fps,
- * which currently gets called during #SCREEN_OT_animation_step.
- */
-void ED_scene_draw_fps(Scene *scene, const rcti *rect)
-{
- ScreenFrameRateInfo *fpsi = scene->fps_info;
- 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 */
- fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
-#else
- fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
-
- for (i = 0, tot = 0, fps = 0.0f; i < REDRAW_FRAME_AVERAGE; i++) {
- 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
-
- /* is this more than half a frame behind? */
- if (fps + 0.5f < (float)(FPS)) {
- UI_ThemeColor(TH_REDALERT);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
- }
- else {
- UI_ThemeColor(TH_TEXT_HI);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
- }
-
-#ifdef WITH_INTERNATIONAL
- BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
-#else
- BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
-#endif
-}
-static bool view3d_main_region_do_render_draw(Scene *scene)
-{
- RenderEngineType *type = RE_engines_find(scene->r.engine);
+/* -------------------------------------------------------------------- */
- return (type && type->view_update && type->view_draw);
-}
+/** \name Legacy Interface
+ *
+ * This will be removed once the viewport gets replaced
+ * meanwhile it should keep the old viewport working.
+ *
+ * \{ */
-bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *rect)
+void VP_legacy_drawcursor(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
{
- RegionView3D *rv3d = ar->regiondata;
- rctf viewborder;
- bool use_border;
-
- /* test if there is a 3d view rendering */
- if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
- 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);
+ if (is_cursor_visible(scene, sl)) {
+ drawcursor(scene, ar, v3d);
}
- 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;
- }
-
- BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
- BLI_rcti_isect(&ar->winrct, rect, rect);
-
- return true;
}
-static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- bool clip_border, const rcti *border_rect)
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
- RenderEngineType *type;
- GLint scissor[4];
-
- /* create render engine */
- if (!rv3d->render_engine) {
- RenderEngine *engine;
-
- type = RE_engines_find(scene->r.engine);
-
- if (!(type->view_update && type->view_draw))
- return false;
-
- engine = RE_engine_create_ex(type, true);
-
- engine->tile_x = scene->r.tilex;
- engine->tile_y = scene->r.tiley;
-
- type->view_update(engine, C);
-
- rv3d->render_engine = engine;
- }
-
- /* setup view matrices */
- view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL, NULL);
-
- /* background draw */
- ED_region_pixelspace(ar);
-
- if (clip_border) {
- /* for border draw, we only need to clear a subset of the 3d view */
- if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
- glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(border_rect->xmin, border_rect->ymin,
- BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
- }
- else {
- return false;
- }
- }
-
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (v3d->flag & V3D_DISPBGPICS)
- view3d_draw_bgpic_test(scene, ar, v3d, false, true);
- else
- fdrawcheckerboard(0, 0, ar->winx, ar->winy);
-
- /* render result draw */
- type = rv3d->render_engine->type;
- type->view_draw(rv3d->render_engine, C);
-
- if (v3d->flag & V3D_DISPBGPICS)
- view3d_draw_bgpic_test(scene, ar, v3d, true, true);
-
- if (clip_border) {
- /* restore scissor as it was before */
- glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
- }
-
- return true;
+ draw_view_axis(rv3d, rect);
}
-static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
- float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
-
- if (!rv3d->render_engine || !rv3d->render_engine->text[0])
- return;
-
- if (render_border) {
- /* draw darkened background color. no alpha because border render does
- * partial redraw and will not redraw the region behind this info bar */
- float alpha = 1.0f - fill_color[3];
- Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
-
- if (camera) {
- if (camera->flag & CAM_SHOWPASSEPARTOUT) {
- alpha *= (1.0f - camera->passepartalpha);
- }
- }
-
- UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
- mul_v3_fl(fill_color, alpha);
- fill_color[3] = 1.0f;
- }
-
- ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
+ draw_viewport_name(ar, v3d, rect);
}
-static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
+void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect)
{
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- return false;
- }
-
- if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
- return false;
- }
-
- switch (v3d->stereo3d_camera) {
- case STEREO_MONO_ID:
- return false;
- 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;
- }
- return true;
+ draw_selected_name(scene, ob, rect);
}
-/* setup the view and win matrices for the multiview cameras
- *
- * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
- * we have no winmatrix (i.e., projection matrix) defined at that time.
- * Since the camera and the camera shift are needed for the winmat calculation
- * we do a small hack to replace it temporarily so we don't need to change the
- * view3d)main_region_setup_view() code to account for that.
- */
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
{
- bool is_left;
- const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
- const char *viewname;
-
- /* show only left or right camera */
- if (v3d->stereo3d_camera != STEREO_3D_ID)
- v3d->multiview_eye = v3d->stereo3d_camera;
-
- is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
-
- /* update the viewport matrices with the new camera */
- if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- Camera *data;
- float viewmat[4][4];
- float shiftx;
-
- data = (Camera *)v3d->camera->data;
- shiftx = data->shiftx;
-
- BLI_lock_thread(LOCK_VIEW3D);
- data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
-
- BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
-
- data->shiftx = shiftx;
- BLI_unlock_thread(LOCK_VIEW3D);
- }
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- float viewmat[4][4];
- Object *view_ob = v3d->camera;
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
-
- BLI_lock_thread(LOCK_VIEW3D);
- v3d->camera = camera;
-
- BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
-
- v3d->camera = view_ob;
- BLI_unlock_thread(LOCK_VIEW3D);
- }
+ drawgrid(unit, ar, v3d, grid_unit);
}
-static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- float winmat[4][4], const char *viewname)
+void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
{
- /* 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);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
- }
- 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);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
- }
+ drawfloor(scene, v3d, grid_unit, write_depth);
}
-#ifdef WITH_GAMEENGINE
-static void update_lods(Scene *scene, float camera_pos[3])
+void VP_legacy_view3d_main_region_setup_view(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d,
+ ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
- Scene *sce_iter;
- Base *base;
- Object *ob;
-
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
- BKE_object_lod_update(ob, camera_pos);
- }
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
}
-#endif
-static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
- ARegion *ar, const char **grid_unit)
+bool VP_legacy_view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- wmWindow *win = CTX_wm_window(C);
- RegionView3D *rv3d = ar->regiondata;
- unsigned int lay_used = v3d->lay_used;
-
- /* post processing */
- bool do_compositing = false;
-
- /* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows_world(scene, v3d);
-
- /* 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();
- }
-
- /* Setup the view matrix. */
- ED_view3d_draw_setup_view(CTX_wm_window(C), scene, ar, v3d, NULL, NULL, NULL);
-
- rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
-#ifdef WITH_GAMEENGINE
- if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) {
- rv3d->rflag |= RV3D_IS_GAME_ENGINE;
-
- /* Make sure LoDs are up to date */
- update_lods(scene, rv3d->viewinv[3]);
- }
-#endif
-
- /* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
- 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;
- }
-
- do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
- }
-
- /* clear the background */
- view3d_main_region_clear(scene, v3d, ar);
-
- /* enables anti-aliasing for 3D view drawing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glEnable(GL_MULTISAMPLE);
- }
-
- /* main drawing call */
- view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
-
- /* post process */
- if (do_compositing) {
- GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
- }
-
- /* Disable back anti-aliasing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glDisable(GL_MULTISAMPLE);
- }
-
- if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
- /* find header and force tag redraw */
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
- ED_region_tag_redraw(ar_header); /* can be NULL */
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- BDR_drawSketch(C);
- }
-
-#ifdef WITH_INPUT_NDOF
- if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) && (rv3d->persp != RV3D_CAMOB))
- /* TODO: draw something else (but not this) during fly mode */
- draw_rotation_guide(rv3d);
-#endif
+ return view3d_stereo3d_active(win, scene, v3d, rv3d);
}
-static bool is_cursor_visible(Scene *scene)
+void VP_legacy_view3d_stereo3d_setup(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar)
{
- 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);
-
- if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
- if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
- return true;
- }
- }
- }
-
- /* no exception met? then don't draw cursor! */
- return false;
- }
-
- return true;
+ view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, NULL);
}
-static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- const char *grid_unit, bool render_border)
+bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- RegionView3D *rv3d = ar->regiondata;
- rcti rect;
-
- /* local coordinate visible rect inside region, to accomodate overlapping ui */
- ED_region_visible_rect(ar, &rect);
-
- if (rv3d->persp == RV3D_CAMOB) {
- drawviewborder(scene, ar, v3d);
- }
- else if (v3d->flag2 & V3D_RENDER_BORDER) {
- glLineWidth(1.0f);
- setlinestyle(3);
- cpack(0x4040FF);
-
- 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);
-
- setlinestyle(0);
- }
-
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- ED_gpencil_draw_view3d(wm, scene, v3d, ar, false);
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- Object *ob;
-
- /* 3d cursor */
- if (is_cursor_visible(scene)) {
- drawcursor(scene, ar, v3d);
- }
-
- if (U.uiflag & USER_SHOW_ROTVIEWICON)
- draw_view_axis(rv3d, &rect);
- else
- draw_view_icon(rv3d, &rect);
-
- ob = OBACT;
- if (U.uiflag & USER_DRAWVIEWINFO)
- draw_selected_name(scene, ob, &rect);
- }
-
- if (rv3d->render_engine) {
- view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border);
- return;
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
- ED_scene_draw_fps(scene, &rect);
- }
- else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(ar, v3d, &rect);
- }
-
- if (grid_unit) { /* draw below the viewport name */
- char numstr[32] = "";
-
- UI_ThemeColor(TH_TEXT_HI);
- if (v3d->grid != 1.0f) {
- BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
- }
-
- BLF_draw_default_ascii(rect.xmin + U.widget_unit,
- rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
- numstr[0] ? numstr : grid_unit, sizeof(numstr));
- }
- }
+ return use_depth_doit(scene, v3d);
}
-void view3d_main_region_draw(const bContext *C, ARegion *ar)
+void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- const char *grid_unit = NULL;
- rcti border_rect;
- bool render_border, clip_border;
-
- /* 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));
-
- /* draw viewport using opengl */
- 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);
-
-#ifdef DEBUG_DRAW
- bl_debug_draw();
-#endif
- if (G.debug & G_DEBUG_SIMDATA)
- draw_sim_debug_data(scene, v3d, ar);
-
- ED_region_pixelspace(ar);
- }
-
- /* draw viewport using external renderer */
- if (v3d->drawtype == OB_RENDER)
- view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
-
- view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
-
- v3d->flag |= V3D_INVALID_BACKBUF;
-
- 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));
+ drawviewborder(scene, ar, v3d);
}
-#ifdef DEBUG_DRAW
-/* debug drawing */
-#define _DEBUG_DRAW_QUAD_TOT 1024
-#define _DEBUG_DRAW_EDGE_TOT 1024
-static float _bl_debug_draw_quads[_DEBUG_DRAW_QUAD_TOT][4][3];
-static int _bl_debug_draw_quads_tot = 0;
-static float _bl_debug_draw_edges[_DEBUG_DRAW_QUAD_TOT][2][3];
-static int _bl_debug_draw_edges_tot = 0;
-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;
-
-void bl_debug_draw_quad_clear(void)
-{
- _bl_debug_draw_quads_tot = 0;
- _bl_debug_draw_edges_tot = 0;
- _bl_debug_draw_color = 0x00FF0000;
-}
-void bl_debug_color_set(const unsigned int color)
+void VP_drawrenderborder(ARegion *ar, View3D *v3d)
{
- _bl_debug_draw_color = color;
+ drawrenderborder(ar, v3d);
}
-void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3])
+
+void VP_view3d_draw_background_none(void)
{
- if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) {
- printf("%s: max quad count hit %d!", __func__, _bl_debug_draw_quads_tot);
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ view3d_draw_background_gradient();
}
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;
- _bl_debug_draw_quads_color[_bl_debug_draw_quads_tot] = _bl_debug_draw_color;
- _bl_debug_draw_quads_tot++;
+ view3d_draw_background_none();
}
}
-void bl_debug_draw_edge_add(const float v0[3], const float v1[3])
+
+void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d)
{
- if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_EDGE_TOT) {
- printf("%s: max edge count hit %d!", __func__, _bl_debug_draw_edges_tot);
- }
- else {
- float *pt = &_bl_debug_draw_edges[_bl_debug_draw_edges_tot][0][0];
- copy_v3_v3(pt, v0); pt += 3;
- copy_v3_v3(pt, v1); pt += 3;
- _bl_debug_draw_edges_color[_bl_debug_draw_edges_tot] = _bl_debug_draw_color;
- _bl_debug_draw_edges_tot++;
- }
+ view3d_draw_background_world(scene, rv3d);
}
-static void bl_debug_draw(void)
+
+void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
- unsigned int color;
- if (_bl_debug_draw_quads_tot) {
- int i;
- color = _bl_debug_draw_quads_color[0];
- cpack(color);
- for (i = 0; i < _bl_debug_draw_quads_tot; i ++) {
- if (_bl_debug_draw_quads_color[i] != color) {
- color = _bl_debug_draw_quads_color[i];
- cpack(color);
- }
- glBegin(GL_LINE_LOOP);
- 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]);
- glEnd();
- }
- }
- if (_bl_debug_draw_edges_tot) {
- int i;
- color = _bl_debug_draw_edges_color[0];
- cpack(color);
- glBegin(GL_LINES);
- for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
- if (_bl_debug_draw_edges_color[i] != color) {
- color = _bl_debug_draw_edges_color[i];
- cpack(color);
- }
- glVertex3fv(_bl_debug_draw_edges[i][0]);
- glVertex3fv(_bl_debug_draw_edges[i][1]);
- }
- glEnd();
- color = _bl_debug_draw_edges_color[0];
- cpack(color);
- glPointSize(4.0);
- glBegin(GL_POINTS);
- for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
- if (_bl_debug_draw_edges_color[i] != color) {
- color = _bl_debug_draw_edges_color[i];
- cpack(color);
- }
- glVertex3fv(_bl_debug_draw_edges[i][0]);
- glVertex3fv(_bl_debug_draw_edges[i][1]);
- }
- glEnd();
- }
+ view3d_main_region_clear(scene, v3d, ar);
}
-#endif
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
new file mode 100644
index 00000000000..9f1c27a09e7
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -0,0 +1,2186 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_draw_legacy.c
+ * \ingroup spview3d
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_group_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+#include "DNA_brush_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_jitter.h"
+#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
+#include "BLI_threads.h"
+
+#include "BKE_anim.h"
+#include "BKE_camera.h"
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_image.h"
+#include "BKE_key.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_global.h"
+#include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+#include "BKE_unit.h"
+#include "BKE_movieclip.h"
+
+#include "DEG_depsgraph.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+
+#include "BIF_glutil.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLF_api.h"
+#include "BLT_translation.h"
+
+#include "ED_armature.h"
+#include "ED_keyframing.h"
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_space_api.h"
+#include "ED_screen_types.h"
+#include "ED_transform.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+
+#include "GPU_draw.h"
+#include "GPU_framebuffer.h"
+#include "GPU_lamp.h"
+#include "GPU_material.h"
+#include "GPU_compositing.h"
+#include "GPU_extensions.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_select.h"
+#include "GPU_matrix.h"
+
+#include "RE_engine.h"
+
+#include "DRW_engine.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* ********* custom clipping *********** */
+
+static void view3d_draw_clipping(RegionView3D *rv3d)
+{
+ BoundBox *bb = rv3d->clipbb;
+
+ if (bb) {
+ const unsigned int clipping_index[6][4] = {
+ {0, 1, 2, 3},
+ {0, 4, 5, 1},
+ {4, 7, 6, 5},
+ {7, 3, 2, 6},
+ {1, 5, 6, 2},
+ {7, 4, 0, 3}
+ };
+
+ /* fill in zero alpha for rendering & re-projection [#31530] */
+ unsigned char col[4];
+ UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
+ glColor4ubv(col);
+
+ glEnable(GL_BLEND);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, bb->vec);
+ glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisable(GL_BLEND);
+ }
+}
+
+void ED_view3d_clipping_set(RegionView3D *rv3d)
+{
+ double plane[4];
+ const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
+
+ for (unsigned a = 0; a < tot; a++) {
+ copy_v4db_v4fl(plane, rv3d->clip[a]);
+ glClipPlane(GL_CLIP_PLANE0 + a, plane);
+ glEnable(GL_CLIP_PLANE0 + a);
+ }
+}
+
+/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
+void ED_view3d_clipping_disable(void)
+{
+ for (unsigned a = 0; a < 6; a++) {
+ glDisable(GL_CLIP_PLANE0 + a);
+ }
+}
+void ED_view3d_clipping_enable(void)
+{
+ for (unsigned a = 0; a < 6; a++) {
+ glEnable(GL_CLIP_PLANE0 + a);
+ }
+}
+
+static bool view3d_clipping_test(const float co[3], const float clip[6][4])
+{
+ 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)
+ return false;
+
+ return true;
+}
+
+/* for 'local' ED_view3d_clipping_local must run first
+ * then all comparisons can be done in localspace */
+bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
+{
+ return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
+}
+
+/* ********* end custom clipping *********** */
+
+static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
+{
+ BIFIconID icon;
+
+ 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;
+ else return;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
+
+ glDisable(GL_BLEND);
+}
+
+/* *********************** backdraw for selection *************** */
+
+static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ struct Base *base = sl->basact;
+ int multisample_enabled;
+
+ BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
+
+ if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
+ BKE_paint_select_face_test(base->object)))
+ {
+ /* do nothing */
+ }
+ /* texture paint mode sampling */
+ else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
+ (v3d->drawtype > OB_WIRE))
+ {
+ /* do nothing */
+ }
+ else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
+ V3D_IS_ZBUF(v3d))
+ {
+ /* do nothing */
+ }
+ else if (scene->obedit &&
+ V3D_IS_ZBUF(v3d))
+ {
+ /* do nothing */
+ }
+ else {
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
+ return;
+ }
+
+ if (!(v3d->flag & V3D_INVALID_BACKBUF))
+ return;
+
+#if 0
+ if (test) {
+ if (qtest()) {
+ addafterqueue(ar->win, BACKBUFDRAW, 1);
+ return;
+ }
+ }
+#endif
+
+ if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
+
+ /* dithering and AA break color coding, so disable */
+ glDisable(GL_DITHER);
+
+ multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
+ if (multisample_enabled)
+ glDisable(GL_MULTISAMPLE);
+
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ /* 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) {
+ if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
+ GPU_offscreen_height(rv3d->gpuoffscreen) != h)
+ {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+ }
+
+ if (!rv3d->gpuoffscreen) {
+ rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, error);
+
+ if (!rv3d->gpuoffscreen)
+ fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
+ }
+ }
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
+ else
+ glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ else {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_set(rv3d);
+
+ G.f |= G_BACKBUFSEL;
+
+ if (base && ((base->flag & BASE_VISIBLED) != 0))
+ draw_object_backbufsel(eval_ctx, scene, v3d, rv3d, base->object);
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
+ else
+ ar->swap = 0; /* mark invalid backbuf for wm draw */
+
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
+
+ G.f &= ~G_BACKBUFSEL;
+ v3d->zbuf = false;
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_DITHER);
+ if (multisample_enabled)
+ glEnable(GL_MULTISAMPLE);
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_disable();
+}
+
+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) {
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glReadPixels(x, y, w, h, format, type, data);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
+ }
+ else {
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+ }
+}
+
+/* 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);
+}
+
+void ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, ViewContext *vc)
+{
+ if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
+ backdrawview3d(eval_ctx, vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d);
+ }
+}
+
+/**
+ * allow for small values [0.5 - 2.5],
+ * and large values, FLT_MAX by clamping by the area size
+ */
+int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
+{
+ return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+}
+
+/* samples a single pixel (copied from vpaint) */
+unsigned int ED_view3d_backbuf_sample(
+ const EvaluationContext *eval_ctx, ViewContext *vc, int x, int y)
+{
+ if (x >= vc->ar->winx || y >= vc->ar->winy) {
+ return 0;
+ }
+
+ ED_view3d_backbuf_validate(eval_ctx, vc);
+
+ unsigned int col;
+ view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
+ glReadBuffer(GL_BACK);
+
+ if (ENDIAN_ORDER == B_ENDIAN) {
+ BLI_endian_switch_uint32(&col);
+ }
+
+ return GPU_select_to_index(col);
+}
+
+/* reads full rect, converts indices */
+ImBuf *ED_view3d_backbuf_read(
+ const EvaluationContext *eval_ctx, ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
+{
+ /* clip */
+ 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)))
+ {
+ return NULL;
+ }
+
+ ImBuf *ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
+
+ ED_view3d_backbuf_validate(eval_ctx, vc);
+
+ view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
+
+ glReadBuffer(GL_BACK);
+
+ if (ENDIAN_ORDER == B_ENDIAN) {
+ IMB_convert_rgba_to_abgr(ibuf_clip);
+ }
+
+ GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]);
+
+ 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 */
+ const int size[2] = {
+ (xmax - xmin + 1),
+ (ymax - ymin + 1)};
+
+ ImBuf *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;
+ }
+}
+
+/* smart function to sample a rect spiralling outside, nice for backbuf selection */
+unsigned int ED_view3d_backbuf_sample_rect(
+ const EvaluationContext *eval_ctx, ViewContext *vc, const int mval[2], int size,
+ unsigned int min, unsigned int max, float *r_dist)
+{
+ int dirvec[4][2];
+
+ const int amount = (size - 1) / 2;
+
+ const int minx = mval[0] - (amount + 1);
+ const int miny = mval[1] - (amount + 1);
+ ImBuf *buf = ED_view3d_backbuf_read(eval_ctx, vc, minx, miny, minx + size - 1, miny + size - 1);
+ if (!buf) return 0;
+
+ unsigned index = 0;
+ int rc = 0;
+
+ 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;
+
+ const unsigned *bufmin = buf->rect;
+ const unsigned *tbuf = buf->rect;
+ const unsigned *bufmax = buf->rect + size * size;
+ tbuf += amount * size + amount;
+
+ for (int nr = 1; nr <= size; nr++) {
+ for (int a = 0; a < 2; a++) {
+ for (int b = 0; b < nr; b++) {
+ if (*tbuf && *tbuf >= min && *tbuf < max) {
+ /* we got a hit */
+
+ /* get x,y pixel coords from the offset
+ * (manhatten distance in keeping with other screen-based selection) */
+ *r_dist = (float)(
+ abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
+ abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
+
+ /* indices start at 1 here */
+ index = (*tbuf - min) + 1;
+ goto exit;
+ }
+
+ tbuf += (dirvec[rc][0] + dirvec[rc][1]);
+
+ if (tbuf < bufmin || tbuf >= bufmax) {
+ goto exit;
+ }
+ }
+ rc++;
+ rc &= 3;
+ }
+ }
+
+exit:
+ IMB_freeImBuf(buf);
+ return index;
+}
+
+
+/* ************************************************************* */
+
+static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
+{
+ if (BKE_image_is_stereo(ima)) {
+ iuser->flag |= IMA_SHOW_STEREO;
+
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ iuser->multiview_eye = STEREO_LEFT_ID;
+ }
+ else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ /* show only left or right camera */
+ iuser->multiview_eye = v3d->stereo3d_camera;
+ }
+
+ BKE_image_multiview_index(ima, iuser);
+ }
+ else {
+ iuser->flag &= ~IMA_SHOW_STEREO;
+ }
+}
+
+static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
+ const bool do_foreground, const bool do_camera_frame)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0;
+ if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) {
+ return;
+ }
+ Camera *cam = v3d->camera->data;
+
+ for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
+ bgpic->iuser.scene = scene; /* Needed for render results. */
+
+ if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag)
+ continue;
+
+ {
+ float image_aspect[2];
+ float x1, y1, x2, y2, centx, centy;
+
+ void *lock;
+
+ Image *ima = NULL;
+
+ /* disable individual images */
+ if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED))
+ continue;
+
+ ImBuf *ibuf = NULL;
+ ImBuf *freeibuf = NULL;
+ ImBuf *releaseibuf = NULL;
+ if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
+ ima = bgpic->ima;
+ if (ima == NULL)
+ continue;
+ BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0);
+ if (ima->source == IMA_SRC_SEQUENCE && !(bgpic->iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
+ ibuf = NULL; /* frame is out of range, dont show */
+ }
+ else {
+ view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
+ releaseibuf = ibuf;
+ }
+
+ image_aspect[0] = ima->aspx;
+ image_aspect[1] = ima->aspy;
+ }
+ else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
+ /* TODO: skip drawing when out of frame range (as image sequences do above) */
+ MovieClip *clip = NULL;
+
+ if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
+ if (scene->camera)
+ clip = BKE_object_movieclip_get(scene, scene->camera, true);
+ }
+ else {
+ clip = bgpic->clip;
+ }
+
+ if (clip == NULL)
+ continue;
+
+ BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
+ ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+
+ image_aspect[0] = clip->aspx;
+ image_aspect[1] = clip->aspy;
+
+ /* working with ibuf from image and clip has got different workflow now.
+ * ibuf acquired from clip is referenced by cache system and should
+ * be dereferenced after usage. */
+ freeibuf = ibuf;
+ }
+ else {
+ /* perhaps when loading future files... */
+ BLI_assert(0);
+ copy_v2_fl(image_aspect, 1.0f);
+ }
+
+ if (ibuf == NULL)
+ continue;
+
+ if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+
+ continue;
+ }
+
+ if (ibuf->rect == NULL)
+ IMB_rect_from_float(ibuf);
+
+ BLI_assert(rv3d->persp == RV3D_CAMOB);
+ {
+ if (do_camera_frame) {
+ rctf vb;
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
+ x1 = vb.xmin;
+ y1 = vb.ymin;
+ x2 = vb.xmax;
+ y2 = vb.ymax;
+ }
+ else {
+ x1 = ar->winrct.xmin;
+ y1 = ar->winrct.ymin;
+ x2 = ar->winrct.xmax;
+ y2 = ar->winrct.ymax;
+ }
+
+ /* 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_ */
+ {
+ const float max_dim = max_ff(x2 - x1, y2 - y1);
+ const float xof_scale = bgpic->offset[0] * max_dim;
+ const float yof_scale = bgpic->offset[1] * max_dim;
+
+ x1 += xof_scale;
+ y1 += yof_scale;
+ x2 += xof_scale;
+ y2 += yof_scale;
+ }
+
+ centx = (x1 + x2) * 0.5f;
+ centy = (y1 + y2) * 0.5f;
+
+ /* aspect correction */
+ if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
+ /* 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 & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) {
+ /* fit X */
+ const float div = asp_src / asp_dst;
+ x1 = ((x1 - centx) * div) + centx;
+ x2 = ((x2 - centx) * div) + centx;
+ }
+ else {
+ /* fit Y */
+ const float div = asp_dst / asp_src;
+ y1 = ((y1 - centy) * div) + centy;
+ y2 = ((y2 - centy) * div) + centy;
+ }
+ }
+ }
+ }
+
+ /* complete clip? */
+ rctf clip_rect;
+ BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
+ if (bgpic->rotation) {
+ BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
+ }
+
+ if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+
+ continue;
+ }
+
+ float zoomx = (x2 - x1) / ibuf->x;
+ float zoomy = (y2 - y1) / ibuf->y;
+
+ /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
+ if (zoomx < 1.0f || zoomy < 1.0f) {
+ float tzoom = min_ff(zoomx, zoomy);
+ int mip = 0;
+
+ if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
+ IMB_remakemipmap(ibuf, 0);
+ ibuf->userflags &= ~IB_MIPMAP_INVALID;
+ }
+ else if (ibuf->mipmap[0] == NULL)
+ IMB_makemipmap(ibuf, 0);
+
+ while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
+ tzoom *= 2.0f;
+ zoomx *= 2.0f;
+ zoomy *= 2.0f;
+ mip++;
+ }
+ if (mip > 0)
+ ibuf = ibuf->mipmap[mip - 1];
+ }
+
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gpuPushProjectionMatrix();
+ gpuPushMatrix();
+ ED_region_pixelspace(ar);
+
+ gpuTranslate2f(centx, centy);
+ gpuScaleUniform(bgpic->scale);
+ gpuRotate2D(RAD2DEGF(-bgpic->rotation));
+
+ if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) {
+ zoomx *= -1.0f;
+ x1 = x2;
+ }
+ if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) {
+ zoomy *= -1.0f;
+ y1 = y2;
+ }
+
+ float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect,
+ zoomx, zoomy, col);
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(GL_TRUE);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+ }
+ }
+}
+
+void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
+ const bool do_foreground, const bool do_camera_frame)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
+ Camera *cam = v3d->camera->data;
+ if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) {
+ return;
+ }
+ }
+ else {
+ return;
+ }
+
+ /* 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
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE)
+ return;
+#endif
+
+ if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ }
+ }
+ else {
+ view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ }
+}
+
+/* ****************** View3d afterdraw *************** */
+
+typedef struct View3DAfter {
+ struct View3DAfter *next, *prev;
+ struct Base *base;
+ short dflag;
+} View3DAfter;
+
+/* temp storage of Objects that need to be drawn as last */
+void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag)
+{
+ View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
+ BLI_assert((base->flag_legacy & OB_FROMDUPLI) == 0);
+ BLI_addtail(lb, v3da);
+ v3da->base = base;
+ v3da->dflag = dflag;
+}
+
+/* disables write in zbuffer and draws it over */
+static void view3d_draw_transp(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
+{
+ View3DAfter *v3da;
+
+ glDepthMask(GL_FALSE);
+ v3d->transp = true;
+
+ while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+ v3d->transp = false;
+
+ glDepthMask(GL_TRUE);
+
+}
+
+/* clears zbuffer and draws it over */
+static void view3d_draw_xray(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
+{
+ if (*clear && v3d->zbuf) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ *clear = false;
+ }
+
+ v3d->xray = true;
+ View3DAfter *v3da;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+ v3d->xray = false;
+}
+
+
+/* clears zbuffer and draws it over */
+static void view3d_draw_xraytransp(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear)
+{
+ if (clear && v3d->zbuf)
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ v3d->xray = true;
+ v3d->transp = true;
+
+ glDepthMask(GL_FALSE);
+
+ View3DAfter *v3da;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+
+ v3d->transp = false;
+ v3d->xray = false;
+
+ glDepthMask(GL_TRUE);
+}
+
+/* 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(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, 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->object->select_color)) {
+ draw_object_select(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ }
+ MEM_freeN(v3da);
+ }
+ v3d->xray = false;
+}
+
+/* *********************** */
+
+/*
+ * 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
+ */
+
+#if 0
+int dupli_ob_sort(void *arg1, void *arg2)
+{
+ void *p1 = ((DupliObject *)arg1)->ob;
+ void *p2 = ((DupliObject *)arg2)->ob;
+ int val = 0;
+ if (p1 < p2) val = -1;
+ else if (p1 > p2) val = 1;
+ return val;
+}
+#endif
+
+
+static DupliObject *dupli_step(DupliObject *dob)
+{
+ while (dob && dob->no_draw)
+ dob = dob->next;
+ return dob;
+}
+
+static void draw_dupli_objects_color(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base,
+ const short dflag, const int color)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ ListBase *lb;
+ LodLevel *savedlod;
+ Base tbase = {NULL};
+ BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
+ unsigned char color_rgb[3];
+ const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
+ short transflag;
+ char dt;
+ short dtx;
+ DupliApplyData *apply_data;
+
+ if ((base->flag & BASE_VISIBLED) == 0) return;
+ if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
+
+ if (dflag & DRAW_CONSTCOLOR) {
+ BLI_assert(color == TH_UNDEFINED);
+ }
+ else {
+ UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
+ }
+
+ tbase.flag_legacy = OB_FROMDUPLI | base->flag_legacy;
+ tbase.flag = base->flag;
+ lb = object_duplilist(eval_ctx, scene, base->object);
+ // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+
+ apply_data = duplilist_apply(eval_ctx, base->object, scene, lb);
+
+ DupliObject *dob_next = NULL;
+ DupliObject *dob = dupli_step(lb->first);
+ if (dob) dob_next = dupli_step(dob->next);
+
+ for (; dob; dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
+ bool testbb = false;
+
+ tbase.object = dob->ob;
+
+ /* Make sure lod is updated from dupli's position */
+ savedlod = dob->ob->currentlod;
+
+#ifdef WITH_GAMEENGINE
+ if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
+ BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
+ }
+#endif
+
+ /* 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;
+ if (tbase.object->dt != OB_BOUNDBOX)
+ tbase.object->dtx = base->object->dtx;
+
+ /* negative scale flag has to propagate */
+ transflag = tbase.object->transflag;
+
+ if (is_negative_m4(dob->mat))
+ tbase.object->transflag |= OB_NEG_SCALE;
+ else
+ tbase.object->transflag &= ~OB_NEG_SCALE;
+
+ /* should move outside the loop but possible color is set in draw_object still */
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(color_rgb);
+ }
+
+ if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
+ bb = *bb_tmp; /* must make a copy */
+ testbb = true;
+ }
+
+ if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ GPU_begin_dupli_object(dob);
+ draw_object(eval_ctx, scene, sl, ar, v3d, &tbase, dflag_dupli);
+ GPU_end_dupli_object();
+ }
+
+ tbase.object->dt = dt;
+ tbase.object->dtx = dtx;
+ tbase.object->transflag = transflag;
+ tbase.object->currentlod = savedlod;
+ }
+
+ if (apply_data) {
+ duplilist_restore(lb, apply_data);
+ duplilist_free_apply_data(apply_data);
+ }
+
+ free_object_duplilist(lb);
+}
+
+void draw_dupli_objects(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base)
+{
+ /* define the color here so draw_dupli_objects_color can be called
+ * from the set loop */
+
+ int color = (base->flag & BASE_SELECTED) ? TH_SELECT : TH_WIRE;
+ /* debug */
+ if (base->object->dup_group && base->object->dup_group->id.us < 1)
+ color = TH_REDALERT;
+
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, 0, color);
+}
+
+/* XXX warning, not using gpu offscreen here */
+void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
+{
+ /* clamp rect by region */
+ rcti r = {
+ .xmin = 0,
+ .xmax = ar->winx - 1,
+ .ymin = 0,
+ .ymax = ar->winy - 1
+ };
+
+ /* Constrain rect to depth bounds */
+ BLI_rcti_isect(&r, rect, rect);
+
+ /* assign values to compare with the ViewDepths */
+ int x = rect->xmin;
+ int y = rect->ymin;
+
+ int w = BLI_rcti_size_x(rect);
+ int h = BLI_rcti_size_y(rect);
+
+ if (w <= 0 || h <= 0) {
+ if (d->depths)
+ MEM_freeN(d->depths);
+ d->depths = NULL;
+
+ d->damaged = false;
+ }
+ 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;
+
+ if (d->depths)
+ MEM_freeN(d->depths);
+
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
+
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ /* 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);
+ glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+ d->damaged = false;
+ }
+}
+
+/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
+void ED_view3d_depth_update(ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* Create storage for, and, if necessary, copy depth buffer */
+ if (!rv3d->depths) rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
+ if (rv3d->depths) {
+ ViewDepths *d = rv3d->depths;
+ if (d->w != ar->winx ||
+ d->h != ar->winy ||
+ !d->depths)
+ {
+ d->w = ar->winx;
+ d->h = ar->winy;
+ if (d->depths)
+ MEM_freeN(d->depths);
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+ glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+
+ d->damaged = false;
+ }
+ }
+}
+
+/* utility function to find the closest Z value, use for autodepth */
+float view3d_depth_near(ViewDepths *d)
+{
+ /* convert to float for comparisons */
+ const float near = (float)d->depth_range[0];
+ const float far_real = (float)d->depth_range[1];
+ float far = far_real;
+
+ const float *depths = d->depths;
+ float depth = FLT_MAX;
+ int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
+
+ /* far is both the starting 'far' value
+ * and the closest value found. */
+ while (i--) {
+ depth = *depths++;
+ if ((depth < far) && (depth > near)) {
+ far = depth;
+ }
+ }
+
+ return far == far_real ? FLT_MAX : far;
+}
+
+void ED_view3d_draw_depth_gpencil(
+ const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d)
+{
+ bool zbuf = v3d->zbuf;
+
+ /* Setup view matrix. */
+ ED_view3d_draw_setup_view(NULL, eval_ctx, scene, ar, v3d, NULL, NULL, NULL);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ ED_gpencil_draw_view3d(NULL, scene, eval_ctx->scene_layer, v3d, ar, true);
+ }
+
+ v3d->zbuf = zbuf;
+ if (!zbuf) glDisable(GL_DEPTH_TEST);
+}
+
+void ED_view3d_draw_depth_loop(const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d)
+{
+ Base *base;
+ SceneLayer *sl = eval_ctx->scene_layer;
+ /* no need for color when drawing depth buffer */
+ const short dflag_depth = DRAW_CONSTCOLOR;
+
+ /* draw set first */
+ if (scene->set) {
+ Scene *sce_iter;
+ for (SETLOOPER(scene->set, sce_iter, base)) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, 0);
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ }
+ }
+ }
+ }
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ }
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag_depth);
+ }
+ }
+
+ /* this isn't that nice, draw xray objects as if they are normal */
+ if (v3d->afterdraw_transp.first ||
+ v3d->afterdraw_xray.first ||
+ v3d->afterdraw_xraytransp.first)
+ {
+ View3DAfter *v3da;
+ int mask_orig;
+
+ v3d->xray = true;
+
+ /* transp materials can change the depth mask, see #21388 */
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+
+
+ if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
+ glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
+ for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ }
+ glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
+ }
+
+ /* draw 3 passes, transp/xray/xraytransp */
+ v3d->xray = false;
+ v3d->transp = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+ v3d->xray = true;
+ v3d->transp = false;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+ v3d->xray = true;
+ v3d->transp = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+
+ v3d->xray = false;
+ v3d->transp = false;
+
+ glDepthMask(mask_orig);
+ }
+}
+
+void ED_view3d_draw_select_loop(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest)
+{
+ struct bThemeState theme_state;
+
+ short code = 1;
+ const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
+
+ /* Tools may request depth outside of regular drawing code. */
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
+
+ if (vc->obedit && vc->obedit->type == OB_MBALL) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, BASACT(sl), dflag);
+ }
+ else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
+ /* if not drawing sketch, draw bones */
+ if (!BDR_drawSketchNames(vc)) {
+ draw_object(eval_ctx, scene, sl, ar, v3d, BASACT(sl), dflag);
+ }
+ }
+ else {
+ Base *base;
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ if (((base->flag & BASE_SELECTABLED) == 0) ||
+ (use_obedit_skip && (scene->obedit->data == base->object->data)))
+ {
+ base->object->select_color = 0;
+ }
+ else {
+ base->object->select_color = 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(eval_ctx, scene, sl, ar, v3d, base, dflag);
+ }
+ }
+ code++;
+ }
+ }
+ }
+
+ if (use_nearest) {
+ bool xrayclear = true;
+ if (v3d->afterdraw_xray.first) {
+ view3d_draw_xray_select(eval_ctx, scene, sl, ar, v3d, &xrayclear);
+ }
+ }
+ }
+
+ UI_Theme_Restore(&theme_state);
+}
+
+typedef struct View3DShadow {
+ struct View3DShadow *next, *prev;
+ GPULamp *lamp;
+} View3DShadow;
+
+static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
+ Object *ob, Object *par,
+ float obmat[4][4], unsigned int lay,
+ ListBase *shadows)
+{
+ GPULamp *lamp = GPU_lamp_from_blender(scene, ob, par);
+
+ if (lamp) {
+ Lamp *la = (Lamp *)ob->data;
+
+ GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
+ GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
+
+ unsigned int layers = lay & v3d->lay;
+
+ if (layers &&
+ GPU_lamp_has_shadow_buffer(lamp) &&
+ /* keep last, may do string lookup */
+ GPU_lamp_visible(lamp, NULL))
+ {
+ View3DShadow *shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
+ shadow->lamp = lamp;
+ BLI_addtail(shadows, shadow);
+ }
+ }
+}
+
+static void gpu_update_lamps_shadows_world(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
+{
+ ListBase shadows;
+ Scene *sce_iter;
+ Base *base;
+ World *world = scene->world;
+
+ BLI_listbase_clear(&shadows);
+
+ /* update lamp transform and gather shadow lamps */
+ for (SETLOOPER(scene, sce_iter, base)) {
+ Object *ob = base->object;
+
+ if (ob->type == OB_LAMP)
+ gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows);
+
+ if (ob->transflag & OB_DUPLI) {
+ DupliObject *dob;
+ ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
+
+ for (dob = lb->first; dob; dob = dob->next)
+ if (dob->ob->type == OB_LAMP)
+ gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows);
+
+ free_object_duplilist(lb);
+ }
+ }
+
+ /* render shadows after updating all lamps, nested object_duplilist
+ * don't work correct since it's replacing object matrices */
+ for (View3DShadow *shadow = shadows.first; shadow; shadow = shadow->next) {
+ /* this needs to be done better .. */
+ float viewmat[4][4], winmat[4][4];
+ ARegion ar = {NULL};
+ RegionView3D rv3d = {{{0}}};
+
+ int drawtype = v3d->drawtype;
+ int lay = v3d->lay;
+ int flag2 = v3d->flag2;
+
+ v3d->drawtype = OB_SOLID;
+ v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
+ v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
+
+ int winsize;
+ GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
+
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+ copy_m4_m4(rv3d.winmat, winmat);
+ copy_m4_m4(rv3d.viewmat, viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
+ ED_view3d_draw_offscreen(
+ eval_ctx, scene, eval_ctx->scene_layer, v3d, &ar, winsize, winsize, viewmat, winmat,
+ false, false, true,
+ NULL, NULL, NULL, NULL);
+ GPU_lamp_shadow_buffer_unbind(shadow->lamp);
+
+ v3d->drawtype = drawtype;
+ v3d->lay = lay;
+ v3d->flag2 = flag2;
+ }
+
+ BLI_freelistN(&shadows);
+
+ /* 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);
+ GPU_zenith_update_color(&world->zenr);
+ }
+}
+
+/* *********************** customdata **************** */
+
+CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
+{
+ CustomDataMask mask = 0;
+ const int drawtype = view3d_effective_drawtype(v3d);
+
+ if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL) ||
+ ((drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX)))
+ {
+ mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
+
+ if (BKE_scene_use_new_shading_nodes(scene)) {
+ if (drawtype == OB_MATERIAL)
+ mask |= CD_MASK_ORCO;
+ }
+ else {
+ if ((scene->gm.matmode == GAME_MAT_GLSL && drawtype == OB_TEXTURE) ||
+ (drawtype == OB_MATERIAL))
+ {
+ mask |= CD_MASK_ORCO;
+ }
+ }
+ }
+
+ return mask;
+}
+
+/* goes over all modes and view3d settings */
+CustomDataMask ED_view3d_screen_datamask(const Scene *scene, const bScreen *screen)
+{
+ CustomDataMask mask = CD_MASK_BAREMESH;
+
+ /* check if we need tfaces & mcols due to view mode */
+ for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ mask |= ED_view3d_datamask(scene, sa->spacedata.first);
+ }
+ }
+
+ return mask;
+}
+
+/**
+ * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects
+ *
+ * \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,
+ const EvaluationContext *eval_ctx,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
+{
+ SceneLayer *scene_layer = C ? CTX_data_scene_layer(C) : BKE_scene_layer_from_scene_get(scene);
+ RegionView3D *rv3d = ar->regiondata;
+ Base *base;
+ const bool do_camera_frame = !draw_offscreen;
+ const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
+ 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 */
+ const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
+ bool do_composite_xray = false;
+ bool xrayclear = true;
+
+ 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 */
+ v3d->zbuf = VP_legacy_use_depth(scene, v3d);
+
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ /* 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) {
+ /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
+ rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
+
+ if (!draw_floor) {
+ ED_region_pixelspace(ar);
+ *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
+ VP_legacy_drawgrid(&scene->unit, ar, v3d, grid_unit);
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ }
+ else if (!draw_grids_after) {
+ VP_legacy_drawfloor(scene, v3d, grid_unit, true);
+ }
+ }
+
+ /* 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) {
+ const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET;
+ Scene *sce_iter;
+ for (SETLOOPER(scene->set, sce_iter, base)) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
+ draw_object(eval_ctx, scene, scene_layer, ar, v3d, base, dflag);
+
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(eval_ctx, scene, scene_layer, ar, v3d, base, dflag, TH_UNDEFINED);
+ }
+ }
+ }
+
+ /* Transp and X-ray afterdraw stuff for sets is done later */
+ }
+
+ if (draw_offscreen) {
+ for (base = scene_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(eval_ctx, scene, scene_layer, ar, v3d, base);
+ }
+
+ draw_object(eval_ctx, scene, scene_layer, ar, v3d, base, 0);
+ }
+ }
+ }
+ else {
+ unsigned int lay_used = 0;
+
+ /* then draw not selected and the duplis, but skip editmode object */
+ for (base = scene_layer->object_bases.first; base; base = base->next) {
+ lay_used |= base->lay;
+
+ if ((base->flag & BASE_VISIBLED) != 0) {
+
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(eval_ctx, scene, scene_layer, ar, v3d, base);
+ }
+ if ((base->flag & BASE_SELECTED) == 0) {
+ if (base->object != scene->obedit)
+ draw_object(eval_ctx, scene, scene_layer, ar, v3d, base, 0);
+ }
+ }
+ }
+
+ /* mask out localview */
+ v3d->lay_used = lay_used & ((1 << 20) - 1);
+
+ /* draw selected and editmode */
+ for (base = scene_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) {
+ draw_object(eval_ctx, scene, scene_layer, ar, v3d, base, 0);
+ }
+ }
+ }
+ }
+
+ /* perspective floor goes last to use scene depth and avoid writing to depth buffer */
+ if (draw_grids_after) {
+ VP_legacy_drawfloor(scene, v3d, grid_unit, false);
+ }
+
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL;
+
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ ED_gpencil_draw_view3d(wm, scene, scene_layer, v3d, ar, true);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+
+ /* transp and X-ray afterdraw stuff */
+ if (v3d->afterdraw_transp.first) view3d_draw_transp(eval_ctx, scene, scene_layer, ar, v3d);
+
+ /* always do that here to cleanup depth buffers if none needed */
+ if (fx) {
+ do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
+ GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
+ }
+
+ if (v3d->afterdraw_xray.first) view3d_draw_xray(eval_ctx, scene, scene_layer, ar, v3d, &xrayclear);
+ if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(eval_ctx, scene, scene_layer, ar, v3d, xrayclear);
+
+ if (fx && do_composite_xray) {
+ GPU_fx_compositor_XRay_resolve(fx);
+ }
+
+ 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);
+ }
+
+ /* cleanup */
+ if (v3d->zbuf) {
+ v3d->zbuf = false;
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ GPU_free_images_old();
+ }
+}
+
+/**
+ * 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;
+};
+
+struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
+{
+ 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;
+}
+
+void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
+{
+ struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
+ 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;
+}
+
+/**
+ * \note The info that this uses is updated in #ED_refresh_viewport_fps,
+ * which currently gets called during #SCREEN_OT_animation_step.
+ */
+void ED_scene_draw_fps(Scene *scene, const rcti *rect)
+{
+ ScreenFrameRateInfo *fpsi = scene->fps_info;
+ char printable[16];
+
+ if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime)
+ return;
+
+ printable[0] = '\0';
+
+#if 0
+ /* this is too simple, better do an average */
+ fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
+#else
+ fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
+
+ float fps = 0.0f;
+ int tot = 0;
+ for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) {
+ 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
+
+ const int font_id = BLF_default();
+
+ /* is this more than half a frame behind? */
+ if (fps + 0.5f < (float)(FPS)) {
+ UI_FontThemeColor(font_id, TH_REDALERT);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
+ }
+ else {
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
+ }
+
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#else
+ BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#endif
+}
+
+static bool view3d_main_region_do_render_draw(const Scene *scene)
+{
+ RenderEngineType *type = RE_engines_find(scene->view_render.engine_id);
+ return (type && type->view_update && type->render_to_view);
+}
+
+bool ED_view3d_calc_render_border(const Scene *scene, View3D *v3d, ARegion *ar, rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ bool use_border;
+
+ /* test if there is a 3d view rendering */
+ if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
+ 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) {
+ rctf viewborder;
+ 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;
+ }
+
+ BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
+ BLI_rcti_isect(&ar->winrct, rect, rect);
+
+ return true;
+}
+
+/**
+ * IMPORTANT: this is deprecated, any changes made in this function should
+ * be mirrored in view3d_draw_render_draw() in view3d_draw.c
+ */
+static bool view3d_main_region_draw_engine(
+ const bContext *C, const EvaluationContext *eval_ctx, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ bool clip_border, const rcti *border_rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ RenderEngineType *type;
+ GLint scissor[4];
+
+
+ /* create render engine */
+ if (!rv3d->render_engine) {
+ RenderEngine *engine;
+ type = RE_engines_find(scene->view_render.engine_id);
+
+ if (!(type->view_update && type->render_to_view))
+ return false;
+
+ engine = RE_engine_create_ex(type, true);
+
+ engine->tile_x = scene->r.tilex;
+ engine->tile_y = scene->r.tiley;
+
+ type->view_update(engine, C);
+
+ rv3d->render_engine = engine;
+ }
+
+ /* setup view matrices */
+ VP_legacy_view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, NULL, NULL);
+
+ /* background draw */
+ ED_region_pixelspace(ar);
+
+ if (clip_border) {
+ /* for border draw, we only need to clear a subset of the 3d view */
+ if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
+ glScissor(border_rect->xmin, border_rect->ymin,
+ BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
+ }
+ else {
+ return false;
+ }
+ }
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ bool show_image = false;
+ {
+ Camera *cam = ED_view3d_camera_data_get(v3d, rv3d);
+ if (cam->flag & CAM_SHOW_BG_IMAGE) {
+ show_image = true;
+ view3d_draw_bgpic_test(scene, ar, v3d, false, true);
+ }
+ else {
+ imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy);
+ }
+ }
+
+ if (show_image) {
+ view3d_draw_bgpic_test(scene, ar, v3d, false, true);
+ }
+ else {
+ imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy);
+ }
+
+ /* render result draw */
+ type = rv3d->render_engine->type;
+ type->render_to_view(rv3d->render_engine, C);
+
+ if (show_image) {
+ view3d_draw_bgpic_test(scene, ar, v3d, true, true);
+ }
+
+ if (clip_border) {
+ /* restore scissor as it was before */
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ }
+
+ return true;
+}
+
+static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
+{
+ float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
+
+ if (!rv3d->render_engine || !rv3d->render_engine->text[0])
+ return;
+
+ if (render_border) {
+ /* draw darkened background color. no alpha because border render does
+ * partial redraw and will not redraw the region behind this info bar */
+ float alpha = 1.0f - fill_color[3];
+ Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
+
+ if (camera) {
+ if (camera->flag & CAM_SHOWPASSEPARTOUT) {
+ alpha *= (1.0f - camera->passepartalpha);
+ }
+ }
+
+ UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
+ mul_v3_fl(fill_color, alpha);
+ fill_color[3] = 1.0f;
+ }
+
+ ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
+}
+
+#ifdef WITH_GAMEENGINE
+static void update_lods(Scene *scene, float camera_pos[3])
+{
+ Scene *sce_iter;
+ Base *base;
+
+ for (SETLOOPER(scene, sce_iter, base)) {
+ Object *ob = base->object;
+ BKE_object_lod_update(ob, camera_pos);
+ }
+}
+#endif
+
+static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d,
+ ARegion *ar, const char **grid_unit)
+{
+ wmWindow *win = CTX_wm_window(C);
+ EvaluationContext eval_ctx;
+ RegionView3D *rv3d = ar->regiondata;
+ unsigned int lay_used = v3d->lay_used;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ /* post processing */
+ bool do_compositing = false;
+
+ /* shadow buffers, before we setup matrices */
+ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype))
+ gpu_update_lamps_shadows_world(&eval_ctx, scene, v3d);
+
+ /* 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();
+ }
+
+ /* setup the view matrix */
+ if (VP_legacy_view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ VP_legacy_view3d_stereo3d_setup(&eval_ctx, scene, v3d, ar);
+ }
+ else {
+ VP_legacy_view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, NULL, NULL);
+ }
+
+ rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
+#ifdef WITH_GAMEENGINE
+ if (STREQ(scene->view_render.engine_id, RE_engine_id_BLENDER_GAME)) {
+ rv3d->rflag |= RV3D_IS_GAME_ENGINE;
+
+ /* Make sure LoDs are up to date */
+ update_lods(scene, rv3d->viewinv[3]);
+ }
+#endif
+
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
+ BKE_screen_gpu_fx_validate(&v3d->fx_settings);
+ GPUFXSettings 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;
+ }
+
+ do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
+ }
+
+ /* enables anti-aliasing for 3D view drawing */
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ glEnable(GL_MULTISAMPLE);
+ }
+
+ /* main drawing call */
+ view3d_draw_objects(C, &eval_ctx, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+
+ /* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
+ /* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
+ * later become _IN_SCENE (and draw _3D separate) */
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
+
+ /* post process */
+ if (do_compositing) {
+ GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
+ }
+
+ /* Disable back anti-aliasing */
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ glDisable(GL_MULTISAMPLE);
+ }
+
+ if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
+ /* find header and force tag redraw */
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+ ED_region_tag_redraw(ar_header); /* can be NULL */
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ BDR_drawSketch(C);
+ }
+}
+
+static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ const char *grid_unit, bool render_border)
+{
+ SceneLayer *scene_layer = CTX_data_scene_layer(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RegionView3D *rv3d = ar->regiondata;
+ rcti rect;
+
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ ED_region_visible_rect(ar, &rect);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ VP_drawviewborder(scene, ar, v3d);
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ VP_drawrenderborder(ar, v3d);
+ }
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ ED_gpencil_draw_view3d(wm, scene, scene_layer, v3d, ar, false);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ VP_legacy_drawcursor(scene, scene_layer, ar, v3d); /* 3D cursor */
+
+ if (U.uiflag & USER_SHOW_ROTVIEWICON)
+ VP_legacy_draw_view_axis(rv3d, &rect);
+ else
+ draw_view_icon(rv3d, &rect);
+
+ if (U.uiflag & USER_DRAWVIEWINFO) {
+ Object *ob = OBACT(scene_layer);
+ VP_legacy_draw_selected_name(scene, ob, &rect);
+ }
+ }
+
+ if (rv3d->render_engine) {
+ view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border);
+ return;
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
+ ED_scene_draw_fps(scene, &rect);
+ }
+ else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
+ VP_legacy_draw_viewport_name(ar, v3d, &rect);
+ }
+
+ if (grid_unit) { /* draw below the viewport name */
+ char numstr[32] = "";
+
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ if (v3d->grid != 1.0f) {
+ BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
+ }
+
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
+ numstr[0] ? numstr : grid_unit, sizeof(numstr));
+ }
+ }
+}
+
+void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
+{
+ EvaluationContext eval_ctx;
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ const char *grid_unit = NULL;
+ rcti border_rect;
+
+ /* if we only redraw render border area, skip opengl draw and also
+ * don't do scissor because it's already set */
+ bool render_border = ED_view3d_calc_render_border(scene, v3d, ar, &border_rect);
+ bool clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect));
+
+ gpuPushProjectionMatrix();
+ gpuLoadIdentityProjectionMatrix();
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ /* draw viewport using opengl */
+ if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) {
+ VP_view3d_main_region_clear(scene, v3d, ar); /* background */
+ view3d_main_region_draw_objects(C, scene, sl, v3d, ar, &grid_unit);
+
+ if (G.debug & G_DEBUG_SIMDATA)
+ draw_sim_debug_data(scene, v3d, ar);
+
+ glDisable(GL_DEPTH_TEST);
+ ED_region_pixelspace(ar);
+ }
+
+ /* draw viewport using external renderer */
+ if (v3d->drawtype == OB_RENDER) {
+ view3d_main_region_draw_engine(C, &eval_ctx, scene, ar, v3d, clip_border, &border_rect);
+ }
+
+ VP_legacy_view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, NULL, NULL);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ ED_region_pixelspace(ar);
+
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
+ view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
+
+ 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));
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Deprecated Interface
+ *
+ * New viewport sometimes has a check for new/old viewport code.
+ * Use these functions so new viewport can *optionally* call.
+ *
+ * \{ */
+
+
+void VP_deprecated_view3d_draw_objects(
+ const bContext *C,
+ const EvaluationContext *eval_ctx,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
+{
+ view3d_draw_objects(C, eval_ctx, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen, fx);
+}
+
+void VP_deprecated_gpu_update_lamps_shadows_world(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
+{
+ gpu_update_lamps_shadows_world(eval_ctx, scene, v3d);
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 5203e0617ee..dc6d6382d37 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -34,6 +34,7 @@
#include <float.h>
#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -51,6 +52,7 @@
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_font.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -58,11 +60,10 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_action.h"
-#include "BKE_depsgraph.h" /* for ED_view3d_camera_lock_sync */
+#include "DEG_depsgraph.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -79,6 +80,8 @@
#include "ED_gpencil.h"
#include "ED_view3d.h"
+#include "DEG_depsgraph_query.h"
+
#include "UI_resources.h"
#include "PIL_time.h" /* smoothview */
@@ -163,7 +166,7 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
ob_update = v3d->camera;
while (ob_update) {
- DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob_update->id, OB_RECALC_OB);
WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
ob_update = ob_update->parent;
}
@@ -175,7 +178,7 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
- DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
+ DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
}
@@ -621,7 +624,8 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
bool is_set = false;
Scene *scene = CTX_data_scene(C);
- Object *ob_act = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob_act = OBACT(sl);
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
@@ -658,14 +662,13 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
/* object mode use boundbox centers */
- View3D *v3d = CTX_wm_view3d(C);
Base *base;
unsigned int tot = 0;
float select_center[3];
zero_v3(select_center);
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
+ for (base = FIRSTBASE(sl); base; base = base->next) {
+ if (TESTBASE(base)) {
/* use the boundbox if we can */
Object *ob = base->object;
@@ -741,14 +744,18 @@ static void viewops_data_create_ex(
/* we need the depth info before changing any viewport options */
if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
+ EvaluationContext eval_ctx;
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
float fallback_depth_pt[3];
+ CTX_data_eval_ctx(C, &eval_ctx);
+
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
vod->use_dyn_ofs = ED_view3d_autodist(
- vod->scene, vod->ar, vod->v3d,
+ &eval_ctx, graph, vod->ar, vod->v3d,
event->mval, vod->dyn_ofs, true, fallback_depth_pt);
}
else {
@@ -866,8 +873,9 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
static void viewops_data_free(bContext *C, wmOperator *op)
{
ARegion *ar;
+#if 0
Paint *p = BKE_paint_get_active_from_context(C);
-
+#endif
if (op->customdata) {
ViewOpsData *vod = op->customdata;
ar = vod->ar;
@@ -883,7 +891,9 @@ static void viewops_data_free(bContext *C, wmOperator *op)
ar = CTX_wm_region(C);
}
+#if 0
if (p && (p->flags & PAINT_FAST_NAVIGATE))
+#endif
ED_region_tag_redraw(ar);
}
/** \} */
@@ -2980,6 +2990,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base;
float *curs;
const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
@@ -3003,8 +3014,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
INIT_MINMAX(min, max);
}
- for (base = scene->base.first; base; base = base->next) {
- if (BASE_VISIBLE(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (BASE_VISIBLE(base)) {
changed = true;
if (skip_camera && base->object == v3d->camera) {
@@ -3064,9 +3075,12 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
- Object *ob = OBACT;
+ const bool is_face_map = ((is_gp_edit == false) && ar->manipulator_map &&
+ WM_manipulatormap_is_any_selected(ar->manipulator_map));
+ Object *ob = OBACT(sl);
Object *obedit = CTX_data_edit_object(C);
float min[3], max[3];
bool ok = false, ok_dist = true;
@@ -3077,8 +3091,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
INIT_MINMAX(min, max);
-
- if (is_gp_edit) {
+ if (is_gp_edit || is_face_map) {
ob = NULL;
}
@@ -3086,8 +3099,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
/* hard-coded exception, we look for the one selected armature */
/* this is weak code this way, we should make a generic active/selection callback interface once... */
Base *base;
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (TESTBASELIB(base)) {
if (base->object->type == OB_ARMATURE)
if (base->object->mode & OB_MODE_POSE)
break;
@@ -3110,6 +3123,9 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
+ else if (is_face_map) {
+ ok = WM_manipulatormap_minmax(ar->manipulator_map, true, true, min, max);
+ }
else if (obedit) {
ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */
}
@@ -3120,7 +3136,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ok = paintface_minmax(ob, min, max);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
- ok = PE_minmax(scene, min, max);
+ ok = PE_minmax(scene, sl, min, max);
}
else if (ob &&
(ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
@@ -3132,8 +3148,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
else {
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
+ for (base = FIRSTBASE(sl); base; base = base->next) {
+ if (TESTBASE(base)) {
if (skip_camera && base->object == v3d->camera) {
continue;
@@ -3310,18 +3326,21 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
if (rv3d) {
+ EvaluationContext eval_ctx;
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
float new_ofs[3];
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
ED_view3d_smooth_view_force_finish(C, v3d, ar);
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, NULL)) {
+ if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, event->mval, new_ofs, false, NULL)) {
/* pass */
}
else {
@@ -3576,10 +3595,10 @@ void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
/* Zooms in on a border drawn by the user */
@@ -3592,13 +3611,14 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
float new_ofs[3];
/* ZBuffer depth vars */
- bglMats mats;
float depth_close = FLT_MAX;
- double cent[2], p[3];
+ float p[3];
/* note; otherwise opengl won't work */
view3d_operator_needs_opengl(C);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* get border select values using rna */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -3608,8 +3628,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
/* Get Z Depths, needed for perspective, nice for ortho */
- bgl_get_mats(&mats);
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(&eval_ctx, CTX_data_depsgraph(C), ar, v3d, true);
{
/* avoid allocating the whole depth buffer */
@@ -3624,11 +3643,11 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(depth_temp.depths);
}
- cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
- cent[1] = (((double)rect.ymin) + ((double)rect.ymax)) / 2;
+ float centx = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
+ float centy = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
if (rv3d->is_persp) {
- double p_corner[3];
+ float p_corner[3];
/* no depths to use, we cant do anything! */
if (depth_close == FLT_MAX) {
@@ -3636,23 +3655,14 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* convert border to 3d coordinates */
- if ((!gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p[0], &p[1], &p[2])) ||
- (!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p_corner[0], &p_corner[1], &p_corner[2])))
+ if ((!ED_view3d_unproject(ar, centx, centy, depth_close, p)) ||
+ (!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner)))
{
return OPERATOR_CANCELLED;
}
- dvec[0] = p[0] - p_corner[0];
- dvec[1] = p[1] - p_corner[1];
- dvec[2] = p[2] - p_corner[2];
-
- new_ofs[0] = -p[0];
- new_ofs[1] = -p[1];
- new_ofs[2] = -p[2];
+ sub_v3_v3v3(dvec, p, p_corner);
+ negate_v3_v3(new_ofs, p);
new_dist = len_v3(dvec);
@@ -3667,13 +3677,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_dist = rv3d->dist;
/* convert the drawn rectangle into 3d space */
- if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p[0], &p[1], &p[2]))
- {
- new_ofs[0] = -p[0];
- new_ofs[1] = -p[1];
- new_ofs[2] = -p[2];
+ if (depth_close != FLT_MAX && ED_view3d_unproject(ar, centx, centy, depth_close, p)) {
+ negate_v3_v3(new_ofs, p);
}
else {
float mval_f[2];
@@ -3910,6 +3915,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
ARegion *ar;
RegionView3D *rv3d;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *scene_layer = CTX_data_scene_layer(C);
static int perspo = RV3D_PERSP;
int viewnum, nextperspo;
bool align_active;
@@ -3944,7 +3950,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
/* lastview - */
if (rv3d->persp != RV3D_CAMOB) {
- Object *ob = OBACT;
+ Object *ob = OBACT(scene_layer);
if (!rv3d->smooth_timer) {
/* store settings of current view before allowing overwriting with camera view
@@ -3979,7 +3985,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
v3d->camera = ob;
if (v3d->camera == NULL)
- v3d->camera = BKE_scene_camera_find(scene);
+ v3d->camera = BKE_scene_layer_camera_find(scene_layer);
/* couldnt find any useful camera, bail out */
if (v3d->camera == NULL)
@@ -4511,11 +4517,11 @@ void VIEW3D_OT_navigate(wmOperatorType *ot)
/* ******************** add background image operator **************** */
-static BGpic *background_image_add(bContext *C)
+static CameraBGImage *background_image_add(bContext *C)
{
- View3D *v3d = CTX_wm_view3d(C);
+ Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
- return ED_view3D_background_image_new(v3d);
+ return BKE_camera_background_image_new(cam);
}
static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -4527,9 +4533,9 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- View3D *v3d = CTX_wm_view3d(C);
+ Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
Image *ima;
- BGpic *bgpic;
+ CameraBGImage *bgpic;
ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
/* may be NULL, continue anyway */
@@ -4537,10 +4543,10 @@ static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEven
bgpic = background_image_add(C);
bgpic->ima = ima;
- v3d->flag |= V3D_DISPBGPICS;
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
-
+ cam->flag |= CAM_SHOW_BG_IMAGE;
+
+ WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
+
return OPERATOR_FINISHED;
}
@@ -4556,7 +4562,7 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot)
/* api callbacks */
ot->invoke = background_image_add_invoke;
ot->exec = background_image_add_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_camera;
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -4572,21 +4578,22 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot)
/* ***** remove image operator ******* */
static int background_image_remove_exec(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
+ Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
const int index = RNA_int_get(op->ptr, "index");
- BGpic *bgpic_rem = BLI_findlink(&v3d->bgpicbase, index);
+ CameraBGImage *bgpic_rem = BLI_findlink(&cam->bg_images, index);
if (bgpic_rem) {
- if (bgpic_rem->source == V3D_BGPIC_IMAGE) {
+ if (bgpic_rem->source == CAM_BGIMG_SOURCE_IMAGE) {
id_us_min((ID *)bgpic_rem->ima);
}
- else if (bgpic_rem->source == V3D_BGPIC_MOVIE) {
+ else if (bgpic_rem->source == CAM_BGIMG_SOURCE_MOVIE) {
id_us_min((ID *)bgpic_rem->clip);
}
- ED_view3D_background_image_remove(v3d, bgpic_rem);
+ BKE_camera_background_image_remove(cam, bgpic_rem);
+
+ WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
return OPERATOR_FINISHED;
}
else {
@@ -4604,7 +4611,7 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = background_image_remove_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_camera;
/* flags */
ot->flag = 0;
@@ -4638,9 +4645,8 @@ void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
static int view3d_clipping_exec(bContext *C, wmOperator *op)
{
+ ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- ViewContext vc;
- bglMats mats;
rcti rect;
WM_operator_properties_border_to_rcti(op, &rect);
@@ -4648,12 +4654,8 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
rv3d->rflag |= RV3D_CLIPPING;
rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- view3d_set_viewcontext(C, &vc);
- view3d_get_transformation(vc.ar, vc.rv3d, NULL, &mats); /* NULL because we don't want it in object space */
- ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, &mats, &rect);
+ /* NULL object because we don't want it in object space */
+ ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
return OPERATOR_FINISHED;
}
@@ -4705,7 +4707,6 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* note: cannot use event->mval here (called by object_add() */
void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
{
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = ar->regiondata;
@@ -4727,9 +4728,15 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
+ EvaluationContext eval_ctx;
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, NULL))
+ if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, mval, fp, true, NULL)) {
depth_used = true;
+ }
}
if (depth_used == false) {
@@ -4808,45 +4815,6 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
-
-static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- View3D *v3d = CTX_wm_view3d(C);
-
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
- if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
-
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- if (BIF_do_manipulator(C, event, op) == 0)
- return OPERATOR_PASS_THROUGH;
-
- return OPERATOR_FINISHED;
-}
-
-void VIEW3D_OT_manipulator(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "3D Manipulator";
- ot->description = "Manipulate selected item by axis";
- ot->idname = "VIEW3D_OT_manipulator";
-
- /* api callbacks */
- ot->invoke = manipulator_invoke;
-
- ot->poll = ED_operator_view3d_active;
-
- /* properties to pass to transform */
- Transform_Properties(ot, P_CONSTRAINT);
-
- prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
- "two axes that have not been clicked (translate/scale only)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
-}
-
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
@@ -4950,22 +4918,17 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
* \param fallback_depth_pt: Use this points depth when no depth can be found.
*/
bool ED_view3d_autodist(
- Scene *scene, ARegion *ar, View3D *v3d,
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph, ARegion *ar, View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3])
{
- bglMats mats; /* ZBuffer depth vars */
float depth_close;
- double cent[2], p[3];
int margin_arr[] = {0, 2, 4};
int i;
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
-
- /* call after in case settings have been modified since last drawing, see: T47089 */
- bgl_get_mats(&mats);
+ ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, alphaoverride);
/* Attempt with low margin's first */
i = 0;
@@ -4975,15 +4938,10 @@ bool ED_view3d_autodist(
} while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
if (depth_ok) {
- cent[0] = (double)mval[0] + 0.5;
- cent[1] = (double)mval[1] + 0.5;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
- if (gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
- {
- mouse_worldloc[0] = (float)p[0];
- mouse_worldloc[1] = (float)p[1];
- mouse_worldloc[2] = (float)p[2];
+ if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc)) {
return true;
}
}
@@ -4997,16 +4955,21 @@ bool ED_view3d_autodist(
}
}
-void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
+void ED_view3d_autodist_init(
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d, int mode)
{
/* Get Z Depths, needed for perspective, nice for ortho */
switch (mode) {
case 0:
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, true);
break;
case 1:
- ED_view3d_draw_depth_gpencil(scene, ar, v3d);
+ {
+ Scene *scene = DEG_get_evaluated_scene(graph);
+ ED_view3d_draw_depth_gpencil(eval_ctx, scene, ar, v3d);
break;
+ }
}
}
@@ -5014,9 +4977,7 @@ void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
int margin, float *force_depth)
{
- bglMats mats; /* ZBuffer depth vars, could cache? */
float depth;
- double cent[2], p[3];
/* Get Z Depths, needed for perspective, nice for ortho */
if (force_depth)
@@ -5027,21 +4988,9 @@ bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_world
if (depth == FLT_MAX)
return false;
- cent[0] = (double)mval[0] + 0.5;
- cent[1] = (double)mval[1] + 0.5;
-
- bgl_get_mats(&mats);
-
- if (!gluUnProject(cent[0], cent[1], depth,
- mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
- {
- return false;
- }
-
- mouse_worldloc[0] = (float)p[0];
- mouse_worldloc[1] = (float)p[1];
- mouse_worldloc[2] = (float)p[2];
- return true;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
}
bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
@@ -5223,6 +5172,7 @@ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist,
void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist)
{
float mat[4][4];
+
ED_view3d_to_m4(mat, ofs, quat, dist);
BKE_object_apply_mat4(ob, mat, true, true);
}
@@ -5239,43 +5189,6 @@ void ED_view3d_lastview_store(RegionView3D *rv3d)
}
}
-BGpic *ED_view3D_background_image_new(View3D *v3d)
-{
- BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
-
- bgpic->rotation = 0.0f;
- bgpic->size = 5.0f;
- bgpic->blend = 0.5f;
- bgpic->iuser.fie_ima = 2;
- bgpic->iuser.ok = 1;
- bgpic->view = 0; /* 0 for all */
- bgpic->flag |= V3D_BGPIC_EXPANDED;
-
- BLI_addtail(&v3d->bgpicbase, bgpic);
-
- return bgpic;
-}
-
-void ED_view3D_background_image_remove(View3D *v3d, BGpic *bgpic)
-{
- BLI_remlink(&v3d->bgpicbase, bgpic);
-
- MEM_freeN(bgpic);
-}
-
-void ED_view3D_background_image_clear(View3D *v3d)
-{
- BGpic *bgpic = v3d->bgpicbase.first;
-
- while (bgpic) {
- BGpic *next_bgpic = bgpic->next;
-
- ED_view3D_background_image_remove(v3d, bgpic);
-
- bgpic = next_bgpic;
- }
-}
-
void ED_view3D_lock_clear(View3D *v3d)
{
v3d->ob_centre = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index eda780d01a7..5e7eddb1c22 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -56,6 +56,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "GPU_immediate.h"
+
#include "view3d_intern.h" /* own include */
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
@@ -257,36 +259,45 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
x2 = xoff + 0.55f * fly->width;
y2 = yoff + 0.55f * fly->height;
- UI_ThemeColor(TH_VIEW_OVERLAY);
- glBegin(GL_LINES);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+
+ immBegin(GWN_PRIM_LINES, 16);
+
/* bottom left */
- glVertex2f(x1, y1);
- glVertex2f(x1, y1 + 5);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y1 + 5);
- glVertex2f(x1, y1);
- glVertex2f(x1 + 5, y1);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1 + 5, y1);
/* top right */
- glVertex2f(x2, y2);
- glVertex2f(x2, y2 - 5);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y2 - 5);
- glVertex2f(x2, y2);
- glVertex2f(x2 - 5, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2 - 5, y2);
/* top left */
- glVertex2f(x1, y2);
- glVertex2f(x1, y2 - 5);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1, y2 - 5);
- glVertex2f(x1, y2);
- glVertex2f(x1 + 5, y2);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1 + 5, y2);
/* bottom right */
- glVertex2f(x2, y1);
- glVertex2f(x2, y1 + 5);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y1 + 5);
+
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2 - 5, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2 - 5, y1);
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
static void fly_update_header(bContext *C, wmOperator *op, FlyInfo *fly)
@@ -406,7 +417,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent
}
fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(
- fly->scene, fly->v3d, fly->rv3d,
+ C, fly->scene, fly->v3d, fly->rv3d,
(U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
/* calculate center */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 11dc4d10f2a..4f322b8519d 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -41,11 +41,12 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -71,11 +72,10 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event);
/* XXX quickly ported across */
static void handle_view3d_lock(bContext *C)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = CTX_wm_view3d(C);
-
+
if (v3d != NULL && sa != NULL) {
if (v3d->localvd == NULL && v3d->scenelock && sa->spacetype == SPACE_VIEW3D) {
/* copy to scene */
@@ -83,10 +83,6 @@ static void handle_view3d_lock(bContext *C)
scene->layact = v3d->layact;
scene->camera = v3d->camera;
- /* not through notifier, listener don't have context
- * and non-open screens or spaces need to be updated too */
- BKE_screen_view3d_main_sync(&bmain->screen, scene);
-
/* notifiers for scene update */
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
@@ -172,7 +168,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
if (v3d->scenelock) handle_view3d_lock(C);
- DAG_on_visible_update(CTX_data_main(C), false);
+ DEG_on_visible_update(CTX_data_main(C), false);
ED_area_tag_redraw(sa);
@@ -284,15 +280,16 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
PointerRNA v3dptr, toolsptr, sceneptr;
- Object *ob = OBACT;
+ Object *ob = OBACT(sl);
Object *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
uiBlock *block;
uiLayout *row;
- bool is_paint = false;
- int modeselect;
+ bool is_paint = ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
+ ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr);
RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr);
@@ -303,39 +300,6 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
/* other buttons: */
UI_block_emboss_set(block, UI_EMBOSS);
-
- /* mode */
- if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
- modeselect = OB_MODE_GPENCIL;
- }
- else if (ob) {
- modeselect = ob->mode;
- is_paint = ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
- }
- else {
- modeselect = OB_MODE_OBJECT;
- }
-
- row = uiLayoutRow(layout, false);
- {
- const EnumPropertyItem *item = rna_enum_object_mode_items;
- const char *name = "";
- int icon = ICON_OBJECT_DATAMODE;
-
- while (item->identifier) {
- if (item->value == modeselect && item->identifier[0]) {
- name = IFACE_(item->name);
- icon = item->icon;
- break;
- }
- item++;
- }
-
- uiItemMenuEnumO(row, C, "OBJECT_OT_mode_set", "mode", name, icon);
- }
-
- /* Draw type */
- uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
@@ -364,18 +328,13 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
/* Transform widget / manipulators */
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- if (v3d->twflag & V3D_USE_MANIPULATOR) {
+ if (v3d->twflag & V3D_MANIPULATOR_DRAW) {
uiItemR(row, &v3dptr, "transform_manipulators", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
uiItemR(row, &v3dptr, "transform_orientation", 0, "", ICON_NONE);
}
if (obedit == NULL && v3d->localvd == NULL) {
- unsigned int ob_lay = ob ? ob->lay : 0;
-
- /* Layers */
- uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay);
-
/* Scene lock */
uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 7a106a27833..189e22a04d7 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -37,7 +37,9 @@
struct ARegion;
struct ARegionType;
+struct Base;
struct BoundBox;
+struct Gwn_Batch;
struct DerivedMesh;
struct Object;
struct SmokeDomainSettings;
@@ -46,9 +48,12 @@ struct bContext;
struct bMotionPath;
struct bPoseChannel;
struct Mesh;
+struct SceneLayer;
struct wmOperatorType;
-struct wmWindowManager;
struct wmKeyConfig;
+struct wmManipulatorGroupType;
+struct wmManipulatorType;
+struct wmWindowManager;
/* drawing flags: */
enum {
@@ -99,7 +104,6 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
-void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
@@ -142,13 +146,29 @@ void draw_motion_paths_cleanup(View3D *v3d);
/* drawobject.c */
-void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
-void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag);
-
-bool draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const char dt);
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline);
-void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
-void drawaxes(const float viewmat_local[4][4], float size, char drawtype);
+void draw_object(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d,
+ struct Base *base, const short dflag);
+void draw_object_select(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d,
+ Base *base, const short dflag);
+
+void draw_mesh_object_outline(View3D *v3d, Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
+
+bool draw_glsl_material(Scene *scene, struct SceneLayer *sl, struct Object *ob, View3D *v3d, const char dt);
+void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
+void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
+
+void draw_object_wire_color(Scene *scene, struct SceneLayer *, Base *base, unsigned char r_ob_wire_col[4]);
+void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]);
+void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_obact);
+void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dflag, const unsigned char ob_wire_col[4]);
+void drawspeaker(const unsigned char ob_wire_col[3]);
+void draw_bounding_volume(struct Object *ob, char type, const unsigned char ob_wire_col[4]);
+void draw_rigidbody_shape(struct Object *ob, const unsigned char ob_wire_col[4]);
void view3d_cached_text_draw_begin(void);
void view3d_cached_text_draw_add(const float co[3],
@@ -169,12 +189,13 @@ enum {
int view3d_effective_drawtype(const struct View3D *v3d);
/* drawarmature.c */
-bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4],
- const bool is_outline);
+bool draw_armature(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_outline);
/* drawmesh.c */
-void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
+void draw_mesh_textured(Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
void draw_mesh_face_select(
struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm,
@@ -195,16 +216,28 @@ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
/* view3d_draw.c */
void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
-void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
-void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
+void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset);
+
+void ED_view3d_draw_depth(
+ const struct EvaluationContext *eval_ctx, struct Depsgraph *graph,
+ struct ARegion *ar, View3D *v3d, bool alphaoverride);
+
+/* view3d_draw_legacy.c */
+void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar);
+void ED_view3d_draw_depth_gpencil(const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
+
void ED_view3d_draw_select_loop(
- ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar,
bool use_obedit_skip, bool use_nearest);
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);\
+void ED_view3d_draw_depth_loop(
+ const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
+
+void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
+ const bool do_foreground, const bool do_camera_frame);
+
+void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);
-void circf(float x, float y, float rad);
-void circ(float x, float y, float rad);
void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
float view3d_depth_near(struct ViewDepths *d);
@@ -219,7 +252,6 @@ void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view_selected(struct wmOperatorType *ot);
void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot);
-void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
@@ -248,7 +280,7 @@ void ED_view3d_smooth_view_force_finish(
struct View3D *v3d, struct ARegion *ar);
void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect);
-void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d);
+void view3d_viewmatrix_set(const struct EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
@@ -263,7 +295,7 @@ void view3d_buttons_register(struct ARegionType *art);
/* view3d_camera_control.c */
struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
- Scene *scene, View3D *v3d, RegionView3D *rv3d,
+ const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d,
const bool use_parent_root);
void ED_view3d_cameracontrol_update(
struct View3DCameraControl *vctrl,
@@ -297,6 +329,20 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
+/* view3d_widgets.c */
+void VIEW3D_WGT_lamp_spot(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_lamp_area(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_lamp_target(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera_view(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_force_field(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_empty_image(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_armature_spline(struct wmManipulatorGroupType *wgt);
+
+void VIEW3D_WGT_ruler(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WT_ruler_item(struct wmManipulatorType *wt);
+void VIEW3D_OT_ruler_add(struct wmOperatorType *ot);
+
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
@@ -315,5 +361,31 @@ extern unsigned char view3d_camera_border_hack_col[3];
extern bool view3d_camera_border_hack_test;
#endif
-#endif /* __VIEW3D_INTERN_H__ */
+/* temporary for legacy viewport to work */
+void VP_legacy_drawcursor(Scene *scene, struct SceneLayer *sl, ARegion *ar, View3D *v3d);
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect);
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
+void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect);
+void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
+void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
+void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
+bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void VP_legacy_view3d_stereo3d_setup(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar);
+void draw_dupli_objects(const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base);
+bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
+void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d);
+void VP_drawrenderborder(ARegion *ar, View3D *v3d);
+void VP_view3d_draw_background_none(void);
+void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d);
+void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar);
+
+/* temporary legacy calls, only when there is a switch between new/old draw calls */
+void VP_deprecated_gpu_update_lamps_shadows_world(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d);
+void VP_deprecated_view3d_draw_objects(
+ const struct bContext *C,
+ const struct EvaluationContext *eval_ctx,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, struct GPUFX *fx);
+#endif /* __VIEW3D_INTERN_H__ */
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index ef7b01f7a21..4f80270e1e7 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -40,6 +40,9 @@
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_editmesh.h"
+#include "BKE_context.h"
+
+#include "DEG_depsgraph.h"
#include "bmesh.h"
@@ -104,12 +107,14 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, con
}
void meshobject_foreachScreenVert(
- ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenObjectVert_userData data;
- DerivedMesh *dm = mesh_get_derived_deform(vc->scene, vc->obact, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = mesh_get_derived_deform(eval_ctx, vc->scene, vc->obact, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -145,12 +150,14 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenVert(
- ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenVert_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -199,12 +206,14 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenEdge(
- ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenEdge_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -245,12 +254,14 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenFace(
- ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
void *userData, const eV3DProjTest clip_flag)
{
foreachScreenFace_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_armature.c b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
new file mode 100644
index 00000000000..5d3d88ff2a2
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
@@ -0,0 +1,220 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_armature.c
+ * \ingroup spview3d
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+#include "DNA_armature_types.h"
+
+#include "ED_armature.h"
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Armature Spline Manipulator
+ *
+ * \{ */
+
+/*
+ * TODO(campbell): Current conversion is a approximation (usable not correct),
+ * we'll need to take the next/previous bones into account to get the tangent directions.
+ * First last matrices from 'b_bone_spline_setup' are close but also not quite accurate
+ * since they're not at either end-points on the curve.
+ *
+ * Likely we'll need a function especially to get the first/last orientations.
+ */
+
+#define BBONE_SCALE_Y 3.0f
+
+struct BoneSplineHandle {
+ wmManipulator *manipulator;
+ bPoseChannel *pchan;
+ /* We could remove, keep since at the moment for checking the conversion. */
+ float co[3];
+ int index;
+};
+
+struct BoneSplineWidgetGroup {
+ struct BoneSplineHandle handles[2];
+};
+
+static void manipulator_bbone_offset_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ float *value = value_p;
+ BLI_assert(mpr_prop->type->array_length == 3);
+
+ if (bh->index == 0) {
+ bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveInX;
+ bh->co[2] = pchan->curveInY;
+ }
+ else {
+ bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveOutX;
+ bh->co[2] = pchan->curveOutY;
+ }
+ copy_v3_v3(value, bh->co);
+}
+
+static void manipulator_bbone_offset_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ const float *value = value_p;
+
+ BLI_assert(mpr_prop->type->array_length == 3);
+ copy_v3_v3(bh->co, value);
+
+ if (bh->index == 0) {
+ pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveInX = bh->co[0];
+ pchan->curveInY = bh->co[2];
+ }
+ else {
+ pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveOutX = bh->co[0];
+ pchan->curveOutY = bh->co[2];
+ }
+
+}
+
+static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ if (ob != NULL) {
+ const bArmature *arm = ob->data;
+ if (arm->drawtype == ARM_B_BONE) {
+ if (arm->act_bone && arm->act_bone->segments > 1) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ const wmManipulatorType *wt_grab = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", true);
+
+ struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__);
+ mgroup->customdata = bspline_group;
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmManipulator *mpr;
+ mpr = bspline_group->handles[i].manipulator = WM_manipulator_new_ptr(wt_grab, mgroup, NULL);
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING_2D);
+ RNA_enum_set(mpr->ptr, "draw_options",
+ ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW);
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_VALUE, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+
+ mpr->scale_basis = 0.06f;
+
+ if (i == 0) {
+ copy_v3_v3(mpr->matrix_basis[3], pchan->loc);
+ }
+ }
+}
+
+static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+
+ if (!mgroup->customdata)
+ return;
+
+ struct BoneSplineWidgetGroup *bspline_group = mgroup->customdata;
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmManipulator *mpr = bspline_group->handles[i].manipulator;
+ bspline_group->handles[i].pchan = pchan;
+ bspline_group->handles[i].index = i;
+
+ float mat[4][4];
+ mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
+ copy_m4_m4(mpr->matrix_space, mat);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_manipulator_target_property_def_func(
+ mpr, "offset",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_bbone_offset_get,
+ .value_set_fn = manipulator_bbone_offset_set,
+ .range_get_fn = NULL,
+ .user_data = &bspline_group->handles[i],
+ });
+ }
+}
+
+void VIEW3D_WGT_armature_spline(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Armature Spline Widgets";
+ wgt->idname = "VIEW3D_WGT_armature_spline";
+
+ wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D);
+
+ wgt->poll = WIDGETGROUP_armature_spline_poll;
+ wgt->setup = WIDGETGROUP_armature_spline_setup;
+ wgt->refresh = WIDGETGROUP_armature_spline_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
new file mode 100644
index 00000000000..e8a1b5cea89
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
@@ -0,0 +1,401 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_camera.c
+ * \ingroup spview3d
+ */
+
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_camera.h"
+#include "BKE_context.h"
+
+#include "DNA_object_types.h"
+#include "DNA_camera_types.h"
+
+#include "ED_armature.h"
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Camera Manipulators
+ * \{ */
+
+struct CameraWidgetGroup {
+ wmManipulator *dop_dist;
+ wmManipulator *focal_len;
+ wmManipulator *ortho_scale;
+};
+
+static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ return (ob && ob->type == OB_CAMERA);
+}
+
+static void cameragroup_property_setup(wmManipulator *widget, Object *ob, Camera *ca, const bool is_ortho)
+{
+ const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])};
+ const float scale_fac = ca->drawsize;
+ const float drawsize = is_ortho ?
+ (0.5f * ca->ortho_scale) :
+ (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f));
+ const float half_sensor = 0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? ca->sensor_y : ca->sensor_x);
+ const char *propname = is_ortho ? "ortho_scale" : "lens";
+
+ PointerRNA camera_ptr;
+ float min, max, range;
+ float step, precision;
+
+ RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr);
+
+ /* get property range */
+ PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname);
+ RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision);
+ range = max - min;
+
+ ED_manipulator_arrow3d_set_range_fac(widget, is_ortho ? (scale_fac * range) : (drawsize * range / half_sensor));
+}
+
+static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Object *ob = CTX_data_active_object(C);
+ Camera *ca = ob->data;
+ float dir[3];
+
+ const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", true);
+
+ struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
+ mgroup->customdata = camgroup;
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ /* dof distance */
+ {
+ wmManipulator *mpr;
+ mpr = camgroup->dop_dist = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CROSS);
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_A, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+ }
+
+ /* focal length
+ * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */
+ {
+ wmManipulator *mpr;
+ mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
+ mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE;
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
+ RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+ cameragroup_property_setup(mpr, ob, ca, false);
+
+ mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
+ mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE;
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
+ RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+ cameragroup_property_setup(mpr, ob, ca, true);
+ }
+}
+
+static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ if (!mgroup->customdata)
+ return;
+
+ struct CameraWidgetGroup *camgroup = mgroup->customdata;
+ Object *ob = CTX_data_active_object(C);
+ Camera *ca = ob->data;
+ PointerRNA camera_ptr;
+ float dir[3];
+
+ RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr);
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ if (ca->flag & CAM_SHOWLIMITS) {
+ WM_manipulator_set_matrix_location(camgroup->dop_dist, ob->obmat[3]);
+ WM_manipulator_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir);
+ WM_manipulator_set_scale(camgroup->dop_dist, ca->drawsize);
+ WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, false);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_manipulator_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1);
+ }
+ else {
+ WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ /* TODO - make focal length/ortho scale widget optional */
+ if (true) {
+ const bool is_ortho = (ca->type == CAM_ORTHO);
+ float offset[3];
+ float aspect[2];
+
+ wmManipulator *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len;
+ WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false);
+ WM_manipulator_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_MANIPULATOR_HIDDEN, true);
+
+
+ /* account for lens shifting */
+ offset[0] = ((ob->size[0] > 0.0f) ? -2.0f : 2.0f) * ca->shiftx;
+ offset[1] = 2.0f * ca->shifty;
+ offset[2] = 0.0f;
+
+ /* get aspect */
+ const Scene *scene = CTX_data_scene(C);
+ const float aspx = (float)scene->r.xsch * scene->r.xasp;
+ const float aspy = (float)scene->r.ysch * scene->r.yasp;
+ const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy);
+ aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy;
+ aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f;
+
+ unit_m4(widget->matrix_basis);
+ WM_manipulator_set_matrix_location(widget, ob->obmat[3]);
+ WM_manipulator_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir);
+
+ {
+ float scale_matrix;
+ if (is_ortho) {
+ scale_matrix = ca->ortho_scale * 0.5f;
+ }
+ else {
+ const float scale[3] = {
+ 1.0f / len_v3(ob->obmat[0]),
+ 1.0f / len_v3(ob->obmat[1]),
+ 1.0f / len_v3(ob->obmat[2]),
+ };
+ scale_matrix = ca->drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
+ }
+ mul_v3_fl(widget->matrix_basis[0], scale_matrix);
+ mul_v3_fl(widget->matrix_basis[1], scale_matrix);
+ }
+
+ RNA_float_set_array(widget->ptr, "aspect", aspect);
+
+ WM_manipulator_set_matrix_offset_location(widget, offset);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_manipulator_target_property_def_rna(camgroup->focal_len, "offset", &camera_ptr, "lens", -1);
+ WM_manipulator_target_property_def_rna(camgroup->ortho_scale, "offset", &camera_ptr, "ortho_scale", -1);
+ }
+}
+
+void VIEW3D_WGT_camera(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Camera Widgets";
+ wgt->idname = "VIEW3D_WGT_camera";
+
+ wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_camera_poll;
+ wgt->setup = WIDGETGROUP_camera_setup;
+ wgt->refresh = WIDGETGROUP_camera_refresh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name CameraView Manipulators
+ * \{ */
+
+struct CameraViewWidgetGroup {
+ wmManipulator *border;
+
+ struct {
+ rctf *edit_border;
+ rctf view_border;
+ } state;
+};
+
+/* scale callbacks */
+static void manipulator_render_border_prop_matrix_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
+ const rctf *border = viewgroup->state.edit_border;
+
+ unit_m4(matrix);
+ matrix[0][0] = BLI_rctf_size_x(border);
+ matrix[1][1] = BLI_rctf_size_y(border);
+ matrix[3][0] = BLI_rctf_cent_x(border);
+ matrix[3][1] = BLI_rctf_cent_y(border);
+}
+
+static void manipulator_render_border_prop_matrix_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
+ rctf *border = viewgroup->state.edit_border;
+ BLI_assert(mpr_prop->type->array_length == 16);
+
+ BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1]));
+ BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]);
+ BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border);
+}
+
+static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ /* This is just so the border isn't always in the way,
+ * stealing mouse clicks from regular usage.
+ * We could change the rules for when to show. */
+ {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (scene->camera != OBACT(sl)) {
+ return false;
+ }
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ if (scene->r.mode & R_BORDER) {
+ return true;
+ }
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ return true;
+ }
+ return false;
+}
+
+static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup), __func__);
+
+ viewgroup->border = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+
+ RNA_enum_set(viewgroup->border->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE);
+ /* Box style is more subtle in this case. */
+ RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_MANIPULATOR_CAGE2D_STYLE_BOX);
+
+
+ mgroup->customdata = viewgroup;
+}
+
+static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct CameraViewWidgetGroup *viewgroup = mgroup->customdata;
+
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewgroup->state.view_border, false);
+ }
+ else {
+ viewgroup->state.view_border = (rctf){.xmin = 0, .ymin = 0, .xmax = ar->winx, .ymax = ar->winy};
+ }
+
+ wmManipulator *mpr = viewgroup->border;
+ unit_m4(mpr->matrix_space);
+ mul_v3_fl(mpr->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border));
+ mul_v3_fl(mpr->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border));
+ mpr->matrix_space[3][0] = viewgroup->state.view_border.xmin;
+ mpr->matrix_space[3][1] = viewgroup->state.view_border.ymin;
+}
+
+static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct CameraViewWidgetGroup *viewgroup = mgroup->customdata;
+
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Scene *scene = CTX_data_scene(C);
+
+ {
+ wmManipulator *mpr = viewgroup->border;
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false);
+
+ RNA_enum_set(viewgroup->border->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ viewgroup->state.edit_border = &scene->r.border;
+ }
+ else {
+ viewgroup->state.edit_border = &v3d->render_border;
+ }
+
+ WM_manipulator_target_property_def_func(
+ mpr, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_render_border_prop_matrix_get,
+ .value_set_fn = manipulator_render_border_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = viewgroup,
+ });
+ }
+
+}
+
+void VIEW3D_WGT_camera_view(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Camera View Widgets";
+ wgt->idname = "VIEW3D_WGT_camera_view";
+
+ wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_SCALE);
+
+ wgt->poll = WIDGETGROUP_camera_view_poll;
+ wgt->setup = WIDGETGROUP_camera_view_setup;
+ wgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare;
+ wgt->refresh = WIDGETGROUP_camera_view_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_empty.c b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
new file mode 100644
index 00000000000..1d56c5ee7f4
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
@@ -0,0 +1,196 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_empty.c
+ * \ingroup spview3d
+ */
+
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+#include "BKE_image.h"
+
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Empty Image Manipulators
+ * \{ */
+
+struct EmptyImageWidgetGroup {
+ wmManipulator *manipulator;
+ struct {
+ Object *ob;
+ float dims[2];
+ } state;
+};
+
+/* translate callbacks */
+static void manipulator_empty_image_prop_matrix_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ const Object *ob = imgroup->state.ob;
+
+ unit_m4(matrix);
+ matrix[0][0] = ob->empty_drawsize;
+ matrix[1][1] = ob->empty_drawsize;
+
+ float dims[2] = {0.0f, 0.0f};
+ RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
+
+ matrix[3][0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
+ matrix[3][1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
+}
+
+static void manipulator_empty_image_prop_matrix_set(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ Object *ob = imgroup->state.ob;
+
+ ob->empty_drawsize = matrix[0][0];
+
+ float dims[2];
+ RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
+
+ ob->ima_ofs[0] = (matrix[3][0] - (0.5f * dims[0])) / dims[0];
+ ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
+}
+
+static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && ob->type == OB_EMPTY) {
+ return (ob->empty_drawtype == OB_EMPTY_IMAGE);
+ }
+ return false;
+}
+
+static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct EmptyImageWidgetGroup *imgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__);
+ imgroup->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+ wmManipulator *mpr = imgroup->manipulator;
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE);
+
+ mgroup->customdata = imgroup;
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+}
+
+static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct EmptyImageWidgetGroup *imgroup = mgroup->customdata;
+ Object *ob = CTX_data_active_object(C);
+ wmManipulator *mpr = imgroup->manipulator;
+
+ copy_m4_m4(mpr->matrix_basis, ob->obmat);
+
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE |
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE |
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
+
+ imgroup->state.ob = ob;
+
+ /* Use dimensions for aspect. */
+ if (ob->data != NULL) {
+ const Image *image = ob->data;
+ ImageUser iuser = *ob->iuser;
+ float size[2];
+ BKE_image_get_size_fl(ob->data, &iuser, size);
+
+ /* Get the image aspect even if the buffer is invalid */
+ if (image->aspx > image->aspy) {
+ size[1] *= image->aspy / image->aspx;
+ }
+ else if (image->aspx < image->aspy) {
+ size[0] *= image->aspx / image->aspy;
+ }
+
+ const float dims_max = max_ff(size[0], size[1]);
+ imgroup->state.dims[0] = size[0] / dims_max;
+ imgroup->state.dims[1] = size[1] / dims_max;
+ }
+ else {
+ copy_v2_fl(imgroup->state.dims, 1.0f);
+ }
+ RNA_float_set_array(mpr->ptr, "dimensions", imgroup->state.dims);
+
+ WM_manipulator_target_property_def_func(
+ mpr, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_empty_image_prop_matrix_get,
+ .value_set_fn = manipulator_empty_image_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = imgroup,
+ });
+}
+
+void VIEW3D_WGT_empty_image(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Area Lamp Widgets";
+ wgt->idname = "VIEW3D_WGT_empty_image";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_empty_image_poll;
+ wgt->setup = WIDGETGROUP_empty_image_setup;
+ wgt->refresh = WIDGETGROUP_empty_image_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
new file mode 100644
index 00000000000..6a34f493caf
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
@@ -0,0 +1,118 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_forcefield.c
+ * \ingroup spview3d
+ */
+
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Force Field Manipulators
+ * \{ */
+
+static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ return (ob && ob->pd && ob->pd->forcefield);
+}
+
+static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ /* only wind effector for now */
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+ mgroup->customdata = wwrapper;
+
+ wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, NULL);
+ wmManipulator *mpr = wwrapper->manipulator;
+ RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
+ ED_manipulator_arrow3d_set_ui_range(mpr, -200.0f, 200.0f);
+ ED_manipulator_arrow3d_set_range_fac(mpr, 6.0f);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+}
+
+static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ wmManipulator *mpr = wwrapper->manipulator;
+ Object *ob = CTX_data_active_object(C);
+ PartDeflect *pd = ob->pd;
+
+ if (pd->forcefield == PFIELD_WIND) {
+ const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
+ const float ofs[3] = {0.0f, -size, 0.0f};
+ PointerRNA field_ptr;
+
+ RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr);
+ WM_manipulator_set_matrix_location(mpr, ob->obmat[3]);
+ WM_manipulator_set_matrix_rotation_from_z_axis(mpr, ob->obmat[2]);
+ WM_manipulator_set_matrix_offset_location(mpr, ofs);
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &field_ptr, "strength", -1);
+ }
+ else {
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+}
+
+void VIEW3D_WGT_force_field(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Force Field Widgets";
+ wgt->idname = "VIEW3D_WGT_force_field";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_SCALE |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_forcefield_poll;
+ wgt->setup = WIDGETGROUP_forcefield_setup;
+ wgt->refresh = WIDGETGROUP_forcefield_refresh;
+}
+
+/** \} */
+
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
new file mode 100644
index 00000000000..93b6b69a105
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
@@ -0,0 +1,289 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_lamp.c
+ * \ingroup spview3d
+ */
+
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Spot Lamp Manipulators
+ * \{ */
+
+static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && ob->type == OB_LAMP) {
+ Lamp *la = ob->data;
+ return (la->type == LA_SPOT);
+ }
+ return false;
+}
+
+static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+
+ wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, NULL);
+ wmManipulator *mpr = wwrapper->manipulator;
+ RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_INVERTED);
+
+ mgroup->customdata = wwrapper;
+
+ ED_manipulator_arrow3d_set_range_fac(mpr, 4.0f);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_SECONDARY, mpr->color);
+}
+
+static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ wmManipulator *mpr = wwrapper->manipulator;
+ Object *ob = CTX_data_active_object(C);
+ Lamp *la = ob->data;
+ float dir[3];
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ WM_manipulator_set_matrix_rotation_from_z_axis(mpr, dir);
+ WM_manipulator_set_matrix_location(mpr, ob->obmat[3]);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ PointerRNA lamp_ptr;
+ const char *propname = "spot_size";
+ RNA_pointer_create(&la->id, &RNA_Lamp, la, &lamp_ptr);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &lamp_ptr, propname, -1);
+}
+
+void VIEW3D_WGT_lamp_spot(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Spot Lamp Widgets";
+ wgt->idname = "VIEW3D_WGT_lamp_spot";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_lamp_spot_poll;
+ wgt->setup = WIDGETGROUP_lamp_spot_setup;
+ wgt->refresh = WIDGETGROUP_lamp_spot_refresh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Area Lamp Manipulators
+ * \{ */
+
+/* scale callbacks */
+static void manipulator_area_lamp_prop_matrix_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ BLI_assert(mpr_prop->type->array_length == 16);
+ float (*matrix)[4] = value_p;
+ const Lamp *la = mpr_prop->custom_func.user_data;
+
+ matrix[0][0] = la->area_size;
+ matrix[1][1] = (la->area_shape == LA_AREA_RECT) ? la->area_sizey : la->area_size;
+}
+
+static void manipulator_area_lamp_prop_matrix_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ Lamp *la = mpr_prop->custom_func.user_data;
+
+ if (la->area_shape == LA_AREA_RECT) {
+ la->area_size = len_v3(matrix[0]);
+ la->area_sizey = len_v3(matrix[1]);
+ }
+ else {
+ la->area_size = len_v3(matrix[0]);
+ }
+}
+
+static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && ob->type == OB_LAMP) {
+ Lamp *la = ob->data;
+ return (la->type == LA_AREA);
+ }
+ return false;
+}
+
+static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+ wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+ wmManipulator *mpr = wwrapper->manipulator;
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE);
+
+ mgroup->customdata = wwrapper;
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+}
+
+static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ Object *ob = CTX_data_active_object(C);
+ Lamp *la = ob->data;
+ wmManipulator *mpr = wwrapper->manipulator;
+
+ copy_m4_m4(mpr->matrix_basis, ob->obmat);
+
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE |
+ ((la->area_shape == LA_AREA_SQUARE) ? ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM : 0));
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_manipulator_target_property_def_func(
+ mpr, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_area_lamp_prop_matrix_get,
+ .value_set_fn = manipulator_area_lamp_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = la,
+ });
+}
+
+void VIEW3D_WGT_lamp_area(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Area Lamp Widgets";
+ wgt->idname = "VIEW3D_WGT_lamp_area";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_lamp_area_poll;
+ wgt->setup = WIDGETGROUP_lamp_area_setup;
+ wgt->refresh = WIDGETGROUP_lamp_area_refresh;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Lamp Target Manipulator
+ * \{ */
+
+static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob != NULL) {
+ if (ob->type == OB_LAMP) {
+ Lamp *la = ob->data;
+ return (ELEM(la->type, LA_SUN, LA_SPOT, LA_HEMI, LA_AREA));
+ }
+#if 0
+ else if (ob->type == OB_CAMERA) {
+ return true;
+ }
+#endif
+ }
+ return false;
+}
+
+static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+ wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL);
+ wmManipulator *mpr = wwrapper->manipulator;
+
+ mgroup->customdata = wwrapper;
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+
+ mpr->scale_basis = 0.06f;
+
+ wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true);
+
+ RNA_enum_set(mpr->ptr, "draw_options",
+ ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW);
+
+ WM_manipulator_operator_set(mpr, 0, ot, NULL);
+}
+
+static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ Object *ob = CTX_data_active_object(C);
+ wmManipulator *mpr = wwrapper->manipulator;
+
+ copy_m4_m4(mpr->matrix_basis, ob->obmat);
+ unit_m4(mpr->matrix_offset);
+ mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis;
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_OFFSET_SCALE, true);
+}
+
+void VIEW3D_WGT_lamp_target(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Target Lamp Widgets";
+ wgt->idname = "VIEW3D_WGT_lamp_target";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D);
+
+ wgt->poll = WIDGETGROUP_lamp_target_poll;
+ wgt->setup = WIDGETGROUP_lamp_target_setup;
+ wgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_ruler.c b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
new file mode 100644
index 00000000000..01cf67259a4
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
@@ -0,0 +1,1079 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_ruler.c
+ * \ingroup spview3d
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+#include "BKE_gpencil.h"
+#include "BKE_unit.h"
+
+#include "DNA_object_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BIF_gl.h"
+
+#include "ED_screen.h"
+#include "ED_transform_snap_object_context.h"
+#include "ED_view3d.h"
+
+#include "UI_resources.h"
+#include "UI_interface.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_select.h"
+
+#include "BLF_api.h"
+
+
+static const char *view3d_wgt_ruler_id = "VIEW3D_WGT_ruler";
+
+
+#define MVAL_MAX_PX_DIST 12.0f
+
+/* -------------------------------------------------------------------- */
+/* Ruler Item (we can have many) */
+enum {
+ RULERITEM_USE_ANGLE = (1 << 0), /* use protractor */
+ RULERITEM_USE_RAYCAST = (1 << 1)
+};
+
+enum {
+ RULERITEM_DIRECTION_IN = 0,
+ RULERITEM_DIRECTION_OUT
+};
+
+/* keep smaller then selection, since we may want click elsewhere without selecting a ruler */
+#define RULER_PICK_DIST 12.0f
+#define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST)
+
+/* not clicking on a point */
+#define PART_LINE 0xff
+
+/* -------------------------------------------------------------------- */
+/* Ruler Info (wmManipulatorGroup customdata) */
+
+enum {
+ RULER_STATE_NORMAL = 0,
+ RULER_STATE_DRAG
+};
+
+enum {
+ RULER_SNAP_OK = (1 << 0),
+};
+
+typedef struct RulerInfo {
+ // ListBase items;
+ int item_active;
+ int flag;
+ int snap_flag;
+ int state;
+
+ struct SnapObjectContext *snap_context;
+
+ /* wm state */
+ wmWindow *win;
+ ScrArea *sa;
+ ARegion *ar; /* re-assigned every modal update */
+} RulerInfo;
+
+/* -------------------------------------------------------------------- */
+/* Ruler Item (two or three points) */
+
+typedef struct RulerItem {
+ wmManipulator mpr;
+
+ /* worldspace coords, middle being optional */
+ float co[3][3];
+
+ int flag;
+ int raycast_dir; /* RULER_DIRECTION_* */
+} RulerItem;
+
+typedef struct RulerInteraction {
+ /* selected coord */
+ char co_index; /* 0 -> 2 */
+ float drag_start_co[3];
+ uint inside_region : 1;
+} RulerInteraction;
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Ruler Utilities
+ * \{ */
+
+static RulerItem *ruler_item_add(wmManipulatorGroup *mgroup)
+{
+ /* could pass this as an arg */
+ const wmManipulatorType *wt_ruler = WM_manipulatortype_find("VIEW3D_WT_ruler_item", true);
+ RulerItem *ruler_item = (RulerItem *)WM_manipulator_new_ptr(wt_ruler, mgroup, NULL);
+ WM_manipulator_set_flag(&ruler_item->mpr, WM_MANIPULATOR_DRAW_MODAL, true);
+ return ruler_item;
+}
+
+static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
+ char *numstr, size_t numstr_size, int prec)
+{
+ const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ const float ruler_angle = angle_v3v3v3(ruler_item->co[0],
+ ruler_item->co[1],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle));
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)ruler_angle,
+ prec, unit->system, B_UNIT_ROTATION, do_split, false);
+ }
+ }
+ else {
+ const float ruler_len = len_v3v3(ruler_item->co[0],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len);
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)(ruler_len * unit->scale_length),
+ prec, unit->system, B_UNIT_LENGTH, do_split, false);
+ }
+ }
+}
+
+static bool view3d_ruler_pick(
+ wmManipulatorGroup *mgroup, RulerItem *ruler_item, const float mval[2],
+ int *r_co_index)
+{
+ RulerInfo *ruler_info = mgroup->customdata;
+ ARegion *ar = ruler_info->ar;
+ bool found = false;
+
+ float dist_best = RULER_PICK_DIST_SQ;
+ int co_index_best = -1;
+
+ {
+ float co_ss[3][2];
+ float dist;
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]),
+ dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2]));
+ if (dist < dist_best) {
+ dist_best = dist;
+ found = true;
+
+ {
+ const float dist_points[3] = {
+ len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[1], mval),
+ len_squared_v2v2(co_ss[2], mval),
+ };
+ if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = min_axis_v3(dist_points);
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ else {
+ dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]);
+ if (dist < dist_best) {
+ dist_best = dist;
+ found = true;
+
+ {
+ const float dist_points[2] = {
+ len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[2], mval),
+ };
+ if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ }
+
+ *r_co_index = co_index_best;
+ return found;
+}
+
+/**
+ * Ensure the 'snap_context' is only cached while dragging,
+ * needed since the user may toggle modes between tool use.
+ */
+static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
+{
+ if (state == ruler_info->state) {
+ return;
+ }
+
+ /* always remove */
+ if (ruler_info->snap_context) {
+ ED_transform_snap_object_context_destroy(ruler_info->snap_context);
+ ruler_info->snap_context = NULL;
+ }
+
+ if (state == RULER_STATE_NORMAL) {
+ /* pass */
+ }
+ else if (state == RULER_STATE_DRAG) {
+ ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
+ CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), CTX_data_engine(C), 0,
+ ruler_info->ar, CTX_wm_view3d(C));
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ ruler_info->state = state;
+}
+
+static void view3d_ruler_item_project(
+ RulerInfo *ruler_info, float r_co[3],
+ const int xy[2])
+{
+ ED_view3d_win_to_3d_int(ruler_info->sa->spacedata.first, ruler_info->ar, r_co, xy, r_co);
+}
+
+/* use for mousemove events */
+static bool view3d_ruler_item_mousemove(
+ RulerInfo *ruler_info, RulerItem *ruler_item, const int mval[2],
+ const bool do_thickness, const bool do_snap)
+{
+ RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ const float eps_bias = 0.0002f;
+ float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
+
+ ruler_info->snap_flag &= ~RULER_SNAP_OK;
+
+ if (ruler_item) {
+ float *co = ruler_item->co[inter->co_index];
+ /* restore the initial depth */
+ copy_v3_v3(co, inter->drag_start_co);
+ view3d_ruler_item_project(ruler_info, co, mval);
+ if (do_thickness && inter->co_index != 1) {
+ // Scene *scene = CTX_data_scene(C);
+ // View3D *v3d = ruler_info->sa->spacedata.first;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ float ray_normal[3];
+ float ray_start[3];
+ float *co_other;
+
+ co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
+
+ if (ED_transform_snap_object_project_view3d_mixed(
+ ruler_info->snap_context,
+ SCE_SELECT_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ mval_fl, &dist_px, true,
+ co, ray_normal))
+ {
+ negate_v3(ray_normal);
+ /* add some bias */
+ madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
+ ED_transform_snap_object_project_ray(
+ ruler_info->snap_context,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ ray_start, ray_normal, NULL,
+ co_other, NULL);
+ }
+ }
+ else if (do_snap) {
+ // Scene *scene = CTX_data_scene(C);
+ View3D *v3d = ruler_info->sa->spacedata.first;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ bool use_depth = (v3d->drawtype >= OB_SOLID);
+
+ if (ED_transform_snap_object_project_view3d_mixed(
+ ruler_info->snap_context,
+ (SCE_SELECT_VERTEX | SCE_SELECT_EDGE) | (use_depth ? SCE_SELECT_FACE : 0),
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ mval_fl, &dist_px, use_depth,
+ co, NULL))
+ {
+ ruler_info->snap_flag |= RULER_SNAP_OK;
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ruler/Grease Pencil Conversion
+ * \{ */
+
+#define RULER_ID "RulerData3D"
+static bool view3d_ruler_to_gpencil(bContext *C, wmManipulatorGroup *mgroup)
+{
+ // RulerInfo *ruler_info = mgroup->customdata;
+ Scene *scene = CTX_data_scene(C);
+ bGPDlayer *gpl;
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ bGPDpalette *palette;
+ bGPDpalettecolor *palcolor;
+ RulerItem *ruler_item;
+ const char *ruler_name = RULER_ID;
+ bool changed = false;
+
+ if (scene->gpd == NULL) {
+ scene->gpd = BKE_gpencil_data_addnew("GPencil");
+ }
+
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(scene->gpd, ruler_name, false);
+ gpl->thickness = 1;
+ gpl->flag |= GP_LAYER_HIDE;
+ }
+
+ /* try to get active palette or create a new one */
+ palette = BKE_gpencil_palette_getactive(scene->gpd);
+ if (palette == NULL) {
+ palette = BKE_gpencil_palette_addnew(scene->gpd, DATA_("GP_Palette"), true);
+ }
+ /* try to get color with the ruler name or create a new one */
+ palcolor = BKE_gpencil_palettecolor_getbyname(palette, (char *)ruler_name);
+ if (palcolor == NULL) {
+ palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true);
+ }
+
+ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
+ BKE_gpencil_free_strokes(gpf);
+
+ for (ruler_item = mgroup->manipulators.first; ruler_item; ruler_item = (RulerItem *)ruler_item->mpr.next) {
+ bGPDspoint *pt;
+ int j;
+
+ /* allocate memory for a new stroke */
+ gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ gps->totpoints = 3;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt->strength = 1.0f;
+ pt++;
+ }
+ }
+ else {
+ gps->totpoints = 2;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt->strength = 1.0f;
+ pt++;
+ }
+ }
+ gps->flag = GP_STROKE_3DSPACE;
+ gps->thickness = 3;
+ /* assign color to stroke */
+ BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
+ gps->palcolor = palcolor;
+ BLI_addtail(&gpf->strokes, gps);
+ changed = true;
+ }
+
+ return changed;
+}
+
+static bool view3d_ruler_from_gpencil(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Scene *scene = CTX_data_scene(C);
+ bool changed = false;
+
+ if (scene->gpd) {
+ bGPDlayer *gpl;
+ const char *ruler_name = RULER_ID;
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl) {
+ bGPDframe *gpf;
+ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, false);
+ if (gpf) {
+ bGPDstroke *gps;
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt = gps->points;
+ int j;
+ RulerItem *ruler_item = NULL;
+ if (gps->totpoints == 3) {
+ ruler_item = ruler_item_add(mgroup);
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ ruler_item->flag |= RULERITEM_USE_ANGLE;
+ changed = true;
+ }
+ else if (gps->totpoints == 2) {
+ ruler_item = ruler_item_add(mgroup);
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return changed;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ruler Item Manipulator Type
+ * \{ */
+
+static void manipulator_ruler_draw(const bContext *C, wmManipulator *mpr)
+{
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+ RulerInfo *ruler_info = mpr->parent_mgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)mpr;
+ ARegion *ar = ruler_info->ar;
+ RegionView3D *rv3d = ar->regiondata;
+ const float cap_size = 4.0f;
+ const float bg_margin = 4.0f * U.pixelsize;
+ const float bg_radius = 4.0f * U.pixelsize;
+ const float arc_size = 64.0f * U.pixelsize;
+#define ARC_STEPS 24
+ const int arc_steps = ARC_STEPS;
+ const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ unsigned char color_text[3];
+ unsigned char color_wire[3];
+ float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
+
+ /* anti-aliased lines for more consistent appearance */
+ glEnable(GL_LINE_SMOOTH);
+
+ BLF_enable(blf_mono_font, BLF_ROTATION);
+ BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
+ BLF_rotation(blf_mono_font, 0.0f);
+
+ UI_GetThemeColor3ubv(TH_TEXT, color_text);
+ UI_GetThemeColor3ubv(TH_WIRE, color_wire);
+
+ const bool is_act = (mpr->flag & WM_MANIPULATOR_DRAW_HOVER);
+ float dir_ruler[2];
+ float co_ss[3][2];
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ glEnable(GL_BLEND);
+
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[1]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* arc */
+ {
+ float dir_tmp[3];
+ float co_tmp[3];
+ float arc_ss_coord[2];
+
+ float dir_a[3];
+ float dir_b[3];
+ float quat[4];
+ float axis[3];
+ float angle;
+ const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) *
+ min_fff(arc_size,
+ len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
+ len_v2v2(co_ss[2], co_ss[1]) / 2.0f));
+
+ sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
+ sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
+ normalize_v3(dir_a);
+ normalize_v3(dir_b);
+
+ cross_v3_v3v3(axis, dir_a, dir_b);
+ angle = angle_normalized_v3v3(dir_a, dir_b);
+
+ axis_angle_to_quat(quat, axis, angle / arc_steps);
+
+ copy_v3_v3(dir_tmp, dir_a);
+
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1);
+
+ for (j = 0; j <= arc_steps; j++) {
+ madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
+ ED_view3d_project_float_global(ar, co_tmp, arc_ss_coord, V3D_PROJ_TEST_NOP);
+ mul_qt_v3(quat, dir_tmp);
+
+ immVertex2fv(shdr_pos, arc_ss_coord);
+ }
+
+ immEnd();
+ }
+
+ /* capping */
+ {
+ float rot_90_vec_a[2];
+ float rot_90_vec_b[2];
+ float cap[2];
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
+ rot_90_vec_a[0] = -dir_ruler[1];
+ rot_90_vec_a[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_a);
+
+ sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
+ rot_90_vec_b[0] = -dir_ruler[1];
+ rot_90_vec_b[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_b);
+
+ glEnable(GL_BLEND);
+
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GWN_PRIM_LINES, 8);
+
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
+ immVertex2fv(shdr_pos, cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
+ immVertex2fv(shdr_pos, cap);
+
+ /* angle vertex */
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+
+ immEnd();
+
+ glDisable(GL_BLEND);
+ }
+
+ immUnbindProgram();
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ float posit[2];
+ const int prec = 2; /* XXX, todo, make optional */
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+ posit[0] = co_ss[1][0] + (cap_size * 2.0f);
+ posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+
+ /* draw text (bg) */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(
+ true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
+ /* draw text */
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(GWN_PRIM_LINES, 2);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+
+ /* capping */
+ {
+ float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
+ float cap[2];
+
+ normalize_v2(rot_90_vec);
+
+ glEnable(GL_BLEND);
+
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GWN_PRIM_LINES, 4);
+
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
+ immVertex2fv(shdr_pos, cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
+ immVertex2fv(shdr_pos, cap);
+
+ immEnd();
+
+ glDisable(GL_BLEND);
+ }
+
+ immUnbindProgram();
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float posit[2];
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+ mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
+
+ /* center text */
+ posit[0] -= numstr_size[0] / 2.0f;
+ posit[1] -= numstr_size[1] / 2.0f;
+
+ /* draw text (bg) */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(
+ true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
+ /* draw text */
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+ }
+
+ glDisable(GL_LINE_SMOOTH);
+
+ BLF_disable(blf_mono_font, BLF_ROTATION);
+
+#undef ARC_STEPS
+
+ /* draw snap */
+ if ((ruler_info->snap_flag & RULER_SNAP_OK) &&
+ (ruler_info->state == RULER_STATE_DRAG) &&
+ (ruler_item->mpr.interaction_data != NULL))
+ {
+ RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ /* size from drawSnapping */
+ const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+ float co_ss_snap[3];
+ ED_view3d_project_float_global(ar, ruler_item->co[inter->co_index], co_ss_snap, V3D_PROJ_TEST_NOP);
+
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color_act);
+
+ imm_draw_circle_wire_2d(pos, co_ss_snap[0], co_ss_snap[1], size * U.pixelsize, 32);
+
+ immUnbindProgram();
+ }
+}
+
+static int manipulator_ruler_test_select(
+ bContext *UNUSED(C), wmManipulator *mpr, const wmEvent *event)
+{
+ RulerItem *ruler_item_pick = (RulerItem *)mpr;
+ float mval_fl[2] = {UNPACK2(event->mval)};
+ int co_index;
+
+ /* select and drag */
+ if (view3d_ruler_pick(mpr->parent_mgroup, ruler_item_pick, mval_fl, &co_index)) {
+ if (co_index == -1) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ return PART_LINE;
+ }
+ }
+ else {
+ return co_index;
+ }
+ }
+ return -1;
+}
+
+static int manipulator_ruler_modal(
+ bContext *C, wmManipulator *mpr, const wmEvent *event,
+ eWM_ManipulatorTweak UNUSED(tweak_flag))
+{
+ bool do_draw = false;
+ int exit_code = OPERATOR_RUNNING_MODAL;
+ RulerInfo *ruler_info = mpr->parent_mgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)mpr;
+ RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ ARegion *ar = CTX_wm_region(C);
+
+ ruler_info->ar = ar;
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ if (view3d_ruler_item_mousemove(
+ ruler_info, ruler_item, event->mval,
+ event->shift != 0, event->ctrl != 0))
+ {
+ do_draw = true;
+ }
+ inter->inside_region = BLI_rcti_isect_pt_v(&ar->winrct, &event->x);
+ }
+ break;
+ }
+ }
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+ return exit_code;
+}
+
+static int manipulator_ruler_invoke(
+ bContext *C, wmManipulator *mpr, const wmEvent *event)
+{
+ wmManipulatorGroup *mgroup = mpr->parent_mgroup;
+ RulerInfo *ruler_info = mgroup->customdata;
+ RulerItem *ruler_item_pick = (RulerItem *)mpr;
+ RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
+ mpr->interaction_data = inter;
+
+ ARegion *ar = ruler_info->ar;
+
+ const float mval_fl[2] = {UNPACK2(event->mval)};
+
+ /* select and drag */
+ if (mpr->highlight_part == PART_LINE) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ /* Add Center Point */
+ ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
+ inter->co_index = 1;
+ ruler_state_set(C, ruler_info, RULER_STATE_DRAG);
+
+ /* find the factor */
+ {
+ float co_ss[2][2];
+ float fac;
+
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP);
+
+ fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
+ CLAMP(fac, 0.0f, 1.0f);
+
+ interp_v3_v3v3(ruler_item_pick->co[1],
+ ruler_item_pick->co[0],
+ ruler_item_pick->co[2], fac);
+ }
+
+ /* update the new location */
+ view3d_ruler_item_mousemove(
+ ruler_info, ruler_item_pick, event->mval,
+ event->shift != 0, event->ctrl != 0);
+ }
+ }
+ else {
+ inter->co_index = mpr->highlight_part;
+ ruler_state_set(C, ruler_info, RULER_STATE_DRAG);
+
+ /* store the initial depth */
+ copy_v3_v3(inter->drag_start_co, ruler_item_pick->co[inter->co_index]);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void manipulator_ruler_exit(bContext *C, wmManipulator *mpr, const bool cancel)
+{
+ wmManipulatorGroup *mgroup = mpr->parent_mgroup;
+ RulerInfo *ruler_info = mgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)mpr;
+ RulerInteraction *inter = mpr->interaction_data;
+
+ if (!cancel) {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ /* rubber-band angle removal */
+ if (ruler_item && (inter->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) {
+ if (!inter->inside_region) {
+ ruler_item->flag &= ~RULERITEM_USE_ANGLE;
+ }
+ }
+ if (ruler_info->snap_flag & RULER_SNAP_OK) {
+ ruler_info->snap_flag &= ~RULER_SNAP_OK;
+ }
+ ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
+ }
+ /* We could convert only the current manipulator, for now just re-generate. */
+ view3d_ruler_to_gpencil(C, mgroup);
+ }
+
+ MEM_SAFE_FREE(mpr->interaction_data);
+
+ ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
+}
+
+static int manipulator_ruler_cursor_get(wmManipulator *mpr)
+{
+ if (mpr->highlight_part == PART_LINE) {
+ return BC_CROSSCURSOR;
+ }
+ return BC_NSEW_SCROLLCURSOR;
+}
+
+void VIEW3D_WT_ruler_item(wmManipulatorType *wt)
+{
+ /* identifiers */
+ wt->idname = "VIEW3D_WT_ruler_item";
+
+ /* api callbacks */
+ wt->draw = manipulator_ruler_draw;
+ wt->test_select = manipulator_ruler_test_select;
+ wt->modal = manipulator_ruler_modal;
+ wt->invoke = manipulator_ruler_invoke;
+ wt->exit = manipulator_ruler_exit;
+ wt->cursor_get = manipulator_ruler_cursor_get;
+
+ wt->struct_size = sizeof(RulerItem);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ruler Manipulator Group
+ * \{ */
+
+static bool WIDGETGROUP_ruler_poll(const bContext *C, wmManipulatorGroupType *wgt)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (!STREQ(wgt->idname, workspace->tool.manipulator_group)) {
+ WM_manipulator_group_type_unlink_delayed_ptr(wgt);
+ return false;
+ }
+ return true;
+}
+
+static void WIDGETGROUP_ruler_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
+
+ if (view3d_ruler_from_gpencil(C, mgroup)) {
+ /* nop */
+ }
+
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ ruler_info->win = win;
+ ruler_info->sa = sa;
+ ruler_info->ar = ar;
+
+ mgroup->customdata = ruler_info;
+}
+
+void VIEW3D_WGT_ruler(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Ruler Widgets";
+ wgt->idname = view3d_wgt_ruler_id;
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_SCALE;
+
+ wgt->mmap_params.spaceid = SPACE_VIEW3D;
+ wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+
+ wgt->poll = WIDGETGROUP_ruler_poll;
+ wgt->setup = WIDGETGROUP_ruler_setup;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Ruler Operator
+ * \{ */
+
+static int view3d_ruler_poll(bContext *C)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (!STREQ(view3d_wgt_ruler_id, workspace->tool.manipulator_group) ||
+ CTX_wm_region_view3d(C) == NULL)
+ {
+ return false;
+ }
+ return true;
+}
+
+static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ wmManipulatorMap *mmap = ar->manipulator_map;
+ wmManipulatorGroup *mgroup = WM_manipulatormap_group_find(mmap, view3d_wgt_ruler_id);
+ const bool use_depth = (v3d->drawtype >= OB_SOLID);
+
+ /* Create new line */
+ RulerItem *ruler_item;
+ ruler_item = ruler_item_add(mgroup);
+
+ /* This is a little weak, but there is no real good way to tweak directly. */
+ WM_manipulator_highlight_set(mmap, &ruler_item->mpr);
+ if (WM_operator_name_call(
+ C, "MANIPULATORGROUP_OT_manipulator_tweak",
+ WM_OP_INVOKE_REGION_WIN, NULL) == OPERATOR_RUNNING_MODAL)
+ {
+ RulerInfo *ruler_info = mgroup->customdata;
+ RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ if (use_depth) {
+ /* snap the first point added, not essential but handy */
+ inter->co_index = 0;
+ view3d_ruler_item_mousemove(ruler_info, ruler_item, event->mval, false, true);
+ copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
+ }
+ else {
+ negate_v3_v3(inter->drag_start_co, rv3d->ofs);
+ copy_v3_v3(ruler_item->co[0], inter->drag_start_co);
+ view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
+ }
+
+ copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
+ ruler_item->mpr.highlight_part = inter->co_index = 2;
+ }
+ return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_ruler_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Ruler Add";
+ ot->idname = "VIEW3D_OT_ruler_add";
+ ot->description = "";
+
+ ot->invoke = view3d_ruler_add_invoke;
+ ot->poll = view3d_ruler_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index d71639c35d2..568343f8ec8 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -119,8 +119,8 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "autoselect"))
flag |= FILE_AUTOSELECT;
- if (RNA_boolean_get(op->ptr, "active_layer"))
- flag |= FILE_ACTIVELAY;
+ if (RNA_boolean_get(op->ptr, "active_collection"))
+ flag |= FILE_ACTIVE_COLLECTION;
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
if (BKE_copybuffer_paste(C, str, flag, op->reports)) {
@@ -152,7 +152,7 @@ static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select pasted objects");
- RNA_def_boolean(ot->srna, "active_layer", true, "Active Layer", "Put pasted objects on the active layer");
+ RNA_def_boolean(ot->srna, "active_collection", true, "Active Collection", "Put pasted objects on the active collection");
}
/* ************************** registration **********************************/
@@ -193,7 +193,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_render_border);
WM_operatortype_append(VIEW3D_OT_clear_render_border);
WM_operatortype_append(VIEW3D_OT_zoom_border);
- WM_operatortype_append(VIEW3D_OT_manipulator);
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
WM_operatortype_append(VIEW3D_OT_cursor3d);
WM_operatortype_append(VIEW3D_OT_select_lasso);
@@ -201,7 +200,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_camera_to_view);
WM_operatortype_append(VIEW3D_OT_camera_to_view_selected);
WM_operatortype_append(VIEW3D_OT_object_as_camera);
- WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_walk);
@@ -224,6 +222,8 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_toggle_render);
+ WM_operatortype_append(VIEW3D_OT_ruler_add);
+
transform_operatortypes();
}
@@ -240,24 +240,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
- /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", true);
-
- /* Using KM_ANY here to allow holding modifiers before starting to transform. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_CLICK, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
@@ -372,8 +355,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", true);
-
- WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
#ifdef WITH_INPUT_NDOF
/* note: positioned here so keymaps show keyboard keys if assigned */
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 65a6dee2f6c..f8b02f0b405 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -36,14 +36,13 @@
#include "BLI_sys_types.h" /* int64_t */
-#include "BIF_gl.h" /* bglMats */
-#include "BIF_glutil.h" /* bglMats */
-
#include "BLI_math_vector.h"
#include "BKE_camera.h"
#include "BKE_screen.h"
+#include "GPU_matrix.h"
+
#include "ED_view3d.h" /* own include */
#define BL_NEAR_CLIP 0.001
@@ -656,16 +655,22 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obm
}
/**
- * Uses window coordinates (x,y) and depth component z to find a point in
- * modelspace */
-void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
+ * Convert between region relative coordinates (x,y) and depth component z and
+ * a point in world space. */
+void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3])
{
- double ux, uy, uz;
+ // viewport is set up to make coordinates relative to the region, not window
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
- gluUnProject(x, y, z, mats->modelview, mats->projection,
- (GLint *)mats->viewport, &ux, &uy, &uz);
+ gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region);
+}
+
+bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
+ float region[3] = {regionx, regiony, regionz};
- out[0] = ux;
- out[1] = uy;
- out[2] = uz;
+ return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
}
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index f2c87953302..03f4f506c13 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -43,6 +43,9 @@
#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -279,7 +282,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), 0,
+ CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), CTX_data_engine(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
@@ -425,12 +428,11 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
#define ARC_STEPS 24
const int arc_steps = ARC_STEPS;
int i;
- //unsigned int color_act = 0x666600;
- unsigned int color_act = 0xffffff;
- unsigned int color_base = 0x0;
- unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80};
+ const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
unsigned char color_text[3];
unsigned char color_wire[3];
+ float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
/* anti-aliased lines for more consistent appearance */
glEnable(GL_LINE_SMOOTH);
@@ -455,28 +457,37 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
glEnable(GL_BLEND);
- cpack(is_act ? color_act : color_base);
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j++) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- cpack(0xaaaaaa);
- setlinestyle(3);
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j++) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- setlinestyle(0);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[1]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* arc */
{
float dir_tmp[3];
float co_tmp[3];
- float arc_ss_coords[ARC_STEPS + 1][2];
+ float arc_ss_coord[2];
float dir_a[3];
float dir_b[3];
@@ -500,46 +511,19 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
copy_v3_v3(dir_tmp, dir_a);
- glColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1);
for (j = 0; j <= arc_steps; j++) {
madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
- ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, co_tmp, arc_ss_coord, V3D_PROJ_TEST_NOP);
mul_qt_v3(quat, dir_tmp);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords);
- glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- /* text */
- {
- char numstr[256];
- float numstr_size[2];
- float pos[2];
- const int prec = 2; /* XXX, todo, make optional */
-
- ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
-
- BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
-
- pos[0] = co_ss[1][0] + (cap_size * 2.0f);
- pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+ immVertex2fv(shdr_pos, arc_ss_coord);
+ }
- /* draw text (bg) */
- glColor4ubv(color_back);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(
- pos[0] - bg_margin, pos[1] - bg_margin,
- pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
- bg_radius);
- /* draw text */
- glColor3ubv(color_text);
- BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
- BLF_rotation(blf_mono_font, 0.0f);
- BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ immEnd();
}
/* capping */
@@ -560,75 +544,84 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
glEnable(GL_BLEND);
- glColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 8);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
/* angle vertex */
- glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
- glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
- glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
- glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
- glEnd();
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+
+ immEnd();
glDisable(GL_BLEND);
}
- }
- else {
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j += 2) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- cpack(0xaaaaaa);
- setlinestyle(3);
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j += 2) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- setlinestyle(0);
- sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+ immUnbindProgram();
/* text */
{
char numstr[256];
float numstr_size[2];
- const int prec = 6; /* XXX, todo, make optional */
- float pos[2];
+ float posit[2];
+ const int prec = 2; /* XXX, todo, make optional */
ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
- mid_v2_v2v2(pos, co_ss[0], co_ss[2]);
-
- /* center text */
- pos[0] -= numstr_size[0] / 2.0f;
- pos[1] -= numstr_size[1] / 2.0f;
+ posit[0] = co_ss[1][0] + (cap_size * 2.0f);
+ posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
/* draw text (bg) */
- glColor4ubv(color_back);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(pos[0] - bg_margin, pos[1] - bg_margin,
- pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
- bg_radius);
+ UI_draw_roundbox_aa(true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
/* draw text */
- glColor3ubv(color_text);
- BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
BLF_draw(blf_mono_font, numstr, sizeof(numstr));
}
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(GWN_PRIM_LINES, 2);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
/* capping */
{
@@ -638,22 +631,56 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
normalize_v2(rot_90_vec);
glEnable(GL_BLEND);
- glColor3ubv(color_wire);
- glBegin(GL_LINES);
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GWN_PRIM_LINES, 4);
+
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
- glVertex2fv(cap);
- glEnd();
+ immVertex2fv(shdr_pos, cap);
+
+ immEnd();
glDisable(GL_BLEND);
}
+
+ immUnbindProgram();
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float posit[2];
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+ mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
+
+ /* center text */
+ posit[0] -= numstr_size[0] / 2.0f;
+ posit[1] -= numstr_size[1] / 2.0f;
+
+ /* draw text (bg) */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
+ /* draw text */
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
}
}
@@ -672,8 +699,14 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
float co_ss[3];
ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP);
- cpack(color_act);
- circ(co_ss[0], co_ss[1], size * U.pixelsize);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color_act);
+
+ imm_draw_circle_wire_2d(pos, co_ss[0], co_ss[1], size * U.pixelsize, 32);
+
+ immUnbindProgram();
}
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 05cf552e5cc..297bd5c4aa1 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -63,16 +63,16 @@
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
+#include "BKE_scene.h"
#include "BKE_tracking.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "DEG_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -93,6 +93,8 @@
#include "UI_interface.h"
#include "GPU_draw.h"
+#include "GPU_glew.h"
+#include "GPU_matrix.h"
#include "view3d_intern.h" /* own include */
@@ -108,7 +110,10 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
{
memset(vc, 0, sizeof(ViewContext));
vc->ar = CTX_wm_region(C);
+ vc->depsgraph = CTX_data_depsgraph(C);
vc->scene = CTX_data_scene(C);
+ vc->scene_layer = CTX_data_scene_layer(C);
+ vc->engine = CTX_data_engine(C);
vc->v3d = CTX_wm_view3d(C);
vc->win = CTX_wm_window(C);
vc->rv3d = CTX_wm_region_view3d(C);
@@ -116,34 +121,6 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
vc->obedit = CTX_data_edit_object(C);
}
-/*
- * ob == NULL if you want global matrices
- * */
-void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats)
-{
- float cpy[4][4];
- int i, j;
-
- if (ob) {
- mul_m4_m4m4(cpy, rv3d->viewmat, ob->obmat);
- }
- else {
- copy_m4_m4(cpy, rv3d->viewmat);
- }
-
- for (i = 0; i < 4; ++i) {
- for (j = 0; j < 4; ++j) {
- mats->projection[i * 4 + j] = rv3d->winmat[i][j];
- mats->modelview[i * 4 + j] = cpy[i][j];
- }
- }
-
- mats->viewport[0] = ar->winrct.xmin;
- mats->viewport[1] = ar->winrct.ymin;
- mats->viewport[2] = ar->winx;
- mats->viewport[3] = ar->winy;
-}
-
/* ********************** view3d_select: selection manipulations ********************* */
/* local prototypes */
@@ -394,18 +371,18 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[]
bArmature *arm = ob->data;
if (arm->flag & ARM_HAS_VIZ_DEPS) {
/* mask modifier ('armature' mode), etc. */
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
}
-static void object_deselect_all_visible(Scene *scene, View3D *v3d)
+static void object_deselect_all_visible(SceneLayer *sl)
{
Base *base;
- for (base = scene->base.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- ED_base_object_select(base, BA_DESELECT);
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE(base)) {
+ ED_object_base_select(base, BA_DESELECT);
}
}
}
@@ -416,15 +393,14 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons
Base *base;
if (extend == false && select)
- object_deselect_all_visible(vc->scene, vc->v3d);
+ object_deselect_all_visible(vc->scene_layer);
- for (base = vc->scene->base.first; base; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */
+ for (base = vc->scene_layer->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE(base)) { /* use this to avoid un-needed lasso lookups */
if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) {
if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
- base->object->flag = base->flag;
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) {
@@ -481,7 +457,9 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, cons
}
}
-static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_mesh(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const int mcords[][2], short moves, bool extend, bool select)
{
LassoSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
@@ -501,25 +479,25 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- glLoadMatrixf(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ gpuLoadMatrix(vc->rv3d->viewmat);
+ bbsel = EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == false) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -528,7 +506,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -727,7 +705,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv,
SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
}
}
-static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_paintvert(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
@@ -745,7 +723,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
edbm_backbuf_check_and_select_verts_obmode(me, select);
@@ -758,7 +736,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
@@ -767,7 +745,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
}
paintvert_flush_flags(ob);
}
-static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_paintface(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
Object *ob = vc->obact;
Mesh *me = ob->data;
@@ -782,7 +760,7 @@ static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], sh
bm_vertoffs = me->totpoly + 1; /* max index array */
BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
edbm_backbuf_check_and_select_tfaces(me, select);
@@ -828,16 +806,22 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
{
Object *ob = CTX_data_active_object(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (vc->obedit == NULL) { /* Object Mode */
- if (BKE_paint_select_face_test(ob))
- do_lasso_select_paintface(vc, mcords, moves, extend, select);
- else if (BKE_paint_select_vert_test(ob))
- do_lasso_select_paintvert(vc, mcords, moves, extend, select);
+ if (BKE_paint_select_face_test(ob)) {
+ do_lasso_select_paintface(&eval_ctx, vc, mcords, moves, extend, select);
+ }
+ else if (BKE_paint_select_vert_test(ob)) {
+ do_lasso_select_paintvert(&eval_ctx, vc, mcords, moves, extend, select);
+ }
else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
/* pass */
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT))
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
PE_lasso_select(C, mcords, moves, extend, select);
+ }
else {
do_lasso_select_objects(vc, mcords, moves, extend, select);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
@@ -846,7 +830,7 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
else { /* Edit Mode */
switch (vc->obedit->type) {
case OB_MESH:
- do_lasso_select_mesh(vc, mcords, moves, extend, select);
+ do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select);
break;
case OB_CURVE:
case OB_SURF:
@@ -930,7 +914,7 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
base = LASTBASE;
if (base == 0) return 0;
- maxob = base->selcol;
+ maxob = base->object->select_color;
len = (size - 1) / 2;
rc = 0;
@@ -1016,8 +1000,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
if (!toggle) {
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if (base->flag & SELECT) {
- ED_base_object_select(base, BA_DESELECT);
+ if ((base->flag & BASE_SELECTED) != 0) {
+ ED_object_base_select(base, BA_DESELECT);
changed = true;
}
}
@@ -1028,8 +1012,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
{
/* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */
if (STREQ(name, base->object->id.name + 2)) {
- ED_base_object_activate(C, base);
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_activate(C, base);
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -1073,14 +1057,12 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
}
-static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */
+static void deselectall_except(SceneLayer *sl, Base *b) /* deselect all except b */
{
- Base *base;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->flag & SELECT) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_SELECTED) {
if (b != base) {
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
}
}
}
@@ -1093,7 +1075,8 @@ static Base *object_mouse_select_menu(
short baseCount = 0;
bool ok;
LinkNode *linklist = NULL;
-
+
+ /* handle base->object->select_color */
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
ok = false;
@@ -1102,7 +1085,7 @@ static Base *object_mouse_select_menu(
if (buffer) {
for (int a = 0; a < hits; a++) {
/* index was converted */
- if (base->selcol == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
+ if (base->object->select_color == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
ok = true;
break;
}
@@ -1201,7 +1184,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits15, const
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static int mixed_bones_object_selectbuffer(
- ViewContext *vc, unsigned int *buffer, const int mval[2],
+ const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, const int mval[2],
bool use_cycle, bool enumerate,
bool *r_do_nearest)
{
@@ -1241,7 +1224,7 @@ static int mixed_bones_object_selectbuffer(
view3d_opengl_select_cache_begin();
BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode);
+ hits15 = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, &rect, select_mode);
if (hits15 == 1) {
hits = selectbuffer_ret_hits_15(buffer, hits15);
goto finally;
@@ -1252,7 +1235,7 @@ static int mixed_bones_object_selectbuffer(
offs = 4 * hits15;
BLI_rcti_init_pt_radius(&rect, mval, 9);
- hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits9 = view3d_opengl_select(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits9 == 1) {
hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
goto finally;
@@ -1262,7 +1245,7 @@ static int mixed_bones_object_selectbuffer(
offs += 4 * hits9;
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits5 = view3d_opengl_select(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits5 == 1) {
hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
goto finally;
@@ -1291,8 +1274,7 @@ finally:
static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits,
Base *startbase, bool has_bones, bool do_nearest)
{
- Scene *scene = vc->scene;
- View3D *v3d = vc->v3d;
+ SceneLayer *sl = vc->scene_layer;
Base *base, *basact = NULL;
int a;
@@ -1312,7 +1294,9 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
else {
/* only exclude active object when it is selected... */
- if (BASACT && (BASACT->flag & SELECT) && hits > 1) notcol = BASACT->selcol;
+ if (BASACT(sl) && (BASACT(sl)->flag & BASE_SELECTED) && hits > 1) {
+ notcol = BASACT(sl)->object->select_color;
+ }
for (a = 0; a < hits; a++) {
if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
@@ -1322,10 +1306,10 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
}
- base = FIRSTBASE;
+ base = FIRSTBASE(sl);
while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
- if (base->selcol == selcol) break;
+ if (BASE_SELECTABLE(base)) {
+ if (base->object->select_color == selcol) break;
}
base = base->next;
}
@@ -1337,23 +1321,23 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
while (base) {
/* skip objects with select restriction, to prevent prematurely ending this loop
* with an un-selectable choice */
- if (base->object->restrictflag & OB_RESTRICT_SELECT) {
+ if ((base->flag & BASE_SELECTABLED) == 0) {
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE(sl);
if (base == startbase) break;
}
- if (BASE_SELECTABLE(v3d, base)) {
+ if (BASE_SELECTABLE(base)) {
for (a = 0; a < hits; a++) {
if (has_bones) {
/* skip non-bone objects */
if ((buffer[4 * a + 3] & 0xFFFF0000)) {
- if (base->selcol == (buffer[(4 * a) + 3] & 0xFFFF))
+ if (base->object->select_color == (buffer[(4 * a) + 3] & 0xFFFF))
basact = base;
}
}
else {
- if (base->selcol == (buffer[(4 * a) + 3] & 0xFFFF))
+ if (base->object->select_color == (buffer[(4 * a) + 3] & 0xFFFF))
basact = base;
}
}
@@ -1362,7 +1346,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
if (basact) break;
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE(sl);
if (base == startbase) break;
}
}
@@ -1373,6 +1357,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
/* mval comes from event->mval, only use within region handlers */
Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
{
+ EvaluationContext eval_ctx;
ViewContext vc;
Base *basact = NULL;
unsigned int buffer[MAXPICKBUF];
@@ -1381,13 +1366,15 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
/* setup view context for argument to callbacks */
view3d_operator_needs_opengl(C);
+
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest);
+ hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, false, false, &do_nearest);
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene->base.first, has_bones, do_nearest);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene_layer->object_bases.first, has_bones, do_nearest);
}
return basact;
@@ -1417,10 +1404,11 @@ static bool ed_object_select_pick(
bContext *C, const int mval[2],
bool extend, bool deselect, bool toggle, bool obcenter, bool enumerate, bool object)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
bool is_obedit;
float dist = ED_view3d_select_dist_px() * 1.3333f;
@@ -1430,6 +1418,7 @@ static bool ed_object_select_pick(
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
is_obedit = (vc.obedit != NULL);
@@ -1439,8 +1428,8 @@ static bool ed_object_select_pick(
}
/* always start list from basact in wire mode */
- startbase = FIRSTBASE;
- if (BASACT && BASACT->next) startbase = BASACT->next;
+ startbase = FIRSTBASE(sl);
+ if (BASACT(sl) && BASACT(sl)->next) startbase = BASACT(sl)->next;
/* This block uses the control key to make the object selected by its center point rather than its contents */
/* in editmode do not activate */
@@ -1453,13 +1442,13 @@ static bool ed_object_select_pick(
else {
base = startbase;
while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
+ if (BASE_SELECTABLE(base)) {
float screen_co[2];
if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
- if (base == BASACT) dist_temp += 10.0f;
+ if (base == BASACT(sl)) dist_temp += 10.0f;
if (dist_temp < dist) {
dist = dist_temp;
basact = base;
@@ -1468,7 +1457,7 @@ static bool ed_object_select_pick(
}
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE(sl);
if (base == startbase) break;
}
}
@@ -1480,7 +1469,7 @@ static bool ed_object_select_pick(
// TIMEIT_START(select_time);
/* if objects have posemode set, the bones are in the same selection buffer */
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest);
+ hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, true, enumerate, &do_nearest);
// TIMEIT_END(select_time);
@@ -1498,7 +1487,7 @@ static bool ed_object_select_pick(
if (has_bones && basact) {
if (basact->object->type == OB_CAMERA) {
- if (BASACT == basact) {
+ if (BASACT(sl) == basact) {
int i, hitresult;
bool changed = false;
@@ -1507,7 +1496,7 @@ static bool ed_object_select_pick(
/* if there's bundles in buffer select bundles first,
* so non-camera elements should be ignored in buffer */
- if (basact->selcol != (hitresult & 0xFFFF)) {
+ if (basact->object->select_color != (hitresult & 0xFFFF)) {
continue;
}
@@ -1536,8 +1525,8 @@ static bool ed_object_select_pick(
changed = true;
}
- basact->flag |= SELECT;
- basact->object->flag = basact->flag;
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(basact);
retval = true;
@@ -1555,27 +1544,27 @@ static bool ed_object_select_pick(
}
}
}
- else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
+ else if (ED_do_pose_selectbuffer(scene, sl, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
/* then bone is found */
/* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
- basact->flag |= SELECT;
- basact->object->flag = basact->flag;
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(basact);
retval = true;
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if (BASACT && (BASACT->object->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (BASACT(sl) && (BASACT(sl)->object->mode & OB_MODE_WEIGHT_PAINT)) {
/* prevent activating */
basact = NULL;
}
}
/* prevent bone selecting to pass on to object selecting */
- if (basact == BASACT)
+ if (basact == BASACT(sl))
basact = NULL;
}
}
@@ -1587,37 +1576,37 @@ static bool ed_object_select_pick(
if (vc.obedit) {
/* only do select */
- deselectall_except(scene, basact);
- ED_base_object_select(basact, BA_SELECT);
+ deselectall_except(sl, basact);
+ ED_object_base_select(basact, BA_SELECT);
}
/* also prevent making it active on mouse selection */
- else if (BASE_SELECTABLE(v3d, basact)) {
+ else if (BASE_SELECTABLE(basact)) {
- oldbasact = BASACT;
+ oldbasact = BASACT(sl);
if (extend) {
- ED_base_object_select(basact, BA_SELECT);
+ ED_object_base_select(basact, BA_SELECT);
}
else if (deselect) {
- ED_base_object_select(basact, BA_DESELECT);
+ ED_object_base_select(basact, BA_DESELECT);
}
else if (toggle) {
- if (basact->flag & SELECT) {
+ if (basact->flag & BASE_SELECTED) {
if (basact == oldbasact) {
- ED_base_object_select(basact, BA_DESELECT);
+ ED_object_base_select(basact, BA_DESELECT);
}
}
else {
- ED_base_object_select(basact, BA_SELECT);
+ ED_object_base_select(basact, BA_SELECT);
}
}
else {
- deselectall_except(scene, basact);
- ED_base_object_select(basact, BA_SELECT);
+ deselectall_except(sl, basact);
+ ED_object_base_select(basact, BA_SELECT);
}
if ((oldbasact != basact) && (is_obedit == false)) {
- ED_base_object_activate(C, basact); /* adds notifier */
+ ED_object_base_activate(C, basact); /* adds notifier */
}
}
@@ -1673,7 +1662,8 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con
SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
}
}
-static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_paintvert_box_select(
+ const EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Mesh *me;
@@ -1697,7 +1687,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo
if (use_zbuf) {
selar = MEM_callocN(me->totvert + 1, "selar");
- ED_view3d_backbuf_validate(vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
rt = ibuf->rect;
@@ -1745,7 +1735,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
if (select == false) {
@@ -1860,7 +1850,8 @@ static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const
BM_face_select_set(data->vc->em->bm, efa, data->select);
}
}
-static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_mesh_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend)
{
BoxSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
@@ -1874,26 +1865,26 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- glLoadMatrixf(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ gpuLoadMatrix(vc->rv3d->viewmat);
+ bbsel = EDBM_backbuf_border_init(eval_ctx, vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -1902,7 +1893,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -1913,7 +1904,9 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
return OPERATOR_FINISHED;
}
-static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_meta_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const rcti *rect, bool select, bool extend)
{
MetaBall *mb = (MetaBall *)vc->obedit->data;
MetaElem *ml;
@@ -1922,7 +1915,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
if (extend == false && select)
BKE_mball_deselect_all(mb);
@@ -1947,7 +1940,9 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
return OPERATOR_FINISHED;
}
-static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_armature_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const rcti *rect, bool select, bool extend)
{
bArmature *arm = vc->obedit->data;
EditBone *ebone;
@@ -1956,7 +1951,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
/* clear flag we use to detect point was affected */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next)
@@ -2020,8 +2015,30 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
return hits > 0 ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+/**
+ * Compare result of 'GPU_select': 'uint[4]',
+ * needed for when we need to align with object draw-order.
+ */
+static int opengl_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p)
+{
+ /* 4th element is select id */
+ const uint sel_a = ((uint *)sel_a_p)[3];
+ const uint sel_b = ((uint *)sel_b_p)[3];
+
+ if (sel_a < sel_b) {
+ return -1;
+ }
+ else if (sel_a > sel_b) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
{
+ EvaluationContext eval_ctx;
Bone *bone;
Object *ob = vc->obact;
unsigned int *vbuffer = NULL; /* selection buffer */
@@ -2031,6 +2048,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
int totobj = MAXPICKBUF; /* XXX solve later */
int hits;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if ((ob) && (ob->mode & OB_MODE_POSE))
bone_only = 1;
else
@@ -2047,13 +2066,13 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
CTX_DATA_END;
}
else {
- object_deselect_all_visible(vc->scene, vc->v3d);
+ object_deselect_all_visible(vc->scene_layer);
}
}
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(&eval_ctx, vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection
@@ -2061,18 +2080,22 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
* is the same as the object, we have a hit and can move to the next color
* and object pair, if not, just move to the next object,
* keeping the same color until we have a hit.
- *
- * The buffer order is defined by OGL standard, hopefully no stupid GFX card
- * does it incorrectly.
*/
if (hits > 0) { /* no need to loop if there's no hit */
Base *base;
col = vbuffer + 3;
-
- for (base = vc->scene->base.first; base && hits; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base)) {
- while (base->selcol == (*col & 0xFFFF)) { /* we got an object */
+
+ /* The draw order doesn't always match the order we populate the engine, see: T51695. */
+ qsort(vbuffer, hits, sizeof(uint[4]), opengl_select_buffer_cmp);
+
+ /*
+ * Even though 'DRW_draw_select_loop' uses 'DEG_OBJECT_ITER',
+ * we can be sure the order remains the same between both.
+ */
+ for (base = vc->scene_layer->object_bases.first; base && hits; base = base->next) {
+ if (BASE_SELECTABLE(base)) {
+ while (base->object->select_color == (*col & 0xFFFF)) { /* we got an object */
if (*col & 0xFFFF0000) { /* we got a bone */
bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
if (bone) {
@@ -2091,7 +2114,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
}
}
else if (!bone_only) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
col += 4; /* next color */
@@ -2108,7 +2131,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) {
/* mask modifier ('armature' mode), etc. */
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
}
@@ -2123,6 +2146,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
static int view3d_borderselect_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
rcti rect;
bool extend;
@@ -2133,6 +2157,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
view3d_operator_needs_opengl(C);
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
select = !RNA_boolean_get(op->ptr, "deselect");
@@ -2143,7 +2168,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
switch (vc.obedit->type) {
case OB_MESH:
vc.em = BKE_editmesh_from_object(vc.obedit);
- ret = do_mesh_box_select(&vc, &rect, select, extend);
+ ret = do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend);
// if (EM_texFaceCheck())
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
@@ -2157,13 +2182,13 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
}
break;
case OB_MBALL:
- ret = do_meta_box_select(&vc, &rect, select, extend);
+ ret = do_meta_box_select(&eval_ctx, &vc, &rect, select, extend);
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
}
break;
case OB_ARMATURE:
- ret = do_armature_box_select(&vc, &rect, select, extend);
+ ret = do_armature_box_select(&eval_ctx, &vc, &rect, select, extend);
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
}
@@ -2184,10 +2209,10 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend);
}
else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
- ret = do_paintface_box_select(&vc, &rect, select, extend);
+ ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend);
}
else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
- ret = do_paintvert_box_select(&vc, &rect, select, extend);
+ ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend);
}
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
ret = PE_border_select(C, &rect, select, extend);
@@ -2431,13 +2456,13 @@ static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float sc
}
}
-static void mesh_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
+static void mesh_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
ToolSettings *ts = vc->scene->toolsettings;
int bbsel;
CircleSelectUserData data;
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
vc->em = BKE_editmesh_from_object(vc->obedit);
@@ -2449,7 +2474,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2458,7 +2483,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
edbm_backbuf_check_and_select_edges(vc->em, select);
}
else {
- mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2467,7 +2492,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2475,7 +2500,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
EDBM_selectmode_flush(vc->em);
}
-static void paint_facesel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
+static void paint_facesel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
Object *ob = vc->obact;
Mesh *me = ob->data;
@@ -2483,7 +2508,7 @@ static void paint_facesel_circle_select(ViewContext *vc, const bool select, cons
bm_vertoffs = me->totpoly + 1; /* max index array */
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
if (bbsel) {
edbm_backbuf_check_and_select_tfaces(me, select);
EDBM_backbuf_free();
@@ -2499,7 +2524,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv,
SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
}
}
-static void paint_vertsel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
+static void paint_vertsel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
@@ -2510,7 +2535,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons
if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
if (bbsel) {
edbm_backbuf_check_and_select_verts_obmode(me, select);
EDBM_backbuf_free();
@@ -2522,7 +2547,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
- meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
if (select != LEFTMOUSE) {
@@ -2666,7 +2691,7 @@ static void pose_circle_select(ViewContext *vc, const bool select, const int mva
if (arm->flag & ARM_HAS_VIZ_DEPS) {
/* mask modifier ('armature' mode), etc. */
- DAG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
}
}
}
@@ -2776,11 +2801,12 @@ static void mball_circle_select(ViewContext *vc, const bool select, const int mv
/** Callbacks for circle selection in Editmode */
-static void obedit_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
+static void obedit_circle_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
switch (vc->obedit->type) {
case OB_MESH:
- mesh_circle_select(vc, select, mval, rad);
+ mesh_circle_select(eval_ctx, vc, select, mval, rad);
break;
case OB_CURVE:
case OB_SURF:
@@ -2802,22 +2828,22 @@ static void obedit_circle_select(ViewContext *vc, const bool select, const int m
static bool object_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
{
- Scene *scene = vc->scene;
+ SceneLayer *sl = vc->scene_layer;
const float radius_squared = rad * rad;
const float mval_fl[2] = {mval[0], mval[1]};
bool changed = false;
- const int select_flag = select ? SELECT : 0;
+ const int select_flag = select ? BASE_SELECTED : 0;
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) {
+ for (base = FIRSTBASE(sl); base; base = base->next) {
+ if (BASE_SELECTABLE(base) && ((base->flag & BASE_SELECTED) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
changed = true;
}
}
@@ -2840,22 +2866,24 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) ||
(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) )
{
+ EvaluationContext eval_ctx;
ViewContext vc;
view3d_operator_needs_opengl(C);
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
if (CTX_data_edit_object(C)) {
- obedit_circle_select(&vc, select, mval, (float)radius);
+ obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (BKE_paint_select_face_test(obact)) {
- paint_facesel_circle_select(&vc, select, mval, (float)radius);
+ paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (BKE_paint_select_vert_test(obact)) {
- paint_vertsel_circle_select(&vc, select, mval, (float)radius);
+ paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (obact->mode & OB_MODE_POSE)
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 5dd69cc66eb..1df29201bf6 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -40,13 +40,14 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_tracking.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -73,9 +74,12 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
RegionView3D *rv3d = CTX_wm_region_data(C);
TransVertStore tvs = {NULL};
TransVert *tv;
+ EvaluationContext eval_ctx;
float gridf, imat[3][3], bmat[3][3], vec[3];
int a;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
gridf = rv3d->gridview;
if (obedit) {
@@ -153,7 +157,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
}
ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else {
vec[0] = -ob->obmat[3][0] + gridf * floorf(0.5f + ob->obmat[3][0] / gridf);
@@ -162,7 +166,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->parent) {
float originmat[3][3];
- BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
+ BKE_object_where_is_calc_ex(&eval_ctx, scene, NULL, ob, originmat);
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, vec);
@@ -177,7 +181,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
/* auto-keyframing */
ED_autokeyframe_object(C, scene, ob, ks);
- DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
CTX_DATA_END;
@@ -213,11 +217,14 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
View3D *v3d = CTX_wm_view3d(C);
TransVertStore tvs = {NULL};
TransVert *tv;
+ EvaluationContext eval_ctx;
float imat[3][3], bmat[3][3];
float center_global[3];
float offset_global[3];
int a;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (use_offset) {
if ((v3d && v3d->around == V3D_AROUND_ACTIVE) &&
snap_calc_active_center(C, true, center_global))
@@ -329,7 +336,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
obact->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
- DAG_id_tag_update(&obact->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&obact->id, OB_RECALC_DATA);
}
else {
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
@@ -370,7 +377,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
if (ob->parent) {
float originmat[3][3];
- BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
+ BKE_object_where_is_calc_ex(&eval_ctx, scene, NULL, ob, originmat);
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, cursor_parent);
@@ -385,7 +392,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
/* auto-keyframing */
ED_autokeyframe_object(C, scene, ob, ks);
- DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 0bccab626e6..4e98386be97 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -43,7 +43,6 @@
#include "BKE_action.h"
#include "BKE_camera.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -51,12 +50,15 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BIF_gl.h"
+#include "DEG_depsgraph.h"
+
#include "BIF_glutil.h"
#include "UI_resources.h"
+#include "GPU_glew.h"
#include "GPU_select.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -64,6 +66,8 @@
#include "ED_screen.h"
#include "ED_armature.h"
+#include "DRW_engine.h"
+
#ifdef WITH_GAMEENGINE
# include "BLI_listbase.h"
@@ -98,10 +102,8 @@ void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar)
RegionView3D *rv3d = ar->regiondata;
wmSubWindowSet(win, ar->swinid);
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
}
@@ -443,6 +445,9 @@ void ED_view3d_smooth_view_force_finish(
View3D *v3d, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
+ EvaluationContext eval_ctx;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
if (rv3d && rv3d->sms) {
rv3d->sms->time_allowed = 0.0; /* force finishing */
@@ -451,7 +456,7 @@ void ED_view3d_smooth_view_force_finish(
/* force update of view matrix so tools that run immediately after
* can use them without redrawing first */
Scene *scene = CTX_data_scene(C);
- ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL, NULL);
+ ED_view3d_update_viewmat(&eval_ctx, scene, v3d, ar, NULL, NULL, NULL);
}
}
@@ -493,7 +498,7 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
- DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
+ DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
rv3d->persp = RV3D_CAMOB;
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, v3d->camera);
@@ -541,6 +546,7 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
Object *camera_ob = v3d ? v3d->camera : scene->camera;
@@ -553,7 +559,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
}
/* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co, &r_scale)) {
+ if (BKE_camera_view_frame_fit_to_scene(scene, sl, camera_ob, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
@@ -570,7 +576,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
/* notifiers */
- DAG_id_tag_update(&camera_ob->id, OB_RECALC_OB);
+ DEG_id_tag_update(&camera_ob->id, OB_RECALC_OB);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
return OPERATOR_FINISHED;
}
@@ -727,40 +733,35 @@ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb,
}
}
-void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
+void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
{
- float modelview[4][4];
- double xs, ys, p[3];
- int val, flip_sign, a;
-
- /* near zero floating point values can give issues with gluUnProject
- * in side view on some implementations */
- if (fabs(mats->modelview[0]) < 1e-6) mats->modelview[0] = 0.0;
- if (fabs(mats->modelview[5]) < 1e-6) mats->modelview[5] = 0.0;
-
- /* Set up viewport so that gluUnProject will give correct values */
- mats->viewport[0] = 0;
- mats->viewport[1] = 0;
+ /* init in case unproject fails */
+ memset(bb->vec, 0, sizeof(bb->vec));
/* four clipping planes and bounding volume */
/* first do the bounding volume */
- for (val = 0; val < 4; val++) {
- xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
- ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
+ for (int val = 0; val < 4; val++) {
+ float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
+ float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
- gluUnProject(xs, ys, 0.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
- copy_v3fl_v3db(bb->vec[val], p);
+ ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
+ ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
+ }
- gluUnProject(xs, ys, 1.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
- copy_v3fl_v3db(bb->vec[4 + val], p);
+ /* optionally transform to object space */
+ if (ob) {
+ float imat[4][4];
+ invert_m4_m4(imat, ob->obmat);
+
+ for (int val = 0; val < 8; val++) {
+ mul_m4_v3(imat, bb->vec[val]);
+ }
}
/* verify if we have negative scale. doing the transform before cross
* product flips the sign of the vector compared to doing cross product
* before transform then, so we correct for that. */
- for (a = 0; a < 16; a++)
- ((float *)modelview)[a] = mats->modelview[a];
- flip_sign = is_negative_m4(modelview);
+ int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
@@ -836,7 +837,7 @@ float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2])
}
bool ED_view3d_depth_read_cached_normal(
- const ViewContext *vc, const bglMats *mats, const int mval[2],
+ const ViewContext *vc, const int mval[2],
float r_normal[3])
{
/* Note: we could support passing in a radius.
@@ -855,7 +856,7 @@ bool ED_view3d_depth_read_cached_normal(
const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs);
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (ED_view3d_depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
+ if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) {
depths_valid[i] = true;
}
}
@@ -897,21 +898,13 @@ bool ED_view3d_depth_read_cached_normal(
}
bool ED_view3d_depth_unproject(
- const ARegion *ar, const bglMats *mats,
+ const ARegion *ar,
const int mval[2], const double depth,
float r_location_world[3])
{
- double p[3];
- if (gluUnProject(
- (double)ar->winrct.xmin + mval[0] + 0.5,
- (double)ar->winrct.ymin + mval[1] + 0.5,
- depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
- &p[0], &p[1], &p[2]))
- {
- copy_v3fl_v3db(r_location_world, p);
- return true;
- }
- return false;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
}
/** \} */
@@ -1025,14 +1018,14 @@ void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect)
}
if (is_ortho) {
- wmOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ gpuOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
else {
- wmFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ gpuFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
/* update matrix in 3d view region */
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat);
+ gpuGetProjectionMatrix(rv3d->winmat);
}
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
@@ -1116,11 +1109,11 @@ bool ED_view3d_lock(RegionView3D *rv3d)
}
/* don't set windows active in here, is used by renderwin too */
-void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d)
+void view3d_viewmatrix_set(const EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d)
{
if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
if (v3d->camera) {
- BKE_object_where_is_calc(scene, v3d->camera);
+ BKE_object_where_is_calc(eval_ctx, scene, v3d->camera);
obmat_to_viewmat(rv3d, v3d->camera);
}
else {
@@ -1205,10 +1198,11 @@ void view3d_opengl_select_cache_end(void)
* \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
*/
int view3d_opengl_select(
- ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
+ const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
eV3DSelectMode select_mode)
{
struct bThemeState theme_state;
+ Depsgraph *graph = vc->depsgraph;
Scene *scene = vc->scene;
View3D *v3d = vc->v3d;
ARegion *ar = vc->ar;
@@ -1270,7 +1264,7 @@ int view3d_opengl_select(
/* Important we use the 'viewmat' and don't re-calculate since
* the object & bone view locking takes 'rect' into account, see: T51629. */
- ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
+ ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = true;
@@ -1282,7 +1276,16 @@ int view3d_opengl_select(
GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
- ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
+ }
+ else
+#else
+ {
+ DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ }
+#endif /* WITH_OPENGL_LEGACY */
hits = GPU_select_end();
@@ -1290,13 +1293,22 @@ int view3d_opengl_select(
if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
- ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
+ }
+ else
+#else
+ {
+ DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ }
+#endif /* WITH_OPENGL_LEGACY */
GPU_select_end();
}
G.f &= ~G_PICKSEL;
- ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
+ ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = 0;
@@ -1314,42 +1326,6 @@ finally:
return hits;
}
-/* ********************** local view operator ******************** */
-
-static unsigned int free_localbit(Main *bmain)
-{
- unsigned int lay;
- ScrArea *sa;
- bScreen *sc;
-
- lay = 0;
-
- /* sometimes we loose a localview: when an area is closed */
- /* check all areas: which localviews are in use? */
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl = sa->spacedata.first;
- for (; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *) sl;
- lay |= v3d->lay;
- }
- }
- }
- }
-
- if ((lay & 0x01000000) == 0) return 0x01000000;
- if ((lay & 0x02000000) == 0) return 0x02000000;
- if ((lay & 0x04000000) == 0) return 0x04000000;
- if ((lay & 0x08000000) == 0) return 0x08000000;
- if ((lay & 0x10000000) == 0) return 0x10000000;
- if ((lay & 0x20000000) == 0) return 0x20000000;
- if ((lay & 0x40000000) == 0) return 0x40000000;
- if ((lay & 0x80000000) == 0) return 0x80000000;
-
- return 0;
-}
-
int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
{
int i, tot = 0;
@@ -1388,267 +1364,6 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
return lay;
}
-static bool view3d_localview_init(
- wmWindowManager *wm, wmWindow *win,
- Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx,
- ReportList *reports)
-{
- View3D *v3d = sa->spacedata.first;
- Base *base;
- float min[3], max[3], box[3], mid[3];
- float size = 0.0f;
- unsigned int locallay;
- bool ok = false;
-
- if (v3d->localvd) {
- return ok;
- }
-
- INIT_MINMAX(min, max);
-
- locallay = free_localbit(bmain);
-
- if (locallay == 0) {
- BKE_report(reports, RPT_ERROR, "No more than 8 local views");
- ok = false;
- }
- else {
- if (scene->obedit) {
- BKE_object_minmax(scene->obedit, min, max, false);
-
- ok = true;
-
- BASACT->lay |= locallay;
- scene->obedit->lay = BASACT->lay;
- }
- else {
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
- BKE_object_minmax(base->object, min, max, false);
- base->lay |= locallay;
- base->object->lay = base->lay;
- ok = true;
- }
- }
- }
-
- sub_v3_v3v3(box, max, min);
- size = max_fff(box[0], box[1], box[2]);
- }
-
- if (ok == true) {
- ARegion *ar;
-
- v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
-
- memcpy(v3d->localvd, v3d, sizeof(View3D));
-
- mid_v3_v3v3(mid, min, max);
-
- copy_v3_v3(v3d->cursor, mid);
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
- bool ok_dist = true;
-
- /* new view values */
- Object *camera_old = NULL;
- float dist_new, ofs_new[3];
-
- rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
- memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
-
- negate_v3_v3(ofs_new, mid);
-
- if (rv3d->persp == RV3D_CAMOB) {
- rv3d->persp = RV3D_PERSP;
- camera_old = v3d->camera;
- }
-
- if (rv3d->persp == RV3D_ORTHO) {
- if (size < 0.0001f) {
- ok_dist = false;
- }
- }
-
- if (ok_dist) {
- dist_new = ED_view3d_radius_to_dist(v3d, ar, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
- if (rv3d->persp == RV3D_PERSP) {
- /* don't zoom closer than the near clipping plane */
- dist_new = max_ff(dist_new, v3d->near * 1.5f);
- }
- }
-
- ED_view3d_smooth_view_ex(
- wm, win, sa, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old,
- .ofs = ofs_new, .quat = rv3d->viewquat,
- .dist = ok_dist ? &dist_new : NULL, .lens = &v3d->lens});
- }
- }
-
- v3d->lay = locallay;
- }
- else {
- /* clear flags */
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->lay & locallay) {
- base->lay -= locallay;
- if (base->lay == 0) base->lay = v3d->layact;
- if (base->object != scene->obedit) base->flag |= SELECT;
- base->object->lay = base->lay;
- }
- }
- }
-
- DAG_on_visible_update(bmain, false);
-
- return ok;
-}
-
-static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
-{
- const bool free = true;
- ARegion *ar;
- View3D *v3d = sa->spacedata.first;
- Object *camera_old, *camera_new;
-
- if (v3d->localvd == NULL) return;
-
- camera_old = v3d->camera;
- camera_new = v3d->localvd->camera;
-
- v3d->lay = v3d->localvd->lay;
- v3d->layact = v3d->localvd->layact;
- v3d->drawtype = v3d->localvd->drawtype;
- v3d->camera = v3d->localvd->camera;
-
- if (free) {
- MEM_freeN(v3d->localvd);
- v3d->localvd = NULL;
- }
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->localvd) {
- Object *camera_old_rv3d, *camera_new_rv3d;
-
- camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
- camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
-
- rv3d->view = rv3d->localvd->view;
- rv3d->persp = rv3d->localvd->persp;
- rv3d->camzoom = rv3d->localvd->camzoom;
-
- ED_view3d_smooth_view_ex(
- wm, win, sa,
- v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old_rv3d, .camera = camera_new_rv3d,
- .ofs = rv3d->localvd->ofs, .quat = rv3d->localvd->viewquat,
- .dist = &rv3d->localvd->dist});
-
- if (free) {
- MEM_freeN(rv3d->localvd);
- rv3d->localvd = NULL;
- }
- }
-
- ED_view3d_shade_update(bmain, scene, v3d, sa);
- }
- }
-}
-
-static bool view3d_localview_exit(
- wmWindowManager *wm, wmWindow *win,
- Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
-{
- View3D *v3d = sa->spacedata.first;
- struct Base *base;
- unsigned int locallay;
-
- if (v3d->localvd) {
-
- locallay = v3d->lay & 0xFF000000;
-
- restore_localviewdata(wm, win, bmain, scene, sa, smooth_viewtx);
-
- /* for when in other window the layers have changed */
- if (v3d->scenelock) v3d->lay = scene->lay;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->lay & locallay) {
- base->lay -= locallay;
- if (base->lay == 0) base->lay = v3d->layact;
- if (base->object != scene->obedit) {
- base->flag |= SELECT;
- base->object->flag |= SELECT;
- }
- base->object->lay = base->lay;
- }
- }
-
- DAG_on_visible_update(bmain, false);
-
- return true;
- }
- else {
- return false;
- }
-}
-
-static int localview_exec(bContext *C, wmOperator *op)
-{
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = CTX_wm_view3d(C);
- bool changed;
-
- if (v3d->localvd) {
- changed = view3d_localview_exit(wm, win, bmain, scene, sa, smooth_viewtx);
- }
- else {
- changed = view3d_localview_init(wm, win, bmain, scene, sa, smooth_viewtx, op->reports);
- }
-
- if (changed) {
- DAG_id_type_tag(bmain, ID_OB);
- ED_area_tag_redraw(sa);
-
- /* unselected objects become selected when exiting */
- if (v3d->localvd == NULL) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
-}
-
-void VIEW3D_OT_localview(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Local View";
- ot->description = "Toggle display of selected object(s) separately and centered in view";
- ot->idname = "VIEW3D_OT_localview";
-
- /* api callbacks */
- ot->exec = localview_exec;
- ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
-
- ot->poll = ED_operator_view3d_active;
-}
-
#ifdef WITH_GAMEENGINE
static ListBase queue_back;
@@ -1687,7 +1402,6 @@ static void RestoreState(bContext *C, wmWindow *win)
win->queue = queue_back;
GPU_state_init();
- GPU_set_tpage(NULL, 0, 0);
glPopAttrib();
}
@@ -1730,10 +1444,6 @@ static void game_set_commmandline_options(GameData *gm)
SYS_WriteCommandLineInt(syshandle, "blender_material", test);
test = (gm->matmode == GAME_MAT_GLSL);
SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", test);
- test = (gm->flag & GAME_DISPLAY_LISTS);
- SYS_WriteCommandLineInt(syshandle, "displaylists", test);
-
-
}
}
@@ -1741,19 +1451,21 @@ static void game_set_commmandline_options(GameData *gm)
static int game_engine_poll(bContext *C)
{
- bScreen *screen;
+ const wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
+
/* we need a context and area to launch BGE
* it's a temporary solution to avoid crash at load time
* if we try to auto run the BGE. Ideally we want the
* context to be set as soon as we load the file. */
- if (CTX_wm_window(C) == NULL) return 0;
- if ((screen = CTX_wm_screen(C)) == NULL) return 0;
+ if (win == NULL) return 0;
+ if (CTX_wm_screen(C) == NULL) return 0;
if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)
return 0;
- if (!BKE_scene_uses_blender_game(screen->scene))
+ if (!BKE_scene_uses_blender_game(scene))
return 0;
return 1;
@@ -1862,7 +1574,7 @@ static int game_engine_exec(bContext *C, wmOperator *op)
//XXX restore_all_scene_cfra(scene_cfra_store);
BKE_scene_set_background(CTX_data_main(C), startscene);
- //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ //XXX BKE_scene_graph_update_for_newframe(bmain->eval_ctx, bmain, scene, depsgraph);
BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST);
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 9464f332d39..95390fe9065 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -56,6 +56,10 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "GPU_immediate.h"
+
+#include "RE_engine.h"
+
#include "view3d_intern.h" /* own include */
#ifdef WITH_INPUT_NDOF
@@ -246,6 +250,8 @@ typedef struct WalkInfo {
View3D *v3d;
ARegion *ar;
Scene *scene;
+ SceneLayer *scene_layer;
+ RenderEngineType *engine;
wmTimer *timer; /* needed for redraws */
@@ -337,24 +343,33 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a
yoff = walk->ar->winy / 2;
}
- UI_ThemeColor(TH_VIEW_OVERLAY);
- glBegin(GL_LINES);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+
+ immBegin(GWN_PRIM_LINES, 8);
+
/* North */
- glVertex2i(xoff, yoff + inner_length);
- glVertex2i(xoff, yoff + outter_length);
+ immVertex2i(pos, xoff, yoff + inner_length);
+ immVertex2i(pos, xoff, yoff + outter_length);
/* East */
- glVertex2i(xoff + inner_length, yoff);
- glVertex2i(xoff + outter_length, yoff);
+ immVertex2i(pos, xoff + inner_length, yoff);
+ immVertex2i(pos, xoff + outter_length, yoff);
/* South */
- glVertex2i(xoff, yoff - inner_length);
- glVertex2i(xoff, yoff - outter_length);
+ immVertex2i(pos, xoff, yoff - inner_length);
+ immVertex2i(pos, xoff, yoff - outter_length);
/* West */
- glVertex2i(xoff - inner_length, yoff);
- glVertex2i(xoff - outter_length, yoff);
- glEnd();
+ immVertex2i(pos, xoff - inner_length, yoff);
+ immVertex2i(pos, xoff - outter_length, yoff);
+
+ immEnd();
+ immUnbindProgram();
}
static void walk_update_header(bContext *C, wmOperator *op, WalkInfo *walk)
@@ -499,6 +514,8 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->v3d = CTX_wm_view3d(C);
walk->ar = CTX_wm_region(C);
walk->scene = CTX_data_scene(C);
+ walk->scene_layer = CTX_data_scene_layer(C);
+ walk->engine = CTX_data_engine(C);
#ifdef NDOF_WALK_DEBUG
puts("\n-- walk begin --");
@@ -587,11 +604,11 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
walk->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), walk->scene, 0,
+ CTX_data_main(C), walk->scene, walk->scene_layer, walk->engine, 0,
walk->ar, walk->v3d);
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
- walk->scene, walk->v3d, walk->rv3d,
+ C, walk->scene, walk->v3d, walk->rv3d,
(U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
/* center the mouse */