Fixes related to #33087:

* Fix GLSL memory leak in the (vector) math node.
* Fix GLSL math node pow behavior for negative values, same as was done for C.
This commit is contained in:
Brecht Van Lommel 2012-11-06 19:58:48 +00:00
parent 1c6c3ead4f
commit 64467e3ffa
5 changed files with 48 additions and 26 deletions

@ -110,7 +110,6 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int isdata);
GPUNodeLink *GPU_texture(int size, float *pixels);
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
GPUNodeLink *GPU_socket(GPUNodeStack *sock);
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
int GPU_link(GPUMaterial *mat, const char *name, ...);

@ -1148,15 +1148,6 @@ GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
return link;
}
GPUNodeLink *GPU_socket(GPUNodeStack *sock)
{
GPUNodeLink *link = GPU_node_link_create(0);
link->socket= sock;
return link;
}
GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
{
GPUNodeLink *link = GPU_node_link_create(0);

@ -4,6 +4,21 @@ float exp_blender(float f)
return pow(2.71828182846, f);
}
float compatible_pow(float x, float y)
{
/* glsl pow doesn't accept negative x */
if(x < 0.0) {
if(mod(-y, 2.0) == 0.0)
return pow(-x, y);
else
return -pow(-x, y);
}
else if(x == 0.0)
return 0.0;
return pow(x, y);
}
void rgb_to_hsv(vec4 rgb, out vec4 outcol)
{
float cmax, cmin, h, s, v, cdelta;
@ -212,10 +227,17 @@ void math_atan(float val, out float outval)
void math_pow(float val1, float val2, out float outval)
{
if (val1 >= 0.0)
outval = pow(val1, val2);
else
outval = 0.0;
if (val1 >= 0.0) {
outval = compatible_pow(val1, val2);
}
else {
float val2_mod_1 = mod(abs(val2), 1.0);
if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
outval = compatible_pow(val1, floor(val2 + 0.5));
else
outval = 0.0;
}
}
void math_log(float val1, float val2, out float outval)

@ -225,8 +225,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUN
case 13:
case 15:
case 16:
GPU_stack_link(mat, names[node->custom1], NULL, out,
GPU_socket(&in[0]), GPU_socket(&in[1]));
GPU_stack_link(mat, names[node->custom1], in, out);
break;
case 4:
case 5:
@ -235,10 +234,16 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUN
case 8:
case 9:
case 14:
if (in[0].hasinput || !in[1].hasinput)
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0]));
else
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1]));
if (in[0].hasinput || !in[1].hasinput) {
/* use only first item and terminator */
GPUNodeStack tmp_in[2] = {in[0], in[2]};
GPU_stack_link(mat, names[node->custom1], tmp_in, out);
}
else {
/* use only second item and terminator */
GPUNodeStack tmp_in[2] = {in[1], in[2]};
GPU_stack_link(mat, names[node->custom1], tmp_in, out);
}
break;
default:
return 0;

@ -114,14 +114,19 @@ static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
case 2:
case 3:
case 4:
GPU_stack_link(mat, names[node->custom1], NULL, out,
GPU_socket(&in[0]), GPU_socket(&in[1]));
GPU_stack_link(mat, names[node->custom1], in, out);
break;
case 5:
if (in[0].hasinput || !in[1].hasinput)
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0]));
else
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1]));
if (in[0].hasinput || !in[1].hasinput) {
/* use only first item and terminator */
GPUNodeStack tmp_in[2] = {in[0], in[2]};
GPU_stack_link(mat, names[node->custom1], tmp_in, out);
}
else {
/* use only second item and terminator */
GPUNodeStack tmp_in[2] = {in[1], in[2]};
GPU_stack_link(mat, names[node->custom1], tmp_in, out);
}
break;
default:
return 0;