From a6aaaad9795e80af05e8281030107c32c6a1366b Mon Sep 17 00:00:00 2001 From: Alexander Romanov Date: Sat, 23 Jan 2016 15:27:36 +0300 Subject: [PATCH] Vector Transform node support for GLSL mode and the internal renderer The Vector Transform node is a useful node which is present in the Cycles renderer. {F144283} This patch implements the Vector Transform node for GLSL mode and the internal renderer. Example: {F273060} Alexander (Blend4Web Team) Reviewers: brecht, campbellbarton, sergey Reviewed By: campbellbarton, sergey Subscribers: psy-fi, duarteframos, RobM, lightbwk, sergey, AlexKowel, valentin_b4w, Evgeny_Rodygin, yurikovelenov Projects: #bf_blender:_next Differential Revision: https://developer.blender.org/D909 --- release/scripts/startup/nodeitems_builtins.py | 1 + .../blender/editors/render/render_internal.c | 8 ++ source/blender/gpu/GPU_material.h | 6 +- source/blender/gpu/intern/gpu_codegen.c | 4 + source/blender/gpu/intern/gpu_draw.c | 2 +- source/blender/gpu/intern/gpu_material.c | 24 +++- .../gpu/shaders/gpu_shader_material.glsl | 15 ++ .../shader/nodes/node_shader_vectTransform.c | 133 +++++++++++++++++- source/blender/python/intern/gpu.c | 2 + .../render/extern/include/RE_pipeline.h | 7 + .../render/extern/include/RE_shader_ext.h | 16 +++ .../render/intern/include/render_types.h | 4 + .../render/intern/include/renderdatabase.h | 1 + .../render/intern/source/renderdatabase.c | 22 +++ .../render/intern/source/shadeoutput.c | 28 ++++ .../bad_level_call_stubs/stubs.c | 2 + source/gameengine/Ketsji/BL_BlenderShader.cpp | 13 +- 17 files changed, 278 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index c3def14787d..7af10aab648 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -159,6 +159,7 @@ shader_node_categories = [ NodeItem("ShaderNodeNormal"), NodeItem("ShaderNodeMapping"), NodeItem("ShaderNodeVectorCurve"), + NodeItem("ShaderNodeVectorTransform"), ]), ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[ NodeItem("ShaderNodeValToRGB"), diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 143003cc4e6..eb8ea01f750 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1188,6 +1188,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda char name[32]; int update_flag; bool use_border; + int ob_inst_update_flag = 0; update_flag = rp->engine->job_update_flag; rp->engine->job_update_flag = 0; @@ -1299,6 +1300,13 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda /* OK, can we enter render code? */ if (rstats->convertdone) { bool first_time = true; + + if (update_flag & PR_UPDATE_VIEW) { + ob_inst_update_flag |= RE_OBJECT_INSTANCES_UPDATE_VIEW; + } + + RE_updateRenderInstances(re, ob_inst_update_flag); + for (;;) { if (first_time == false) { if (restore) diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 25788c26fea..65cdf834533 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -95,6 +95,8 @@ typedef enum GPUBuiltin { GPU_PARTICLE_LOCATION = (1 << 10), GPU_PARTICLE_VELOCITY = (1 << 11), GPU_PARTICLE_ANG_VELOCITY = (1 << 12), + GPU_LOC_TO_VIEW_MATRIX = (1 << 13), + GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14), } GPUBuiltin; typedef enum GPUOpenGLBuiltin { @@ -148,6 +150,8 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_OBJECT_IMAT = 4 | GPU_DYNAMIC_GROUP_OBJECT, GPU_DYNAMIC_OBJECT_COLOR = 5 | GPU_DYNAMIC_GROUP_OBJECT, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 6 | GPU_DYNAMIC_GROUP_OBJECT, + GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT = 7 | GPU_DYNAMIC_GROUP_OBJECT, + GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT = 8 | GPU_DYNAMIC_GROUP_OBJECT, GPU_DYNAMIC_LAMP_DYNVEC = 1 | GPU_DYNAMIC_GROUP_LAMP, GPU_DYNAMIC_LAMP_DYNCO = 2 | GPU_DYNAMIC_GROUP_LAMP, @@ -218,7 +222,7 @@ void GPU_material_bind( GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock); void GPU_material_bind_uniforms( - GPUMaterial *material, float obmat[4][4], float obcol[4], + GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4], float autobumpscale, GPUParticleInfo *pi); void GPU_material_unbind(GPUMaterial *material); bool GPU_material_bound(GPUMaterial *material); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 857b339c3a3..fb46b167f0f 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -381,6 +381,10 @@ const char *GPU_builtin_name(GPUBuiltin builtin) return "unfinvviewmat"; else if (builtin == GPU_INVERSE_OBJECT_MATRIX) return "unfinvobmat"; + else if (builtin == GPU_LOC_TO_VIEW_MATRIX) + return "unflocaltoviewmat"; + else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX) + return "unfinvlocaltoviewmat"; else if (builtin == GPU_VIEW_POSITION) return "varposition"; else if (builtin == GPU_VIEW_NORMAL) diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 95c019be409..a7f802a4502 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1763,7 +1763,7 @@ int GPU_object_material_bind(int nr, void *attribs) GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock); auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; - GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale, &partile_info); + GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info); GMS.gboundmat = mat; /* for glsl use alpha blend mode, unless it's set to solid and diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 29e49ca89d3..7cb2fc0622d 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -112,6 +112,7 @@ struct GPUMaterial { /* for passing uniforms */ int viewmatloc, invviewmatloc; int obmatloc, invobmatloc; + int localtoviewmatloc, invlocaltoviewmatloc; int obcolloc, obautobumpscaleloc; int cameratexcofacloc; @@ -242,6 +243,10 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX)); if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); + if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) + material->localtoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_LOC_TO_VIEW_MATRIX)); + if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) + material->invlocaltoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_LOC_TO_VIEW_MATRIX)); if (material->builtins & GPU_OBCOLOR) material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); if (material->builtins & GPU_AUTO_BUMPSCALE) @@ -384,12 +389,14 @@ void GPU_material_bind( } void GPU_material_bind_uniforms( - GPUMaterial *material, float obmat[4][4], float obcol[4], + GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4], float autobumpscale, GPUParticleInfo *pi) { if (material->pass) { GPUShader *shader = GPU_pass_shader(material->pass); float invmat[4][4], col[4]; + float localtoviewmat[4][4]; + float invlocaltoviewmat[4][4]; /* handle per object builtins */ if (material->builtins & GPU_OBJECT_MATRIX) { @@ -399,6 +406,19 @@ void GPU_material_bind_uniforms( invert_m4_m4(invmat, obmat); GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat); } + if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) { + if (viewmat) { + mul_m4_m4m4(localtoviewmat, viewmat, obmat); + GPU_shader_uniform_vector(shader, material->localtoviewmatloc, 16, 1, (float *)localtoviewmat); + } + } + if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) { + if (viewmat) { + mul_m4_m4m4(localtoviewmat, viewmat, obmat); + invert_m4_m4(invlocaltoviewmat, localtoviewmat); + GPU_shader_uniform_vector(shader, material->invlocaltoviewmatloc, 16, 1, (float*)invlocaltoviewmat); + } + } if (material->builtins & GPU_OBCOLOR) { copy_v4_v4(col, obcol); CLAMP(col[3], 0.0f, 1.0f); @@ -2352,6 +2372,8 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F }, { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F }, { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F }, + { GPU_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT, GPU_DATA_16F }, + { GPU_INVERSE_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT, GPU_DATA_16F }, { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F }, { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F }, { 0 } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index dfb1af0e863..e7072016cc0 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -166,6 +166,21 @@ void particle_info(vec4 sprops, vec3 loc, vec3 vel, vec3 avel, out float index, angular_velocity = avel; } +void vect_normalize(vec3 vin, out vec3 vout) +{ + vout = normalize(vin); +} + +void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout) +{ + vout = (mat*vec4(vin, 0.0)).xyz; +} + +void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout) +{ + vout = (mat*vec4(vin, 1.0)).xyz; +} + void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec) { outvec = (mat * vec4(vec, 1.0)).xyz; diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c index 4cab9d3ca97..5b6d213703a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c @@ -52,15 +52,146 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod node->storage = vect; } +static const float (* const get_matrix_from_to(ShaderCallData *scd, short from, short to))[4] +{ + switch (from) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB); + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW); + } + break; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return RE_render_current_get_matrix(RE_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OBINV); + } + break; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return RE_render_current_get_matrix(RE_VIEWINV_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV); + } + break; + } + return NULL; +} + +static void node_shader_exec_vect_transform(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +{ + float vec[4]; + const float (*mat)[4]; + + if (data) { + NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; + + nodestack_get_vec(vec, SOCK_VECTOR, in[0]); + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) + vec[3] = 1.0f; + else + vec[3] = 0.0f; + + mat = get_matrix_from_to((ShaderCallData *)data, nodeprop->convert_from, nodeprop->convert_to); + if (mat) { + mul_m4_v4((float(*)[4])mat, vec); + } + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) + normalize_v3(vec); + + copy_v4_v4(out[0]->vec, vec); + } +} + +static GPUNodeLink *get_gpulink_matrix_from_to(short from, short to) +{ + switch (from) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return GPU_builtin(GPU_OBJECT_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return GPU_builtin(GPU_LOC_TO_VIEW_MATRIX); + } + case SHD_VECT_TRANSFORM_SPACE_WORLD: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return GPU_builtin(GPU_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return GPU_builtin(GPU_INVERSE_OBJECT_MATRIX); + } + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return GPU_builtin(GPU_INVERSE_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return GPU_builtin(GPU_INVERSE_LOC_TO_VIEW_MATRIX); + } + } + return 0; +} +static int gpu_shader_vect_transform(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + struct GPUNodeLink *inputlink; + struct GPUNodeLink *fromto; + + int ret = 0; + + const char *vtransform = "direction_transform_m4v3"; + const char *ptransform = "point_transform_m4v3"; + const char *func_name = 0; + + NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; + + if (in[0].hasinput) + inputlink = in[0].link; + else + inputlink = GPU_uniform(in[0].vec); + + fromto = get_gpulink_matrix_from_to(nodeprop->convert_from, nodeprop->convert_to); + + func_name = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? ptransform : vtransform; + if (fromto) + ret = GPU_link(mat, func_name, inputlink, fromto, &out[0].link); + else + ret = GPU_link(mat, "set_rgb", inputlink, &out[0].link); + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) + return GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); + + return ret; +} + void register_node_type_sh_vect_transform(void) { static bNodeType ntype; sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0); - node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_init(&ntype, node_shader_init_vect_transform); node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out); node_type_storage(&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_vect_transform); + node_type_gpu(&ntype, gpu_shader_vect_transform); nodeRegisterType(&ntype); } diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index aada3f6fc80..c6e47de8c90 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -97,6 +97,8 @@ static PyObject *PyInit_gpu(void) PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE); /* GPU_DYNAMIC_GROUP_LAMP */ diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 96ac8aa8c5a..ce0691b7632 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -363,6 +363,13 @@ bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override bool RE_allow_render_generic_object(struct Object *ob); +/* RE_updateRenderInstances flag */ +enum { + RE_OBJECT_INSTANCES_UPDATE_VIEW = (1 << 0), + RE_OBJECT_INSTANCES_UPDATE_OBMAT = (1 << 1), +}; +void RE_updateRenderInstances(Render *re, int flag); + /******* defined in render_result.c *********/ bool RE_HasFakeLayer(RenderResult *res); diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index f78c0aa8cb2..2b07ace26db 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -220,6 +220,22 @@ float RE_bake_make_derivative(struct ImBuf *ibuf, float *heights_buffer, const c const float height_min, const float height_max, const float fmult); +enum { + RE_OBJECT_INSTANCE_MATRIX_OB, + RE_OBJECT_INSTANCE_MATRIX_OBINV, + RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW, + RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV, +}; + +const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4]; + +enum { + RE_VIEW_MATRIX, + RE_VIEWINV_MATRIX, +}; + +const float (*RE_render_current_get_matrix(int matrix_id))[4]; + #define BAKE_RESULT_OK 0 #define BAKE_RESULT_NO_OBJECTS 1 #define BAKE_RESULT_FEEDBACK_LOOP 2 diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 3569cb2c168..3b69c124753 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -353,6 +353,10 @@ typedef struct ObjectInstanceRen { float mat[4][4], imat[4][4]; float nmat[3][3]; /* nmat is inverse mat tranposed */ + + float obmat[4][4], obinvmat[4][4]; + float localtoviewmat[4][4], localtoviewinvmat[4][4]; + short flag; float dupliorco[3], dupliuv[2]; diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 224974454e8..167ebc58030 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -119,6 +119,7 @@ struct ObjectInstanceRen *RE_addRenderInstance( struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay, const struct DupliObject *dob); void RE_makeRenderInstances(struct Render *re); +void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag); void RE_instance_rotate_ray_start(struct ObjectInstanceRen *obi, struct Isect *is); void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index ac42c0d1dcc..560627b1be1 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1363,6 +1363,26 @@ void project_renderdata(Render *re, /* ------------------------------------------------------------------------- */ +void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag) +{ + /* flag specifies what things have changed. */ + if (flag & RE_OBJECT_INSTANCES_UPDATE_OBMAT) { + copy_m4_m4(obi->obmat, obi->ob->obmat); + invert_m4_m4(obi->obinvmat, obi->obmat); + } + if (flag & RE_OBJECT_INSTANCES_UPDATE_VIEW) { + mul_m4_m4m4(obi->localtoviewmat, re->viewmat, obi->obmat); + mul_m4_m4m4(obi->localtoviewinvmat, obi->obinvmat, re->viewinv); + } +} + +void RE_updateRenderInstances(Render *re, int flag) +{ + int i = 0; + for (i = 0; i < re->totinstance; i++) + RE_updateRenderInstance(re, &re->objectinstance[i], flag); +} + ObjectInstanceRen *RE_addRenderInstance( Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob) @@ -1407,6 +1427,8 @@ ObjectInstanceRen *RE_addRenderInstance( } } + RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW); + if (mat) { copy_m4_m4(obi->mat, mat); copy_m3_m4(mat3, mat); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 27c0f5d81ec..71b409dbba7 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -2112,3 +2112,31 @@ float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv return 0.0f; } + +const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4] +{ + if (obi) { + switch (matrix_id) { + case RE_OBJECT_INSTANCE_MATRIX_OB: + return (const float(*)[4])obi->obmat; + case RE_OBJECT_INSTANCE_MATRIX_OBINV: + return (const float(*)[4])obi->obinvmat; + case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW: + return (const float(*)[4])obi->localtoviewmat; + case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV: + return (const float(*)[4])obi->localtoviewinvmat; + } + } + return NULL; +} + +const float (*RE_render_current_get_matrix(int matrix_id))[4] +{ + switch(matrix_id) { + case RE_VIEW_MATRIX: + return (const float(*)[4])R.viewmat; + case RE_VIEWINV_MATRIX: + return (const float(*)[4])R.viewinv; + } + return NULL; +} diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 4d0840ece74..c0ff81b3b20 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -263,6 +263,8 @@ void RE_sample_material_color( struct Render *RE_GetRender(const char *name) RET_NULL struct Object *RE_GetCamera(struct Render *re) RET_NULL float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) RET_ZERO +const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4] RET_NULL +const float (*RE_render_current_get_matrix(int matrix_id))[4] RET_NULL /* blenkernel */ bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 0f71f8d3bac..95679b5d3a6 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -74,8 +74,8 @@ void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty) float viewmat[4][4], viewinvmat[4][4]; const MT_Matrix4x4& view = rasty->GetViewMatrix(); const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix(); - view.getValue((float*)viewmat); - viewinv.getValue((float*)viewinvmat); + view.getValue(&viewmat[0][0]); + viewinv.getValue(&viewinvmat[0][0]); GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, NULL, false); } @@ -148,7 +148,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) { - float obmat[4][4], obcol[4]; + float obmat[4][4], viewmat[4][4], obcol[4]; GPUMaterial *gpumat; gpumat = mGPUMat; @@ -160,15 +160,16 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) model.setValue(ms.m_OpenGLMatrix); // note: getValue gives back column major as needed by OpenGL - model.getValue((float*)obmat); + model.getValue(&obmat[0][0]); if (ms.m_bObjectColor) - ms.m_RGBAcolor.getValue((float *)obcol); + ms.m_RGBAcolor.getValue(&obcol[0]); else obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f; + rasty->GetViewMatrix().getValue(&viewmat[0][0]); float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f; - GPU_material_bind_uniforms(gpumat, obmat, obcol, auto_bump_scale, NULL); + GPU_material_bind_uniforms(gpumat, obmat, viewmat, obcol, auto_bump_scale, NULL); mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol); }