Fix #32522: Object's diffuse color not showing in Sculpt Mode
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 23 Sep 2012 14:16:52 +0000 (14:16 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 23 Sep 2012 14:16:52 +0000 (14:16 +0000)
It was missing since sculpting mask implementation.

Now object's color would be multiplied by sculpt mask value.

For VBOs it's done by storing final color in VertexBufferFormat and
mimic behavior of setMaterial callback for getting current diffuse
color.

For non-VBOs diffuse color is getting from current OpenGL context.

source/blender/blenlib/intern/pbvh.c
source/blender/gpu/GPU_buffers.h
source/blender/gpu/GPU_draw.h
source/blender/gpu/intern/gpu_buffers.c
source/blender/gpu/intern/gpu_draw.c

index d3d8d371f60b9deb489fd3f448842394ef287822..0bd9e68cb71f1d19f92927b223f74e732004db7d 100644 (file)
@@ -1169,10 +1169,14 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
                                        break;
                                case PBVH_FACES:
                                        GPU_update_mesh_buffers(node->draw_buffers,
+                                                               bvh->faces,
+                                                               node->prim_indices,
+                                                               node->totprim,
                                                                bvh->verts,
                                                                node->vert_indices,
                                                                node->uniq_verts +
                                                                node->face_verts,
+                                                               node->face_vert_indices,
                                                                CustomData_get_layer(bvh->vdata,
                                                                                     CD_PAINT_MASK));
                                        break;
index 1729ac06f5a7358a31bcfa097cae65bfce6d765c..745ca1ef2acf6bbb11e698d5af93232e2d2f751c 100644 (file)
@@ -162,8 +162,9 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4],
                                     struct MFace *mface, struct MVert *mvert,
                                     int *face_indices, int totface);
 
-void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert,
-                             int *vert_indices, int totvert, const float *vmask);
+void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MFace *mface, int *face_indices, int totface,
+                             struct MVert *mvert, int *vert_indices, int totvert,
+                             int (*face_vert_indices)[4], const float *vmask);
 
 GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
                                     unsigned int **grid_hidden, int gridsize);
index 285acb6bdde324395e6ba85598bfd6129357827c..7d829bd57bfd4d5c73f0fa8d564214f128be0664 100644 (file)
@@ -75,6 +75,8 @@ void GPU_end_object_materials(void);
 int GPU_enable_material(int nr, void *attribs);
 void GPU_disable_material(void);
 
+void GPU_material_diffuse_get(int nr, float diff[4]);
+
 void GPU_set_material_alpha_blend(int alphablend);
 int GPU_get_material_alpha_blend(void);
 
index c44a181841ef1c6291849e6d7ae791635f77edb0..930573ec750fa81427844a676d6bba9934f976ca 100644 (file)
@@ -54,6 +54,7 @@
 #include "DNA_userdef_types.h"
 
 #include "GPU_buffers.h"
+#include "GPU_draw.h"
 
 typedef enum {
        GPU_BUFFER_VERTEX_STATE = 1,
@@ -1280,6 +1281,8 @@ typedef struct {
        char pad[2];
        
        unsigned char color[3];
+       float accum_color[3];
+       int tot_color;
 } VertexBufferFormat;
 
 struct GPU_Buffers {
@@ -1327,24 +1330,24 @@ static void gpu_colors_disable(VBO_State vbo_state)
 
 static float gpu_color_from_mask(float mask)
 {
-       return (1.0f - mask) * 0.5f + 0.25f;
+       return 1.0f - mask;
 }
 
-static void gpu_color_from_mask_copy(float mask, unsigned char out[3])
+static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3])
 {
-       unsigned char color;
-       
-       color = gpu_color_from_mask(mask) * 255.0f;
+       float mask_color;
+
+       mask_color = gpu_color_from_mask(mask) * 255.0f;
 
-       out[0] = color;
-       out[1] = color;
-       out[2] = color;
+       out[0] = diffuse_color[0] * mask_color;
+       out[1] = diffuse_color[1] * mask_color;
+       out[2] = diffuse_color[2] * mask_color;
 }
 
