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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-12-08 02:03:49 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-12-08 02:03:49 +0400
commita5fb261016f0dd9a1393da4aadc76272a0c248b0 (patch)
tree473c21d434b885fd1b8e8eb8004f4242ff0a9d88 /source/blender/gpu
parent5310ee5e2cd4c16ff9dbdc205db1404982ad1551 (diff)
Fix #29520: issue drawing with VBO + GLSL + alpha pass. Includes some refactoring
to hopefully make alpha material drawing code more clear.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c57
2 files changed, 37 insertions, 22 deletions
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index dc1f80ca903..f73bd402167 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -69,7 +69,7 @@ void GPU_state_print(void);
* - after drawing, the material must be disabled again */
void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
- struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_pass);
+ struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_after);
void GPU_end_object_materials(void);
int GPU_enable_material(int nr, void *attribs);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index afd22fb70a0..3cd3cde8aad 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -942,7 +942,7 @@ static struct GPUMaterialState {
GPUBlendMode *alphablend;
GPUBlendMode alphablend_fixed[FIXEDMAT];
- int alphapass;
+ int use_alpha_pass, is_alpha_pass;
int lastmatnr, lastretval;
GPUBlendMode lastalphablend;
@@ -993,7 +993,7 @@ static Material *gpu_active_node_material(Material *ma)
return ma;
}
-void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
+void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_after)
{
Material *ma;
GPUMaterial *gpumat;
@@ -1015,9 +1015,15 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.gviewmat= rv3d->viewmat;
GMS.gviewinv= rv3d->viewinv;
- GMS.alphapass = (v3d && v3d->transp);
- if(do_alpha_pass)
- *do_alpha_pass = 0;
+ /* alpha pass setup. there's various cases to handle here:
+ * object transparency on: only solid materials draw in the first pass,
+ and only transparent in the second 'alpha' pass.
+ * object transparency off: for glsl we draw both in a single pass, and
+ for solid we don't use transparency at all. */
+ GMS.use_alpha_pass = (do_alpha_after != NULL);
+ GMS.is_alpha_pass = (v3d && v3d->transp);
+ if(GMS.use_alpha_pass)
+ *do_alpha_after = 0;
if(GMS.totmat > FIXEDMAT) {
GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf");
@@ -1064,20 +1070,23 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* fixed function opengl materials */
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
- alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
- if(do_alpha_pass && GMS.alphapass)
+ if(GMS.use_alpha_pass) {
GMS.matbuf[a].diff[3]= ma->alpha;
- else
+ alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+ }
+ else {
GMS.matbuf[a].diff[3]= 1.0f;
+ alphablend = GPU_BLEND_SOLID;
+ }
}
- /* setting do_alpha_pass = 1 indicates this object needs to be
+ /* setting do_alpha_after = 1 indicates this object needs to be
* drawn in a second alpha pass for improved blending */
- if(do_alpha_pass) {
- GMS.alphablend[a]= alphablend;
- if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT) && !GMS.alphapass)
- *do_alpha_pass= 1;
- }
+ if(GMS.use_alpha_pass && !GMS.is_alpha_pass)
+ if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
+ *do_alpha_after= 1;
+
+ GMS.alphablend[a]= alphablend;
}
/* let's start with a clean state */
@@ -1122,20 +1131,26 @@ int GPU_enable_material(int nr, void *attribs)
/* unbind glsl material */
if(GMS.gboundmat) {
- if(GMS.alphapass) glDepthMask(0);
+ if(GMS.is_alpha_pass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
GMS.gboundmat= NULL;
}
/* draw materials with alpha in alpha pass */
GMS.lastmatnr = nr;
- GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
- if(GMS.alphapass)
- GMS.lastretval = !GMS.lastretval;
+ GMS.lastretval = 1;
+
+ if(GMS.use_alpha_pass) {
+ GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
+ if(GMS.is_alpha_pass)
+ GMS.lastretval = !GMS.lastretval;
+ }
+ else
+ GMS.lastretval = !GMS.is_alpha_pass;
if(GMS.lastretval) {
/* for alpha pass, use alpha blend */
- alphablend = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID;
+ alphablend = GMS.alphablend[nr];
if(gattribs && GMS.gmatbuf[nr]) {
/* bind glsl material and get attributes */
@@ -1152,7 +1167,7 @@ int GPU_enable_material(int nr, void *attribs)
if(mat->game.alpha_blend != GPU_BLEND_SOLID)
alphablend= mat->game.alpha_blend;
- if(GMS.alphapass) glDepthMask(1);
+ if(GMS.is_alpha_pass) glDepthMask(1);
}
else {
/* or do fixed function opengl material */
@@ -1188,7 +1203,7 @@ void GPU_disable_material(void)
GMS.lastretval= 1;
if(GMS.gboundmat) {
- if(GMS.alphapass) glDepthMask(0);
+ if(GMS.is_alpha_pass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
GMS.gboundmat= NULL;
}