From 475b43ad4a7f04c07226d97d46c6d2b18fa13f51 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 31 Aug 2016 02:17:11 +0200 Subject: Fix T49175: GLSL material crash with environment maps. --- .../nodes/shader/nodes/node_shader_material.c | 41 +++++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 8b21b1ff33b..6850cdbf6ea 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -223,12 +223,27 @@ static void node_shader_init_material(bNodeTree *UNUSED(ntree), bNode *node) /* XXX this is also done as a local static function in gpu_codegen.c, * but we need this to hack around the crappy material node. */ -static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in) +static GPUNodeLink *gpu_get_input_link(GPUMaterial *mat, GPUNodeStack *in) { - if (in->link) + if (in->link) { return in->link; - else - return GPU_uniform(in->vec); + } + else { + GPUNodeLink *result = NULL; + + /* note GPU_uniform() is only intended to be used as a parameter to + * GPU_link(), returning it directly results in leaks or double frees */ + if (in->type == GPU_FLOAT) + GPU_link(mat, "set_value", GPU_uniform(in->vec), &result); + else if (in->type == GPU_VEC3) + GPU_link(mat, "set_rgb", GPU_uniform(in->vec), &result); + else if (in->type == GPU_VEC4) + GPU_link(mat, "set_rgba", GPU_uniform(in->vec), &result); + else + BLI_assert(0); + + return result; + } } static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) @@ -251,18 +266,18 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU /* write values */ if (hasinput[MAT_IN_COLOR]) - shi.rgb = gpu_get_input_link(&in[MAT_IN_COLOR]); + shi.rgb = gpu_get_input_link(mat, &in[MAT_IN_COLOR]); if (hasinput[MAT_IN_SPEC]) - shi.specrgb = gpu_get_input_link(&in[MAT_IN_SPEC]); + shi.specrgb = gpu_get_input_link(mat, &in[MAT_IN_SPEC]); if (hasinput[MAT_IN_REFL]) - shi.refl = gpu_get_input_link(&in[MAT_IN_REFL]); + shi.refl = gpu_get_input_link(mat, &in[MAT_IN_REFL]); /* retrieve normal */ if (hasinput[MAT_IN_NORMAL]) { GPUNodeLink *tmp; - shi.vn = gpu_get_input_link(&in[MAT_IN_NORMAL]); + shi.vn = gpu_get_input_link(mat, &in[MAT_IN_NORMAL]); if (GPU_material_use_world_space_shading(mat)) { GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); GPU_link(mat, "direction_transform_m4v3", shi.vn, GPU_builtin(GPU_VIEW_MATRIX), &shi.vn); @@ -276,15 +291,15 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU if (node->type == SH_NODE_MATERIAL_EXT) { if (hasinput[MAT_IN_MIR]) - shi.mir = gpu_get_input_link(&in[MAT_IN_MIR]); + shi.mir = gpu_get_input_link(mat, &in[MAT_IN_MIR]); if (hasinput[MAT_IN_AMB]) - shi.amb = gpu_get_input_link(&in[MAT_IN_AMB]); + shi.amb = gpu_get_input_link(mat, &in[MAT_IN_AMB]); if (hasinput[MAT_IN_EMIT]) - shi.emit = gpu_get_input_link(&in[MAT_IN_EMIT]); + shi.emit = gpu_get_input_link(mat, &in[MAT_IN_EMIT]); if (hasinput[MAT_IN_SPECTRA]) - shi.spectra = gpu_get_input_link(&in[MAT_IN_SPECTRA]); + shi.spectra = gpu_get_input_link(mat, &in[MAT_IN_SPECTRA]); if (hasinput[MAT_IN_ALPHA]) - shi.alpha = gpu_get_input_link(&in[MAT_IN_ALPHA]); + shi.alpha = gpu_get_input_link(mat, &in[MAT_IN_ALPHA]); } GPU_shaderesult_set(&shi, &shr); /* clears shr */ -- cgit v1.2.3