-static void gpu_color_from_mask_set(float mask)
+static void gpu_color_from_mask_set(float mask, float diffuse_color[4])
 {
        float color = gpu_color_from_mask(mask);
-       glColor3f(color, color, color);
+       glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
 }
 
 static float gpu_color_from_mask_quad(const CCGKey *key,
@@ -1360,29 +1363,32 @@ static float gpu_color_from_mask_quad(const CCGKey *key,
 static void gpu_color_from_mask_quad_copy(const CCGKey *key,
                                           CCGElem *a, CCGElem *b,
                                           CCGElem *c, CCGElem *d,
+                                          const float *diffuse_color,
                                           unsigned char out[3])
 {
-       unsigned char color =
+       float mask_color =
            gpu_color_from_mask((*CCG_elem_mask(key, a) +
                                 *CCG_elem_mask(key, b) +
                                 *CCG_elem_mask(key, c) +
                                 *CCG_elem_mask(key, d)) * 0.25f) * 255.0f;
 
-       out[0] = color;
-       out[1] = color;
-       out[2] = color;
+       out[0] = diffuse_color[0] * mask_color;
+       out[1] = diffuse_color[1] * mask_color;
+       out[2] = diffuse_color[2] * mask_color;
 }
 
 static void gpu_color_from_mask_quad_set(const CCGKey *key,
                                          CCGElem *a, CCGElem *b,
-                                         CCGElem *c, CCGElem *d)
+                                         CCGElem *c, CCGElem *d,
+                                         float diffuse_color[4])
 {
        float color = gpu_color_from_mask_quad(key, a, b, c, d);
-       glColor3f(color, color, color);
+       glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
 }
 
-void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
-                             int *vert_indices, int totvert, const float *vmask)
+void GPU_update_mesh_buffers(GPU_Buffers *buffers, MFace *mface, int *face_indices, int totface,
+                             MVert *mvert, int *vert_indices, int totvert,
+                             int (*face_vert_indices)[4], const float *vmask)
 {
        VertexBufferFormat *vert_data;
        int i;
@@ -1404,8 +1410,40 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
 
                                copy_v3_v3(out->co, v->co);
                                memcpy(out->no, v->no, sizeof(short) * 3);
-                               gpu_color_from_mask_copy(vmask[vert_indices[i]],
-                                                        out->color);
+                               zero_v3(out->accum_color);
+                               out->tot_color = 0;
+                       }
+
+#define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
+                       { \
+                               VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
+                               add_v3_v3(out->accum_color, diffuse_color);     \
+                               out->tot_color++; \
+                       } (void)0
+
+                       for (i = 0; i < totface; ++i) {
+                               MFace *f = mface + face_indices[i];
+                               float diffuse_color[4];
+
+                               GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+
+                               UPDATE_VERTEX(i, f->v1, 0, diffuse_color);
+                               UPDATE_VERTEX(i, f->v2, 1, diffuse_color);
+                               UPDATE_VERTEX(i, f->v3, 2, diffuse_color);
+                               if (f->v4)
+                                       UPDATE_VERTEX(i, f->v4, 3, diffuse_color);
+                       }
+#undef UPDATE_VERTEX
+
+                       for (i = 0; i < totvert; ++i) {
+                               VertexBufferFormat *out = vert_data + i;
+                               if (out->tot_color) {
+                                       float diffuse_color[4];
+
+                                       mul_v3_v3fl(diffuse_color, out->accum_color, 1.0f / out->tot_color);
+
+                                       gpu_color_from_mask_copy(vmask[vert_indices[i]], diffuse_color, out->color);
+                               }
                        }
 
                        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
@@ -1517,6 +1555,10 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
                        for (i = 0; i < totgrid; ++i) {
                                VertexBufferFormat *vd = vert_data;
                                CCGElem *grid = grids[grid_indices[i]];
+                               const DMFlagMat *flags = &grid_flag_mats[grid_indices[i]];
+                               float diffuse_color[4];
+
+                               GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
 
                                for (y = 0; y < key->grid_size; y++) {
                                        for (x = 0; x < key->grid_size; x++) {
@@ -1524,11 +1566,9 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
                                                
                                                copy_v3_v3(vd->co, CCG_elem_co(key, elem));
                                                if (smooth) {
-                                                       normal_float_to_short_v3(vd->no,
-                                                                                CCG_elem_no(key, elem));
+                                                       normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
 
-                                                       gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
-                                                                                vd->color);
+                                                       gpu_color_from_mask_copy(*CCG_elem_mask(key, elem), diffuse_color, vd->color);
                                                }
                                                vd++;
                                        }
@@ -1561,6 +1601,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
                                                                                      elems[1],
                                                                                      elems[2],
                                                                                      elems[3],
+                                                                                     diffuse_color,
                                                                                      vd->color);
                                                }
                                        }
