diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 5 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 3 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 3 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_vertex.glsl | 52 |
12 files changed, 95 insertions, 8 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 2b13a847e14..8ccc4a6eb0e 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -757,22 +757,22 @@ void DM_update_weight_mcol( typedef struct DMVertexAttribs { struct { struct MLoopUV *array; - int em_offset, gl_index, gl_texco; + int em_offset, gl_index, gl_texco, gl_info_index; } tface[MAX_MTFACE]; struct { struct MLoopCol *array; - int em_offset, gl_index; + int em_offset, gl_index, gl_info_index; } mcol[MAX_MCOL]; struct { float (*array)[4]; - int em_offset, gl_index; + int em_offset, gl_index, gl_info_index; } tang[MAX_MTFACE]; struct { float (*array)[3]; - int em_offset, gl_index, gl_texco; + int em_offset, gl_index, gl_texco, gl_info_index; } orco; int tottface, totmcol, tottang, totorco; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index bb5cc9cb067..0de0e4d7797 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -3673,6 +3673,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->tface[a].gl_index = gattribs->layer[b].glindex; + attribs->tface[a].gl_info_index = gattribs->layer[b].glinfoindoex; attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } else if (type == CD_MCOL) { @@ -3696,6 +3697,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->mcol[a].gl_index = gattribs->layer[b].glindex; + attribs->mcol[a].gl_info_index = gattribs->layer[b].glinfoindoex; } else if (type == CD_TANGENT) { /* note, even with 'is_editmesh' this uses the derived-meshes loop data */ @@ -3718,6 +3720,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->tang[a].gl_index = gattribs->layer[b].glindex; + attribs->tang[a].gl_info_index = gattribs->layer[b].glinfoindoex; } else if (type == CD_ORCO) { /* original coordinates */ @@ -3737,6 +3740,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, attribs->orco.gl_index = gattribs->layer[b].glindex; attribs->orco.gl_texco = gattribs->layer[b].gltexco; + attribs->orco.gl_info_index = gattribs->layer[b].glinfoindoex; } } } @@ -3765,6 +3769,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, glTexCoord3fv(orco); else glVertexAttrib3fv(attribs->orco.gl_index, orco); + glUniform1i(attribs->orco.gl_info_index, 0); } /* uv texture coordinates */ @@ -3783,6 +3788,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, glTexCoord2fv(uv); else glVertexAttrib2fv(attribs->tface[b].gl_index, uv); + glUniform1i(attribs->tface[b].gl_info_index, 0); } /* vertex colors */ @@ -3798,6 +3804,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, } glVertexAttrib4fv(attribs->mcol[b].gl_index, col); + glUniform1i(attribs->mcol[b].gl_info_index, GPU_ATTR_INFO_SRGB); } /* tangent for normal mapping */ @@ -3807,6 +3814,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, const float *tang = (array) ? array[a * 4 + vert] : zero; glVertexAttrib4fv(attribs->tang[b].gl_index, tang); } + glUniform1i(attribs->tang[b].gl_info_index, 0); } } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index af1ad4900b3..e7e6118813e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1032,6 +1032,7 @@ static void cdDM_drawMappedFacesGLSL( if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; matconv[a].datatypes[numdata].size = 3; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -1039,6 +1040,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.tottface; b++) { if (matconv[a].attribs.tface[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; matconv[a].datatypes[numdata].size = 2; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -1047,6 +1049,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.totmcol; b++) { if (matconv[a].attribs.mcol[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; @@ -1055,6 +1058,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.tottang; b++) { if (matconv[a].attribs.tang[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 6c117447664..0de4d1b4dd5 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -57,6 +57,7 @@ #include "MEM_guardedalloc.h" #include "GPU_glew.h" +#include "GPU_buffers.h" #include "GPU_shader.h" #include "GPU_basic_shader.h" @@ -1431,6 +1432,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B glTexCoord3fv(orco); else glVertexAttrib3fv(attribs->orco.gl_index, orco); + glUniform1i(attribs->orco.gl_info_index, 0); } for (i = 0; i < attribs->tottface; i++) { const float *uv; @@ -1447,6 +1449,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B glTexCoord2fv(uv); else glVertexAttrib2fv(attribs->tface[i].gl_index, uv); + glUniform1i(attribs->tface[i].gl_info_index, 0); } for (i = 0; i < attribs->totmcol; i++) { GLubyte col[4]; @@ -1458,6 +1461,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; } glVertexAttrib4ubv(attribs->mcol[i].gl_index, col); + glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB); } for (i = 0; i < attribs->tottang; i++) { @@ -1469,6 +1473,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B tang = zero; } glVertexAttrib4fv(attribs->tang[i].gl_index, tang); + glUniform1i(attribs->tang[i].gl_info_index, 0); } } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 5fd418fadfc..88bc3fb9854 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2996,6 +2996,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; matconv[a].datatypes[numdata].size = 3; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -3003,6 +3004,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.tottface; b++) { if (matconv[a].attribs.tface[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; matconv[a].datatypes[numdata].size = 2; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -3011,6 +3013,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.totmcol; b++) { if (matconv[a].attribs.mcol[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; @@ -3019,6 +3022,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.tottang; b++) { if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index a8656c05224..ee7abe08aba 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -147,6 +147,7 @@ typedef struct GPUVertPointLink { /* used for GLSL materials */ typedef struct GPUAttrib { int index; + int info_index; int size; int type; } GPUAttrib; @@ -179,6 +180,10 @@ typedef enum { GPU_BINDING_INDEX = 1, } GPUBindingType; +typedef enum { + GPU_ATTR_INFO_SRGB = (1 << 0), +} GPUAttrInfo; + /* called before drawing */ void GPU_vertex_setup(struct DerivedMesh *dm); void GPU_normal_setup(struct DerivedMesh *dm); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 4c674b460aa..762329ee077 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -104,6 +104,7 @@ typedef struct GPUVertexAttribs { struct { int type; int glindex; + int glinfoindoex; int gltexco; int attribid; char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 09d0a383426..f80ce3c1fab 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -822,6 +822,12 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda for (i = 0; i < numdata; i++) { glEnableVertexAttribArray(data[i].index); + int info = 0; + if (data[i].type == GL_UNSIGNED_BYTE) { + info |= GPU_ATTR_INFO_SRGB; + } + glUniform1i(data[i].info_index, info); + glVertexAttribPointer(data[i].index, data[i].size, data[i].type, GL_TRUE, elementsize, BUFFER_OFFSET(offset)); offset += data[i].size * GPU_typesize(data[i].type); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 94d52c3617c..58ef4063430 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -749,6 +749,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "%s %s att%d;\n", GLEW_VERSION_3_0 ? "in" : "attribute", GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf(ds, "uniform int att%d_info;\n", input->attribid); BLI_dynstr_appendf(ds, "%s %s var%d;\n", GLEW_VERSION_3_0 ? "out" : "varying", GPU_DATATYPE_STR[input->type], input->attribid); @@ -801,7 +802,8 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); } #endif - BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid); + BLI_dynstr_appendf(ds, "\tset_var_from_attr(att%d, att%d_info, var%d);\n", + input->attribid, input->attribid, input->attribid); #ifdef WITH_OPENSUBDIV if (is_mtface) { BLI_dynstr_appendf(ds, "#endif\n"); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index aaa52b2c3f6..99ecf687f70 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -212,6 +212,9 @@ static void gpu_material_set_attrib_id(GPUMaterial *material) BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid); attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); + BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid); + attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name); + if (attribs->layer[a].glindex >= 0) { attribs->layer[b] = attribs->layer[a]; b++; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index dae66ce7eb5..9914c4bb362 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2668,9 +2668,6 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol) void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) { - /* TODO(sergey): This needs linearization for vertex color. - * But how to detect cases when input is linear and when it's srgb? - */ outcol = vec4(attr, 1.0); outvec = attr; outf = (attr.x + attr.y + attr.z) / 3.0; diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 5824d5a80db..a91d9e3e6f2 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -14,6 +14,58 @@ varying vec3 varnormal; varying float gl_ClipDistance[6]; #endif +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); + else + return pow((c + 0.055) * (1.0 / 1.055), 2.4); +} + +void srgb_to_linearrgb(vec3 col_from, out vec3 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); +} + +void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); + col_to.a = col_from.a; +} + +bool is_srgb(int info) +{ +#ifdef USE_NEW_SHADING + return (info == 1)? true: false; +#else + return false; +#endif +} + +void set_var_from_attr(vec3 attr, int info, out vec3 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + +void set_var_from_attr(vec4 attr, int info, out vec4 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + void main() { #ifndef USE_OPENSUBDIV |