Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_codegen.c
| Show All 30 Lines | |||||
| * Convert material node-trees to GLSL. | * Convert material node-trees to GLSL. | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_customdata_types.h" | #include "DNA_customdata_types.h" | ||||
| #include "DNA_image_types.h" | #include "DNA_image_types.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "DNA_node_types.h" | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_dynstr.h" | #include "BLI_dynstr.h" | ||||
| #include "BLI_ghash.h" | #include "BLI_ghash.h" | ||||
| #include "GPU_extensions.h" | #include "GPU_extensions.h" | ||||
| #include "GPU_glew.h" | #include "GPU_glew.h" | ||||
| #include "GPU_material.h" | #include "GPU_material.h" | ||||
| #include "GPU_shader.h" | #include "GPU_shader.h" | ||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||
| #include "GPU_uniformbuffer.h" | |||||
| #include "BLI_sys_types.h" /* for intptr_t support */ | #include "BLI_sys_types.h" /* for intptr_t support */ | ||||
| #include "gpu_codegen.h" | #include "gpu_codegen.h" | ||||
| #include <string.h> | #include <string.h> | ||||
| #include <stdarg.h> | #include <stdarg.h> | ||||
| ▲ Show 20 Lines • Show All 445 Lines • ▼ Show 20 Lines | for (output = node->outputs.first; output; output = output->next) | ||||
| /* set id for unique names of tmp variables storing output */ | /* set id for unique names of tmp variables storing output */ | ||||
| output->id = id++; | output->id = id++; | ||||
| } | } | ||||
| BLI_ghash_free(bindhash, NULL, NULL); | BLI_ghash_free(bindhash, NULL, NULL); | ||||
| BLI_ghash_free(definehash, NULL, NULL); | BLI_ghash_free(definehash, NULL, NULL); | ||||
| } | } | ||||
| static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes) | /** | ||||
| * It will create an UBO for GPUMaterial if there is any GPU_DYNAMIC_UBO. | |||||
| */ | |||||
| static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, ListBase *nodes) | |||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUInput *input; | GPUInput *input; | ||||
| const char *name; | const char *name; | ||||
| int builtins = 0; | int builtins = 0; | ||||
| ListBase ubo_inputs = {NULL, NULL}; | |||||
| /* print uniforms */ | /* print uniforms */ | ||||
| for (node = nodes->first; node; node = node->next) { | for (node = nodes->first; node; node = node->next) { | ||||
| for (input = node->inputs.first; input; input = input->next) { | for (input = node->inputs.first; input; input = input->next) { | ||||
| if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) { | if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) { | ||||
| /* create exactly one sampler for each texture */ | /* create exactly one sampler for each texture */ | ||||
| if (codegen_input_has_texture(input) && input->bindtex) { | if (codegen_input_has_texture(input) && input->bindtex) { | ||||
| BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", | BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", | ||||
| Show All 15 Lines | for (input = node->inputs.first; input; input = input->next) { | ||||
| else { | else { | ||||
| BLI_dynstr_appendf(ds, "%s %s %s;\n", | BLI_dynstr_appendf(ds, "%s %s %s;\n", | ||||
| GLEW_VERSION_3_0 ? "in" : "varying", | GLEW_VERSION_3_0 ? "in" : "varying", | ||||
| GPU_DATATYPE_STR[input->type], name); | GPU_DATATYPE_STR[input->type], name); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (input->source == GPU_SOURCE_VEC_UNIFORM) { | else if (input->source == GPU_SOURCE_VEC_UNIFORM) { | ||||
| if (input->dynamicvec) { | if (input->dynamictype == GPU_DYNAMIC_UBO) { | ||||
| if (!input->link) { | |||||
| /* We handle the UBOuniforms separately. */ | |||||
| BLI_addtail(&ubo_inputs, BLI_genericNodeN(input)); | |||||
| } | |||||
| } | |||||
| else if (input->dynamicvec) { | |||||
| /* only create uniforms for dynamic vectors */ | /* only create uniforms for dynamic vectors */ | ||||
| BLI_dynstr_appendf(ds, "uniform %s unf%d;\n", | BLI_dynstr_appendf(ds, "uniform %s unf%d;\n", | ||||
| GPU_DATATYPE_STR[input->type], input->id); | GPU_DATATYPE_STR[input->type], input->id); | ||||
| } | } | ||||
| else { | else { | ||||
| if (input->type != GPU_CLOSURE) { | if (input->type != GPU_CLOSURE) { | ||||
| /* for others use const so the compiler can do folding */ | /* for others use const so the compiler can do folding */ | ||||
| BLI_dynstr_appendf(ds, "const %s cons%d = ", | BLI_dynstr_appendf(ds, "const %s cons%d = ", | ||||
| Show All 22 Lines | #ifdef WITH_OPENSUBDIV | ||||
| if (skip_opensubdiv) { | if (skip_opensubdiv) { | ||||
| BLI_dynstr_appendf(ds, "#endif\n"); | BLI_dynstr_appendf(ds, "#endif\n"); | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Handle the UBO block separately. */ | |||||
| if ((material != NULL) && !BLI_listbase_is_empty(&ubo_inputs)) { | |||||
| GPU_material_create_uniform_buffer(material, &ubo_inputs); | |||||
| /* Inputs are sorted */ | |||||
| BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME); | |||||
| for (LinkData *link = ubo_inputs.first; link; link = link->next) { | |||||
| input = link->data; | |||||
| BLI_dynstr_appendf(ds, "\t%s unf%d;\n", | |||||
fclem: You don't need the uniform identifier here. | |||||
| GPU_DATATYPE_STR[input->type], input->id); | |||||
| } | |||||
| BLI_dynstr_append(ds, "};\n"); | |||||
| BLI_freelistN(&ubo_inputs); | |||||
| } | |||||
| BLI_dynstr_append(ds, "\n"); | BLI_dynstr_append(ds, "\n"); | ||||
| return builtins; | return builtins; | ||||
| } | } | ||||
| static void codegen_declare_tmps(DynStr *ds, ListBase *nodes) | static void codegen_declare_tmps(DynStr *ds, ListBase *nodes) | ||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | for (node = nodes->first; node; node = node->next) { | ||||
| BLI_dynstr_append(ds, ");\n"); | BLI_dynstr_append(ds, ");\n"); | ||||
| } | } | ||||
| BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id); | BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id); | ||||
| BLI_dynstr_append(ds, ";\n"); | BLI_dynstr_append(ds, ";\n"); | ||||
| } | } | ||||
| static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use_new_shading) | static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUOutput *output, bool use_new_shading) | ||||
| { | { | ||||
| DynStr *ds = BLI_dynstr_new(); | DynStr *ds = BLI_dynstr_new(); | ||||
| char *code; | char *code; | ||||
| int builtins; | int builtins; | ||||
| #ifdef WITH_OPENSUBDIV | #ifdef WITH_OPENSUBDIV | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUInput *input; | GPUInput *input; | ||||
| #endif | #endif | ||||
| #if 0 | #if 0 | ||||
| BLI_dynstr_append(ds, FUNCTION_PROTOTYPES); | BLI_dynstr_append(ds, FUNCTION_PROTOTYPES); | ||||
| #endif | #endif | ||||
| codegen_set_unique_ids(nodes); | codegen_set_unique_ids(nodes); | ||||
| builtins = codegen_print_uniforms_functions(ds, nodes); | builtins = codegen_process_uniforms_functions(material, ds, nodes); | ||||
| #if 0 | #if 0 | ||||
| if (G.debug & G_DEBUG) | if (G.debug & G_DEBUG) | ||||
| BLI_dynstr_appendf(ds, "/* %s */\n", name); | BLI_dynstr_appendf(ds, "/* %s */\n", name); | ||||
| #endif | #endif | ||||
| BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n"); | BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n"); | ||||
| ▲ Show 20 Lines • Show All 677 Lines • ▼ Show 20 Lines | static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType type) | ||||
| GPUNode *outnode; | GPUNode *outnode; | ||||
| const char *name; | const char *name; | ||||
| if (link->output) { | if (link->output) { | ||||
| outnode = link->output->node; | outnode = link->output->node; | ||||
| name = outnode->name; | name = outnode->name; | ||||
| input = outnode->inputs.first; | input = outnode->inputs.first; | ||||
| if ((STREQ(name, "set_value") || STREQ(name, "set_rgb")) && | if ((STREQ(name, "set_value") || STREQ(name, "set_rgb") || STREQ(name, "set_rgba")) && | ||||
| (input->type == type)) | (input->type == type)) | ||||
| { | { | ||||
| input = MEM_dupallocN(outnode->inputs.first); | input = MEM_dupallocN(outnode->inputs.first); | ||||
| input->type = type; | input->type = type; | ||||
| if (input->link) | if (input->link) | ||||
| input->link->users++; | input->link->users++; | ||||
| BLI_addtail(&node->inputs, input); | BLI_addtail(&node->inputs, input); | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | if (link->dynamic) { | ||||
| input->dynamicdata = link->ptr2; | input->dynamicdata = link->ptr2; | ||||
| } | } | ||||
| MEM_freeN(link); | MEM_freeN(link); | ||||
| } | } | ||||
| BLI_addtail(&node->inputs, input); | BLI_addtail(&node->inputs, input); | ||||
| } | } | ||||
| static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock) | |||||
| static const char *gpu_uniform_set_function_from_type(eNodeSocketDatatype type) | |||||
| { | { | ||||
| switch (type) { | |||||
| case SOCK_FLOAT: | |||||
| return "set_value"; | |||||
| case SOCK_VECTOR: | |||||
| return "set_rgb"; | |||||
| case SOCK_RGBA: | |||||
| return "set_rgba"; | |||||
| default: | |||||
| BLI_assert(!"No gpu function for non-supported eNodeSocketDatatype"); | |||||
| return NULL; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Link stack uniform buffer. | |||||
| * This is called for the input/output sockets that are note connected. | |||||
| */ | |||||
| static GPUNodeLink *gpu_uniformbuffer_link( | |||||
| GPUMaterial *mat, bNode *node, GPUNodeStack *stack, const int index, const eNodeSocketInOut in_out) | |||||
| { | |||||
| bNodeSocket *socket; | |||||
| if (in_out == SOCK_IN) { | |||||
| socket = BLI_findlink(&node->original->inputs, index); | |||||
| } | |||||
| else { | |||||
| socket = BLI_findlink(&node->original->outputs, index); | |||||
| } | |||||
| BLI_assert(socket != NULL); | |||||
| BLI_assert(socket->in_out == in_out); | |||||
| if ((socket->flag & SOCK_HIDE_VALUE) == 0) { | |||||
| GPUNodeLink *link; | GPUNodeLink *link; | ||||
| switch (socket->type) { | |||||
| case SOCK_FLOAT: | |||||
| { | |||||
| bNodeSocketValueFloat *socket_data = socket->default_value; | |||||
| link = GPU_uniform_buffer(&socket_data->value, GPU_FLOAT); | |||||
| break; | |||||
| } | |||||
| case SOCK_VECTOR: | |||||
| { | |||||
| bNodeSocketValueRGBA *socket_data = socket->default_value; | |||||
| link = GPU_uniform_buffer(socket_data->value, GPU_VEC3); | |||||
| break; | |||||
| } | |||||
| case SOCK_RGBA: | |||||
| { | |||||
| bNodeSocketValueRGBA *socket_data = socket->default_value; | |||||
| link = GPU_uniform_buffer(socket_data->value, GPU_VEC4); | |||||
| break; | |||||
| } | |||||
| default: | |||||
| return NULL; | |||||
| break; | |||||
| } | |||||
| if (in_out == SOCK_IN) { | |||||
| GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link); | |||||
| } | |||||
| return link; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| static void gpu_node_input_socket(GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index) | |||||
| { | |||||
| if (sock->link) { | if (sock->link) { | ||||
| gpu_node_input_link(node, sock->link, sock->type); | gpu_node_input_link(node, sock->link, sock->type); | ||||
| } | } | ||||
| else if ((material != NULL) && (gpu_uniformbuffer_link(material, bnode, sock, index, SOCK_IN) != NULL)) { | |||||
| gpu_node_input_link(node, sock->link, sock->type); | |||||
| } | |||||
| else { | else { | ||||
| link = GPU_node_link_create(); | GPUNodeLink *link = GPU_node_link_create(); | ||||
| link->ptr1 = sock->vec; | link->ptr1 = sock->vec; | ||||
| gpu_node_input_link(node, link, sock->type); | gpu_node_input_link(node, link, sock->type); | ||||
| } | } | ||||
| } | } | ||||
| static void gpu_node_output(GPUNode *node, const GPUType type, GPUNodeLink **link) | static void gpu_node_output(GPUNode *node, const GPUType type, GPUNodeLink **link) | ||||
| { | { | ||||
| GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput"); | GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput"); | ||||
| ▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data) | ||||
| link->ptr2 = data; | link->ptr2 = data; | ||||
| link->dynamic = true; | link->dynamic = true; | ||||
| link->dynamictype = dynamictype; | link->dynamictype = dynamictype; | ||||
| return link; | return link; | ||||
| } | } | ||||
| /** | |||||
| * Add uniform to UBO struct of GPUMaterial. | |||||
| */ | |||||
| GPUNodeLink *GPU_uniform_buffer(float *num, GPUType gputype) | |||||
| { | |||||
| GPUNodeLink *link = GPU_node_link_create(); | |||||
| link->ptr1 = num; | |||||
| link->ptr2 = NULL; | |||||
| link->dynamic = true; | |||||
| link->dynamictype = GPU_DYNAMIC_UBO; | |||||
| link->type = gputype; | |||||
| return link; | |||||
| } | |||||
| GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data) | GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data) | ||||
| { | { | ||||
| GPUNodeLink *link = GPU_node_link_create(); | GPUNodeLink *link = GPU_node_link_create(); | ||||
| link->image = GPU_NODE_LINK_IMAGE_BLENDER; | link->image = GPU_NODE_LINK_IMAGE_BLENDER; | ||||
| link->ptr1 = ima; | link->ptr1 = ima; | ||||
| link->ptr2 = iuser; | link->ptr2 = iuser; | ||||
| link->image_isdata = is_data; | link->image_isdata = is_data; | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | bool GPU_link(GPUMaterial *mat, const char *name, ...) | ||||
| } | } | ||||
| va_end(params); | va_end(params); | ||||
| gpu_material_add_node(mat, node); | gpu_material_add_node(mat, node); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...) | bool GPU_stack_link(GPUMaterial *material, bNode *bnode, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...) | ||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUFunction *function; | GPUFunction *function; | ||||
| GPUNodeLink *link, **linkptr; | GPUNodeLink *link, **linkptr; | ||||
| va_list params; | va_list params; | ||||
| int i, totin, totout; | int i, totin, totout; | ||||
| function = gpu_lookup_function(name); | function = gpu_lookup_function(name); | ||||
| if (!function) { | if (!function) { | ||||
| fprintf(stderr, "GPU failed to find function %s\n", name); | fprintf(stderr, "GPU failed to find function %s\n", name); | ||||
| return false; | return false; | ||||
| } | } | ||||
| node = GPU_node_begin(name); | node = GPU_node_begin(name); | ||||
| totin = 0; | totin = 0; | ||||
| totout = 0; | totout = 0; | ||||
| if (in) { | if (in) { | ||||
| for (i = 0; in[i].type != GPU_NONE; i++) { | for (i = 0; in[i].type != GPU_NONE; i++) { | ||||
| gpu_node_input_socket(node, &in[i]); | gpu_node_input_socket(material, bnode, node, &in[i], i); | ||||
| totin++; | totin++; | ||||
| } | } | ||||
| } | } | ||||
| if (out) { | if (out) { | ||||
| for (i = 0; out[i].type != GPU_NONE; i++) { | for (i = 0; out[i].type != GPU_NONE; i++) { | ||||
| gpu_node_output(node, out[i].type, &out[i].link); | gpu_node_output(node, out[i].type, &out[i].link); | ||||
| totout++; | totout++; | ||||
| } | } | ||||
| } | } | ||||
| va_start(params, out); | va_start(params, out); | ||||
| for (i = 0; i < function->totparam; i++) { | for (i = 0; i < function->totparam; i++) { | ||||
| if (function->paramqual[i] != FUNCTION_QUAL_IN) { | if (function->paramqual[i] != FUNCTION_QUAL_IN) { | ||||
| if (totout == 0) { | if (totout == 0) { | ||||
| linkptr = va_arg(params, GPUNodeLink **); | linkptr = va_arg(params, GPUNodeLink **); | ||||
| gpu_node_output(node, function->paramtype[i], linkptr); | gpu_node_output(node, function->paramtype[i], linkptr); | ||||
| } | } | ||||
| else | else | ||||
| totout--; | totout--; | ||||
| } | } | ||||
| else { | else { | ||||
| if (totin == 0) { | if (totin == 0) { | ||||
| link = va_arg(params, GPUNodeLink *); | link = va_arg(params, GPUNodeLink *); | ||||
| if (link->socket) | if (link->socket) | ||||
| gpu_node_input_socket(node, link->socket); | gpu_node_input_socket(NULL, NULL, node, link->socket, -1); | ||||
| else | else | ||||
| gpu_node_input_link(node, link, function->paramtype[i]); | gpu_node_input_link(node, link, function->paramtype[i]); | ||||
| } | } | ||||
| else | else | ||||
| totin--; | totin--; | ||||
| } | } | ||||
| } | } | ||||
| va_end(params); | va_end(params); | ||||
| gpu_material_add_node(mat, node); | gpu_material_add_node(material, node); | ||||
| return true; | return true; | ||||
| } | } | ||||
| int GPU_link_changed(GPUNodeLink *link) | int GPU_link_changed(GPUNodeLink *link) | ||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUInput *input; | GPUInput *input; | ||||
| const char *name; | const char *name; | ||||
| if (link->output) { | if (link->output) { | ||||
| node = link->output->node; | node = link->output->node; | ||||
| name = node->name; | name = node->name; | ||||
| if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) { | if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) { | ||||
| input = node->inputs.first; | input = node->inputs.first; | ||||
| return (input->link != NULL); | return (input->link != NULL); | ||||
| } | } | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| else | else | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| GPUNodeLink *GPU_uniformbuffer_link_out(GPUMaterial *mat, bNode *node, GPUNodeStack *stack, const int index) | |||||
| { | |||||
| return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT); | |||||
| } | |||||
| /* Pass create/free */ | /* Pass create/free */ | ||||
| static void gpu_nodes_tag(GPUNodeLink *link) | static void gpu_nodes_tag(GPUNodeLink *link) | ||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUInput *input; | GPUInput *input; | ||||
Done Inline ActionsCan't we use bNodeSocket->type for this instead of passing the gputype and potentially have errors? fclem: Can't we use bNodeSocket->type for this instead of passing the gputype and potentially have… | |||||
| if (!link->output) | if (!link->output) | ||||
| return; | return; | ||||
| node = link->output->node; | node = link->output->node; | ||||
| if (node->tag) | if (node->tag) | ||||
| return; | return; | ||||
| node->tag = true; | node->tag = true; | ||||
| Show All 17 Lines | for (node = nodes->first; node; node = next) { | ||||
| if (!node->tag) { | if (!node->tag) { | ||||
| BLI_remlink(nodes, node); | BLI_remlink(nodes, node); | ||||
| gpu_node_free(node); | gpu_node_free(node); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GPUPass *GPU_generate_pass_new( | GPUPass *GPU_generate_pass_new( | ||||
| struct GPUMaterial *material, | |||||
| ListBase *nodes, struct GPUNodeLink *frag_outlink, | ListBase *nodes, struct GPUNodeLink *frag_outlink, | ||||
| GPUVertexAttribs *attribs, | GPUVertexAttribs *attribs, | ||||
| const char *vert_code, const char *geom_code, | const char *vert_code, const char *geom_code, | ||||
| const char *frag_lib, const char *defines) | const char *frag_lib, const char *defines) | ||||
| { | { | ||||
| GPUShader *shader; | GPUShader *shader; | ||||
| GPUPass *pass; | GPUPass *pass; | ||||
| char *vertexgen, *fragmentgen, *tmp; | char *vertexgen, *fragmentgen, *tmp; | ||||
| char *vertexcode, *geometrycode, *fragmentcode; | char *vertexcode, *geometrycode, *fragmentcode; | ||||
| /* prune unused nodes */ | /* prune unused nodes */ | ||||
| gpu_nodes_prune(nodes, frag_outlink); | gpu_nodes_prune(nodes, frag_outlink); | ||||
| gpu_nodes_get_vertex_attributes(nodes, attribs); | gpu_nodes_get_vertex_attributes(nodes, attribs); | ||||
| /* generate code and compile with opengl */ | /* generate code and compile with opengl */ | ||||
| fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true); | fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output, true); | ||||
| vertexgen = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL)); | vertexgen = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL)); | ||||
| tmp = BLI_strdupcat(frag_lib, glsl_material_library); | tmp = BLI_strdupcat(frag_lib, glsl_material_library); | ||||
| fragmentcode = BLI_strdupcat(tmp, fragmentgen); | fragmentcode = BLI_strdupcat(tmp, fragmentgen); | ||||
| vertexcode = BLI_strdup(vertexgen); | vertexcode = BLI_strdup(vertexgen); | ||||
| if (geom_code) { | if (geom_code) { | ||||
| geometrycode = code_generate_geometry_new(nodes, geom_code); | geometrycode = code_generate_geometry_new(nodes, geom_code); | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | #endif | ||||
| /* prune unused nodes */ | /* prune unused nodes */ | ||||
| gpu_nodes_prune(nodes, outlink); | gpu_nodes_prune(nodes, outlink); | ||||
| gpu_nodes_get_vertex_attributes(nodes, attribs); | gpu_nodes_get_vertex_attributes(nodes, attribs); | ||||
| gpu_nodes_get_builtin_flag(nodes, builtins); | gpu_nodes_get_builtin_flag(nodes, builtins); | ||||
| /* generate code and compile with opengl */ | /* generate code and compile with opengl */ | ||||
| fragmentcode = code_generate_fragment(nodes, outlink->output, false); | fragmentcode = code_generate_fragment(NULL, nodes, outlink->output, false); | ||||
| vertexcode = code_generate_vertex(nodes, type); | vertexcode = code_generate_vertex(nodes, type); | ||||
| geometrycode = code_generate_geometry(nodes, use_opensubdiv); | geometrycode = code_generate_geometry(nodes, use_opensubdiv); | ||||
| int flags = GPU_SHADER_FLAGS_NONE; | int flags = GPU_SHADER_FLAGS_NONE; | ||||
| if (use_opensubdiv) { | if (use_opensubdiv) { | ||||
| flags |= GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV; | flags |= GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV; | ||||
| } | } | ||||
| if (use_new_shading) { | if (use_new_shading) { | ||||
| ▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines | |||||
You don't need the uniform identifier here.