Support Vertex Color in GLSL viewport for Cycles
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 22 May 2016 16:24:53 +0000 (18:24 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 23 May 2016 08:23:43 +0000 (10:23 +0200)
The title says it all actually.

Added special custom data type, because we don't know in advance
whether we're referencing UV or Color layer. Also made it so vertex
attributes are normalized.

TODO: Border render in viewport ignores the normalization of the
attribute array for some reason, will be looked into still.

Reviewers: mont29, brecht, campbellbarton

Reviewed By: brecht, campbellbarton

Differential Revision: https://developer.blender.org/D2022

source/blender/blenkernel/intern/DerivedMesh.c
source/blender/gpu/intern/gpu_buffers.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/makesdna/DNA_customdata_types.h
source/blender/nodes/shader/nodes/node_shader_attribute.c

index 1bfc3d90730e400dc0bc210f5432a60c06658b59..9c500fad2ca9cdee61bd1b426315e9f5db6a6eff 100644 (file)
@@ -3629,12 +3629,41 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
                dm->calcLoopTangents(dm, false, (const char (*)[MAX_NAME])tangent_names, tangent_names_count);
 
        for (b = 0; b < gattribs->totlayer; b++) {
-               if (gattribs->layer[b].type == CD_MTFACE) {
+               int type = gattribs->layer[b].type;
+               layer = -1;
+               if (type == CD_AUTO_FROM_NAME) {
+                       /* We need to deduct what exact layer is used.
+                        *
+                        * We do it based on the specified name.
+                        */
+                       if (gattribs->layer[b].name[0]) {
+                               layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name);
+                               type = CD_TANGENT;
+                               if (layer == -1) {
+                                       layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name);
+                                       type = CD_MCOL;
+                               }
+                               if (layer == -1) {
+                                       layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name);
+                                       type = CD_MTFACE;
+                               }
+                               if (layer == -1) {
+                                       continue;
+                               }
+                       }
+                       else {
+                               /* Fall back to the UV layer, which matches old behavior. */
+                               type = CD_MTFACE;
+                       }
+               }
+               if (type == CD_MTFACE) {
                        /* uv coordinates */
-                       if (gattribs->layer[b].name[0])
-                               layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name);
-                       else
-                               layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
+                       if (layer == -1) {
+                               if (gattribs->layer[b].name[0])
+                                       layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name);
+                               else
+                                       layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
+                       }
 
                        a = attribs->tottface++;
 
@@ -3650,11 +3679,13 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
                        attribs->tface[a].gl_index = gattribs->layer[b].glindex;
                        attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
                }
-               else if (gattribs->layer[b].type == CD_MCOL) {
-                       if (gattribs->layer[b].name[0])
-                               layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name);
-                       else
-                               layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
+               else if (type == CD_MCOL) {
+                       if (layer == -1) {
+                               if (gattribs->layer[b].name[0])
+                                       layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name);
+                               else
+                                       layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
+                       }
 
                        a = attribs->totmcol++;
 
@@ -3670,13 +3701,14 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
 
                        attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
                }
-               else if (gattribs->layer[b].type == CD_TANGENT) {
+               else if (type == CD_TANGENT) {
                        /* note, even with 'is_editmesh' this uses the derived-meshes loop data */
-
-                       if (gattribs->layer[b].name[0])
-                               layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name);
-                       else
-                               layer = CustomData_get_active_layer_index(&dm->loopData, CD_TANGENT);
+                       if (layer == -1) {
+                               if (gattribs->layer[b].name[0])
+                                       layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name);
+                               else
+                                       layer = CustomData_get_active_layer_index(&dm->loopData, CD_TANGENT);
+                       }
 
                        a = attribs->tottang++;
 
@@ -3691,9 +3723,11 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
 
                        attribs->tang[a].gl_index = gattribs->layer[b].glindex;
                }
-               else if (gattribs->layer[b].type == CD_ORCO) {
+               else if (type == CD_ORCO) {
                        /* original coordinates */
-                       layer = CustomData_get_layer_index(vdata, CD_ORCO);
+                       if (layer == -1) {
+                               layer = CustomData_get_layer_index(vdata, CD_ORCO);
+                       }
                        attribs->totorco = 1;
 
                        if (layer != -1) {
index 072ff5235bfc268c59b8f7f5433713044e981ab3..09d0a383426f86d5ae4b0d5523f98e308024adbf 100644 (file)
@@ -823,7 +823,7 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda
        for (i = 0; i < numdata; i++) {
                glEnableVertexAttribArray(data[i].index);
                glVertexAttribPointer(data[i].index, data[i].size, data[i].type,
-                                        GL_FALSE, elementsize, BUFFER_OFFSET(offset));
+                                        GL_TRUE, elementsize, BUFFER_OFFSET(offset));
                offset += data[i].size * GPU_typesize(data[i].type);
                
                attribData[i].index = data[i].index;
index dcb888b1a9bbb5de6162789974ae8e15a42f811a..be7228b979a1b0f779708812b95d1a84c16008bf 100644 (file)
@@ -2573,11 +2573,11 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol)
 
 /* geometry */
 
-void node_attribute(vec3 attr_uv, out vec4 outcol, out vec3 outvec, out float outf)
+void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
 {
-       outcol = vec4(attr_uv, 1.0);
-       outvec = attr_uv;
-       outf = (attr_uv.x + attr_uv.y + attr_uv.z)/3.0;
+       outcol = vec4(attr, 1.0);
+       outvec = attr;
+       outf = (attr.x + attr.y + attr.z)/3.0;
 }
 
 void node_uvmap(vec3 attr_uv, out vec3 outvec)
index 3807bb296fd465bf0bc3d17b326d38c9fb524b46..2d1ffaa53eba1a708fae993948baa8e0eb164140 100644 (file)
@@ -75,6 +75,12 @@ typedef struct CustomData {
 
 /* CustomData.type */
 typedef enum CustomDataType {
+       /* Used by GLSL attributes in the cases when we need a delayed CD type
+        * assignment (in the cases when we don't know in advance which layer
+        * we are addressing).
+        */
+       CD_AUTO_FROM_NAME   = -1,
+
        CD_MVERT            = 0,
 #ifdef DNA_DEPRECATED
        CD_MSTICKY          = 1,  /* DEPRECATED */
index 61bdfb3dfd6ffad0471204a653c74bdf6f3ad54c..0a69593cf0773eda400bc9fead9e04e1affdcfa8 100644 (file)
@@ -45,9 +45,9 @@ static void node_shader_init_attribute(bNodeTree *UNUSED(ntree), bNode *node)
 static int node_shader_gpu_attribute(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
 {
        NodeShaderAttribute *attr = node->storage;
-       GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, attr->name);
+       GPUNodeLink *cd_attr = GPU_attribute(CD_AUTO_FROM_NAME, attr->name);
 
-       return GPU_stack_link(mat, "node_attribute", in, out, mtface);
+       return GPU_stack_link(mat, "node_attribute", in, out, cd_attr);
 }
 
 /* node type definition */