3D View: add Backface Culling option, to hide faces when seen from the back side,

found in the Display panel.

Patch by Simon Kirk and Irie Shinsuke, refactored to also work for non-mesh objects
and avoid globals.
This commit is contained in:
Brecht Van Lommel 2012-05-25 09:26:47 +00:00
parent 29e89dc996
commit 19dd66cf3b
5 changed files with 45 additions and 1 deletions

@ -2391,6 +2391,8 @@ class VIEW3D_PT_view3d_display(Panel):
col.prop(gs, "material_mode", text="")
col.prop(view, "show_textured_solid")
col.prop(view, "show_backface_culling")
layout.separator()
region = view.region_quadview

@ -3610,7 +3610,13 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
else if (ob->modifiers.first || obedit->modifiers.first) {}
else drawlinked = 1;
}
/* backface culling */
if (v3d->flag2 & V3D_BACKFACE_CULLING) {
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
if (ob == obedit || drawlinked) {
DerivedMesh *finalDM, *cageDM;
@ -3669,6 +3675,9 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
}
}
if (v3d->flag2 & V3D_BACKFACE_CULLING)
glDisable(GL_CULL_FACE);
return retval;
}
@ -3939,7 +3948,17 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
const short solid = (dt > OB_WIRE);
int retval = 0;
/* backface culling */
if(v3d->flag2 & V3D_BACKFACE_CULLING) {
/* not all displists use same in/out normal direction convention */
glEnable(GL_CULL_FACE);
glCullFace((ob->type == OB_MBALL) ? GL_BACK : GL_FRONT);
}
if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == 0) {
if (v3d->flag2 & V3D_BACKFACE_CULLING)
glDisable(GL_CULL_FACE);
return 0;
}
@ -4045,6 +4064,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
break;
}
if (v3d->flag2 & V3D_BACKFACE_CULLING)
glDisable(GL_CULL_FACE);
return retval;
}

@ -1017,6 +1017,8 @@ static struct GPUMaterialState {
float (*gviewmat)[4];
float (*gviewinv)[4];
int backface_culling;
GPUBlendMode *alphablend;
GPUBlendMode alphablend_fixed[FIXEDMAT];
int use_alpha_pass, is_alpha_pass;
@ -1085,6 +1087,8 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.lastretval = -1;
GMS.lastalphablend = GPU_BLEND_SOLID;
GMS.backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING);
GMS.gob = ob;
GMS.gscene = scene;
GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
@ -1248,6 +1252,13 @@ int GPU_enable_material(int nr, void *attribs)
alphablend= mat->game.alpha_blend;
if (GMS.is_alpha_pass) glDepthMask(1);
if (GMS.backface_culling) {
if(mat->game.flag)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
}
}
else {
/* or do fixed function opengl material */
@ -1283,6 +1294,9 @@ void GPU_disable_material(void)
GMS.lastretval= 1;
if (GMS.gboundmat) {
if (GMS.backface_culling)
glDisable(GL_CULL_FACE);
if (GMS.is_alpha_pass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
GMS.gboundmat= NULL;

@ -266,6 +266,7 @@ typedef struct View3D {
#define V3D_SHOW_RECONSTRUCTION 128
#define V3D_SHOW_CAMERAPATH 256
#define V3D_SHOW_BUNDLENAME 512
#define V3D_BACKFACE_CULLING 1024
/* View3D->around */
#define V3D_CENTER 0

@ -1567,6 +1567,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_backface_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_BACKFACE_CULLING);
RNA_def_property_ui_text(prop, "Backface Culling", "Use back face culling to hide the back side of faces");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "lock_camera", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_LOCK_CAMERA);
RNA_def_property_ui_text(prop, "Lock Camera to View", "Enable view navigation within the camera view");