diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-06-28 22:05:43 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-06-28 22:05:43 +0300 |
commit | ada6e720f941dbd50e75b04feea6dae16b8ffc55 (patch) | |
tree | f5bb643796be47860bf7ffec1c71a7156cbba9f7 /source/blender/gpu | |
parent | 26b699a105acf47a66f14fe40539b471b409ecc0 (diff) |
GPU_codegen: Add support for passing attributes through the geometry stage.
Should fix some issues with missing attributes in Eevee.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 8586ee67d5d..afdb927fbcc 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -787,7 +787,7 @@ static const char *attrib_prefix_get(CustomDataType type) } } -static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code) +static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code, bool use_geom) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; @@ -814,8 +814,8 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code) BLI_dynstr_appendf(ds, "#define att%d %s%u\n", input->attribid, attrib_prefix_get(input->attribtype), hash); } - BLI_dynstr_appendf(ds, "out %s var%d;\n", - GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf(ds, "out %s var%d%s;\n", + GPU_DATATYPE_STR[input->type], input->attribid, use_geom ? "g" : ""); } } } @@ -831,19 +831,19 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code) if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* silly exception */ BLI_dynstr_appendf( - ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n", - input->attribid, input->attribid); + ds, "\tvar%d%s.xyz = normalize(NormalMatrix * att%d.xyz);\n", + input->attribid, use_geom ? "g" : "", input->attribid); BLI_dynstr_appendf( - ds, "\tvar%d.w = att%d.w;\n", - input->attribid, input->attribid); + ds, "\tvar%d%s.w = att%d.w;\n", + input->attribid, use_geom ? "g" : "", input->attribid); } else if (input->attribtype == CD_ORCO) { - BLI_dynstr_appendf(ds, "\tvar%d = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n", - input->attribid); + BLI_dynstr_appendf(ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n", + input->attribid, use_geom ? "g" : ""); } else { - BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", - input->attribid, input->attribid); + BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", + input->attribid, use_geom ? "g" : "", input->attribid); } } } @@ -972,6 +972,49 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) return code; } +static char *code_generate_geometry_new(ListBase *nodes, const char *geom_code) +{ + DynStr *ds = BLI_dynstr_new(); + GPUNode *node; + GPUInput *input; + char *code; + + /* Generate varying declarations. */ + for (node = nodes->first; node; node = node->next) { + for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { + if (input->attribtype == CD_MTFACE) { + BLI_dynstr_appendf(ds, "in %s var%dg[];\n", + GPU_DATATYPE_STR[input->type], + input->attribid); + BLI_dynstr_appendf(ds, "out %s var%d;\n", + GPU_DATATYPE_STR[input->type], + input->attribid); + } + } + } + } + /* Generate varying assignments. */ + BLI_dynstr_append(ds, "#define ATTRIB\n"); + BLI_dynstr_appendf(ds, "void pass_attrib(in int vert) {\n"); + for (node = nodes->first; node; node = node->next) { + for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { + /* TODO let shader choose what to do depending on what the attrib is. */ + BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];", input->attribid, input->attribid); + } + } + } + BLI_dynstr_append(ds, "}\n"); + + BLI_dynstr_append(ds, geom_code); + + code = BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + + return code; +} + static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) { #ifdef WITH_OPENSUBDIV @@ -1854,7 +1897,7 @@ GPUPass *GPU_generate_pass_new( { GPUShader *shader; GPUPass *pass; - char *vertexgen, *geometrygen, *fragmentgen, *tmp; + char *vertexgen, *fragmentgen, *tmp; char *vertexcode, *geometrycode, *fragmentcode; /* prune unused nodes */ @@ -1864,14 +1907,18 @@ GPUPass *GPU_generate_pass_new( /* generate code and compile with opengl */ fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true); - vertexgen = code_generate_vertex_new(nodes, vert_code); - // geometrygen = code_generate_geometry(nodes, false); - UNUSED_VARS(geometrygen); + vertexgen = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL)); tmp = BLI_strdupcat(frag_lib, glsl_material_library); fragmentcode = BLI_strdupcat(tmp, fragmentgen); vertexcode = BLI_strdup(vertexgen); - geometrycode = (geom_code) ? BLI_strdup(geom_code) : NULL; + + if (geom_code) { + geometrycode = code_generate_geometry_new(nodes, geom_code); + } + else { + geometrycode = NULL; + } shader = GPU_shader_create(vertexcode, fragmentcode, |