@@ -1769,6 +1810,9 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
 {
        const MVert *mvert = buffers->mvert;
        int i, j;
+       float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+       glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color);
 
        gpu_colors_enable(VBO_DISABLED);
 
@@ -1784,7 +1828,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
 
                if (smooth) {
                        for (j = 0; j < S; j++) {
-                               gpu_color_from_mask_set(buffers->vmask[fv[j]]);
+                               gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color);
                                glNormal3sv(mvert[fv[j]].no);
                                glVertex3fv(mvert[fv[j]].co);
                        }
@@ -1809,7 +1853,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
                                fmask = (fmask + buffers->vmask[fv[3]]) * 0.25;
                        else
                                fmask /= 3.0f;
-                       gpu_color_from_mask_set(fmask);
+                       gpu_color_from_mask_set(fmask, diffuse_color);
                        
                        for (j = 0; j < S; j++)
                                glVertex3fv(mvert[fv[j]].co);
@@ -1825,6 +1869,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
 {
        const CCGKey *key = &buffers->gridkey;
        int i, j, x, y, gridsize = buffers->gridkey.grid_size;
+       float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+       glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color);
 
        gpu_colors_enable(VBO_DISABLED);
 
@@ -1853,7 +1900,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
 
                                        if (smooth) {
                                                for (j = 0; j < 4; j++) {
-                                                       gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]));
+                                                       gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color);
                                                        glNormal3fv(CCG_elem_no(key, e[j]));
                                                        glVertex3fv(CCG_elem_co(key, e[j]));
                                                }
@@ -1866,7 +1913,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                                               CCG_elem_co(key, e[2]),
                                                               CCG_elem_co(key, e[3]));
                                                glNormal3fv(fno);
-                                               gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]);
+                                               gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color);
 
                                                for (j = 0; j < 4; j++)
                                                        glVertex3fv(CCG_elem_co(key, e[j]));
@@ -1883,10 +1930,10 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                        CCGElem *a = CCG_grid_elem(key, grid, x, y);
                                        CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
 
-                                       gpu_color_from_mask_set(*CCG_elem_mask(key, a));
+                                       gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color);
                                        glNormal3fv(CCG_elem_no(key, a));
                                        glVertex3fv(CCG_elem_co(key, a));
-                                       gpu_color_from_mask_set(*CCG_elem_mask(key, b));
+                                       gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color);
                                        glNormal3fv(CCG_elem_no(key, b));
                                        glVertex3fv(CCG_elem_co(key, b));
                                }
@@ -1912,7 +1959,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                                               CCG_elem_co(key, c));
                                                glNormal3fv(fno);
 
-                                               gpu_color_from_mask_quad_set(key, a, b, c, d);
+                                               gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color);
                                        }
 
                                        glVertex3fv(CCG_elem_co(key, a));
index 962bb0aed2288d0662412ae582cb09b135d98f42..60e3c19a4198c1a40ac72dc67b3a7d79bfa1e335 100644 (file)
@@ -1440,6 +1440,21 @@ void GPU_disable_material(void)
        GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
 }
 
+void GPU_material_diffuse_get(int nr, float diff[4])
+{
+       /* prevent index to use un-initialized array items */
+       if (nr >= GMS.totmat)
+               nr = 0;
+
+       /* no GPU_begin_object_materials, use default material */
+       if (!GMS.matbuf) {
+               mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit);
+       }
+       else {
+               copy_v4_v4(diff, GMS.matbuf[nr].diff);
+       }
+}
+
 void GPU_end_object_materials(void)
 {
        GPU_disable_material();