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:
authorTon Roosendaal <ton@blender.org>2008-12-19 15:14:58 +0300
committerTon Roosendaal <ton@blender.org>2008-12-19 15:14:58 +0300
commitd92b45d558b861ef3c314f1d9c926113aa36326c (patch)
treed057b1bf627026fc1bbecec74e4625ed737d5229 /source/blender/editors/space_view3d/view3d_draw.c
parentc752ec9fc458f6fd1fc0ae7a156d33bf86e73eff (diff)
2.5
Drawing code for space_view3d module. It's still not cleaned, have to check on context usage still. Also missing is editmodes, armatures, and probably more. Known issue: splitting to 2nd window gives bad opengl lighting. Picture for fun: http://www.blender.org/bf/rt2.jpg Current stat: brought back almost 10k lines! :)
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c385
1 files changed, 371 insertions, 14 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 712a69be77b..d03681d6a59 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -33,6 +33,7 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
+#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
@@ -72,12 +73,16 @@
#include "ED_screen.h"
#include "ED_util.h"
+#include "ED_types.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "GPU_draw.h"
+#include "GPU_material.h"
+
#include "view3d_intern.h" // own include
@@ -1145,6 +1150,178 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
// XXX areawinset(ar->win); // restore viewport / scissor
}
+/* ****************** View3d afterdraw *************** */
+
+typedef struct View3DAfter {
+ struct View3DAfter *next, *prev;
+ struct Base *base;
+ int type, flag;
+} View3DAfter;
+
+/* temp storage of Objects that need to be drawn as last */
+void add_view3d_after(View3D *v3d, Base *base, int type, int flag)
+{
+ View3DAfter *v3da= MEM_callocN(sizeof(View3DAfter), "View 3d after");
+
+ BLI_addtail(&v3d->afterdraw, v3da);
+ v3da->base= base;
+ v3da->type= type;
+ v3da->flag= flag;
+}
+
+/* clears zbuffer and draws it over */
+static void view3d_draw_xray(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, int clear)
+{
+ View3DAfter *v3da, *next;
+ int doit= 0;
+
+ for(v3da= v3d->afterdraw.first; v3da; v3da= v3da->next)
+ if(v3da->type==V3D_XRAY) doit= 1;
+
+ if(doit) {
+ if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT);
+ v3d->xray= TRUE;
+
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_XRAY) {
+ draw_object(C, scene, ar, v3d, v3da->base, v3da->flag);
+ BLI_remlink(&v3d->afterdraw, v3da);
+ MEM_freeN(v3da);
+ }
+ }
+ v3d->xray= FALSE;
+ }
+}
+
+/* disables write in zbuffer and draws it over */
+static void view3d_draw_transp(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
+{
+ View3DAfter *v3da, *next;
+
+ glDepthMask(0);
+ v3d->transp= TRUE;
+
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_TRANSP) {
+ draw_object(C, scene, ar, v3d, v3da->base, v3da->flag);
+ BLI_remlink(&v3d->afterdraw, v3da);
+ MEM_freeN(v3da);
+ }
+ }
+ v3d->transp= FALSE;
+
+ glDepthMask(1);
+
+}
+
+/* *********************** */
+
+/*
+ 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
+ */
+static void draw_dupli_objects_color(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, Base *base, int color)
+{
+ ListBase *lb;
+ DupliObject *dob;
+ Base tbase;
+ BoundBox *bb= NULL;
+ GLuint displist=0;
+ short transflag, use_displist= -1; /* -1 is initialize */
+ char dt, dtx;
+
+ if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
+
+ tbase.flag= OB_FROMDUPLI|base->flag;
+ lb= object_duplilist(scene, base->object);
+
+ for(dob= lb->first; dob; dob= dob->next) {
+ if(dob->no_draw);
+ else {
+ tbase.object= dob->ob;
+
+ /* 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;
+
+ /* negative scale flag has to propagate */
+ transflag= tbase.object->transflag;
+ if(base->object->transflag & OB_NEG_SCALE)
+ tbase.object->transflag ^= OB_NEG_SCALE;
+
+ UI_ThemeColorBlend(color, TH_BACK, 0.5);
+
+ /* generate displist, test for new object */
+ if(use_displist==1 && dob->prev && dob->prev->ob!=dob->ob) {
+ use_displist= -1;
+ glDeleteLists(displist, 1);
+ }
+ /* generate displist */
+ if(use_displist == -1) {
+
+ /* lamp drawing messes with matrices, could be handled smarter... but this works */
+ if(dob->ob->type==OB_LAMP || dob->type==OB_DUPLIGROUP)
+ use_displist= 0;
+ else {
+ /* disable boundbox check for list creation */
+ object_boundbox_flag(dob->ob, OB_BB_DISABLED, 1);
+ /* need this for next part of code */
+ bb= object_get_boundbox(dob->ob);
+
+ Mat4One(dob->ob->obmat); /* obmat gets restored */
+
+ displist= glGenLists(1);
+ glNewList(displist, GL_COMPILE);
+ draw_object(C, scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
+ glEndList();
+
+ use_displist= 1;
+ object_boundbox_flag(dob->ob, OB_BB_DISABLED, 0);
+ }
+ }
+ if(use_displist) {
+ wmMultMatrix(CTX_wm_window(C), dob->mat);
+ if(boundbox_clip(v3d, dob->mat, bb))
+ glCallList(displist);
+ wmLoadMatrix(CTX_wm_window(C), v3d->viewmat);
+ }
+ else {
+ Mat4CpyMat4(dob->ob->obmat, dob->mat);
+ draw_object(C, scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
+ }
+
+ tbase.object->dt= dt;
+ tbase.object->dtx= dtx;
+ tbase.object->transflag= transflag;
+ }
+ }
+
+ /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
+
+ free_object_duplilist(lb); /* does restore */
+
+ if(use_displist)
+ glDeleteLists(displist, 1);
+}
+
+static void draw_dupli_objects(const bContext *C, Scene *scene, 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 & 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(C, scene, ar, v3d, base, color);
+}
+
+
void view3d_update_depths(ARegion *ar, View3D *v3d)
{
/* Create storage for, and, if necessary, copy depth buffer */
@@ -1174,7 +1351,7 @@ void view3d_update_depths(ARegion *ar, View3D *v3d)
}
/* Enable sculpting in wireframe mode by drawing sculpt object only to the depth buffer */
-static void draw_sculpt_depths(Scene *scene, View3D *v3d)
+static void draw_sculpt_depths(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
{
Object *ob = OBACT;
@@ -1193,7 +1370,7 @@ static void draw_sculpt_depths(Scene *scene, View3D *v3d)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST);
-// XXX draw_object(BASACT, 0);
+ draw_object(C, scene, ar, v3d, BASACT, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if(!depth_on)
glDisable(GL_DEPTH_TEST);
@@ -1204,6 +1381,185 @@ static void draw_sculpt_depths(Scene *scene, View3D *v3d)
}
}
+void draw_depth(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *))
+{
+ Base *base;
+ Scene *sce;
+ short zbuf, flag;
+ float glalphaclip;
+ /* temp set drawtype to solid */
+
+ /* Setting these temporarily is not nice */
+ zbuf = v3d->zbuf;
+ flag = v3d->flag;
+ glalphaclip = U.glalphaclip;
+
+ U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */
+ v3d->flag &= ~V3D_SELECT_OUTLINE;
+
+ setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL); /* 0= no pick rect */
+ setviewmatrixview3d(v3d); /* note: calls where_is_object for camera... */
+
+ Mat4MulMat4(v3d->persmat, v3d->viewmat, v3d->winmat);
+ Mat4Invert(v3d->persinv, v3d->persmat);
+ Mat4Invert(v3d->viewinv, v3d->viewmat);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ wmLoadMatrix(CTX_wm_window(C), v3d->viewmat);
+// persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls
+
+ if(v3d->flag & V3D_CLIPPING) {
+ view3d_set_clipping(v3d);
+ }
+
+ v3d->zbuf= TRUE;
+ glEnable(GL_DEPTH_TEST);
+
+ /* draw set first */
+ if(scene->set) {
+ for(SETLOOPER(scene->set, base)) {
+ if(v3d->lay & base->lay) {
+ if (func == NULL || func(base)) {
+ draw_object(C, scene, ar, v3d, base, 0);
+ if(base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(C, scene, ar, v3d, base, TH_WIRE);
+ }
+ }
+ }
+ }
+ }
+
+ for(base= scene->base.first; base; base= base->next) {
+ if(v3d->lay & base->lay) {
+ if (func == NULL || func(base)) {
+ /* dupli drawing */
+ if(base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(C, scene, ar, v3d, base);
+ }
+ draw_object(C, scene, ar, v3d, base, 0);
+ }
+ }
+ }
+
+ /* this isnt that nice, draw xray objects as if they are normal */
+ if (v3d->afterdraw.first) {
+ View3DAfter *v3da, *next;
+ int num = 0;
+ v3d->xray= TRUE;
+
+ glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_XRAY) {
+ draw_object(C, scene, ar, v3d, v3da->base, 0);
+ num++;
+ }
+ /* dont remove this time */
+ }
+ v3d->xray= FALSE;
+
+ glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_XRAY) {
+ v3d->xray= TRUE; v3d->transp= FALSE;
+ } else if (v3da->type==V3D_TRANSP) {
+ v3d->xray= FALSE; v3d->transp= TRUE;
+ }
+
+ draw_object(C, scene, ar, v3d, v3da->base, 0); /* Draw Xray or Transp objects normally */
+ BLI_remlink(&v3d->afterdraw, v3da);
+ MEM_freeN(v3da);
+ }
+ v3d->xray= FALSE;
+ v3d->transp= FALSE;
+ }
+
+ v3d->zbuf = zbuf;
+ U.glalphaclip = glalphaclip;
+ v3d->flag = flag;
+}
+
+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], ListBase *shadows)
+{
+ GPULamp *lamp;
+ View3DShadow *shadow;
+
+ lamp = GPU_lamp_from_blender(scene, ob, par);
+
+ if(lamp) {
+ GPU_lamp_update(lamp, ob->lay, obmat);
+
+ if((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) {
+ shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow");
+ shadow->lamp = lamp;
+ BLI_addtail(shadows, shadow);
+ }
+ }
+}
+
+static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
+{
+ ListBase shadows;
+ View3DShadow *shadow;
+ Scene *sce;
+ Base *base;
+ Object *ob;
+
+ shadows.first= shadows.last= NULL;
+
+ /* update lamp transform and gather shadow lamps */
+ for(SETLOOPER(scene, base)) {
+ ob= base->object;
+
+ if(ob->type == OB_LAMP)
+ gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, &shadows);
+
+ if (ob->transflag & OB_DUPLI) {
+ DupliObject *dob;
+ ListBase *lb = object_duplilist(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, &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(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;
+
+ drawtype= v3d->drawtype;
+ lay= v3d->lay;
+ flag2= v3d->flag2 & V3D_SOLID_TEX;
+
+ v3d->drawtype = OB_SOLID;
+ v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
+ v3d->flag2 &= ~V3D_SOLID_TEX;
+
+ GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
+// XXX drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1);
+ GPU_lamp_shadow_buffer_unbind(shadow->lamp);
+
+ v3d->drawtype= drawtype;
+ v3d->lay= lay;
+ v3d->flag2 |= flag2;
+ }
+
+ BLI_freelistN(&shadows);
+}
+
void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
{
@@ -1228,8 +1584,8 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
}
/* shadow buffers, before we setup matrices */
-// if(draw_glsl_material(NULL, v3d->drawtype))
-// gpu_update_lamps_shadows(scene, v3d);
+ if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
+ gpu_update_lamps_shadows(scene, v3d);
setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL); /* 0= no pick rect */
setviewmatrixview3d(v3d); /* note: calls where_is_object for camera... */
@@ -1319,10 +1675,10 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
if(v3d->lay & base->lay) {
UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
-// XXX draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET);
+ draw_object(C, scene, ar, v3d, base, DRAW_CONSTCOLOR|DRAW_SCENESET);
if(base->object->transflag & OB_DUPLI) {
-// XXX draw_dupli_objects_color(v3d, base, TH_WIRE);
+ draw_dupli_objects_color(C, scene, ar, v3d, base, TH_WIRE);
}
}
}
@@ -1336,10 +1692,11 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
/* dupli drawing */
if(base->object->transflag & OB_DUPLI) {
-// XXX draw_dupli_objects(v3d, base);
+ draw_dupli_objects(C, scene, ar, v3d, base);
}
if((base->flag & SELECT)==0) {
-// XXX if(base->object!=G.obedit) draw_object(base, 0);
+ if(base->object!=G.obedit)
+ draw_object(C, scene, ar, v3d, base, 0);
}
}
}
@@ -1352,14 +1709,14 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
/* draw selected and editmode */
for(base= scene->base.first; base; base= base->next) {
if(v3d->lay & base->lay) {
-// if (base->object==G.obedit || ( base->flag & SELECT) )
-// XXX draw_object(base, 0);
+ if (base->object==G.obedit || ( base->flag & SELECT) )
+ draw_object(C, scene, ar, v3d, base, 0);
}
}
if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) {
if(G.f & G_SCULPTMODE)
- draw_sculpt_depths(scene, v3d);
+ draw_sculpt_depths(C, scene, ar, v3d);
view3d_update_depths(ar, v3d);
}
@@ -1375,12 +1732,12 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
// if(scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID);
/* Transp and X-ray afterdraw stuff */
-// view3d_draw_transp(v3d);
-// view3d_draw_xray(v3d, 1); // clears zbuffer if it is used!
+ view3d_draw_transp(C, scene, ar, v3d);
+ view3d_draw_xray(C, scene, ar, v3d, 1); // clears zbuffer if it is used!
if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) {
if(G.f & G_SCULPTMODE)
- draw_sculpt_depths(scene, v3d);
+ draw_sculpt_depths(C, scene, ar, v3d);
view3d_update_depths(ar, v3d);
}