Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_material.c')
-rw-r--r--source/blender/gpu/intern/gpu_material.c148
1 files changed, 95 insertions, 53 deletions
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 5ae1dd21e4d..703836af504 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -100,6 +100,7 @@ struct GPUMaterial {
struct GPULamp {
Object *ob;
+ Object *par;
Lamp *la;
int type, mode, lay;
@@ -216,14 +217,20 @@ static int GPU_material_construct_end(GPUMaterial *material)
return 0;
}
-void GPU_material_free(GPUMaterial *material)
+void GPU_material_free(Material *ma)
{
- if(material->pass)
- GPU_pass_free(material->pass);
+ GPUMaterial *material = ma->gpumaterial;
- BLI_linklist_free(material->lamps, NULL);
+ if(material) {
+ if(material->pass)
+ GPU_pass_free(material->pass);
- MEM_freeN(material);
+ BLI_linklist_free(material->lamps, NULL);
+
+ MEM_freeN(material);
+
+ ma->gpumaterial = NULL;
+ }
}
void GPU_material_bind(GPUMaterial *material, int lay, double time)
@@ -729,14 +736,15 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
Base *base;
Object *ob;
Scene *sce;
+ GPULamp *lamp;
for(SETLOOPER(shi->gpumat->scene, base)) {
ob= base->object;
if(ob->type==OB_LAMP) {
- GPU_lamp_from_blender(ob, ob->data);
- if(ob->gpulamp)
- shade_one_light(shi, shr, ob->gpulamp);
+ lamp = GPU_lamp_from_blender(ob, NULL);
+ if(lamp)
+ shade_one_light(shi, shr, lamp);
}
if (ob->transflag & OB_DUPLI) {
@@ -749,9 +757,9 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
if(ob->type==OB_LAMP) {
Mat4CpyMat4(ob->obmat, dob->mat);
- GPU_lamp_from_blender(ob, ob->data);
- if(ob->gpulamp)
- shade_one_light(shi, shr, ob->gpulamp);
+ lamp = GPU_lamp_from_blender(ob, base->object);
+ if(lamp)
+ shade_one_light(shi, shr, lamp);
}
}
@@ -855,7 +863,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPUMaterial *mat= shi->gpumat;
MTex *mtex;
Tex *tex;
- GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil = NULL;
+ GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
GPUNodeLink *texco_norm, *texco_orco, *texco_object, *texco_tangent;
GPUNodeLink *texco_global, *texco_uv = NULL;
GPUNodeLink *colfac, *newnor, *varfac, *orn;
@@ -993,10 +1001,17 @@ static void do_material_tex(GPUShadeInput *shi)
newnor = tnor;
norfac = MIN2(mtex->norfac, 1.0);
- if(norfac == 1.0f)
+ if(norfac == 1.0f && !GPU_link_changed(stencil)) {
shi->vn = newnor;
- else
- GPU_link(mat, "mtex_blend_normal", GPU_uniform(&norfac), shi->vn, newnor, &shi->vn);
+ }
+ else {
+ tnorfac = GPU_uniform(&norfac);
+
+ if(GPU_link_changed(stencil))
+ GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
+
+ GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
+ }
}
GPU_link(mat, "vec_math_negate", shi->vn, &orn);
@@ -1217,31 +1232,40 @@ int GPU_material_from_blender(Scene *scene, Material *ma)
void GPU_materials_free()
{
+ Object *ob;
Material *ma;
+ extern Material defmaterial;
- for(ma=G.main->mat.first; ma; ma=ma->id.next) {
- if(ma->gpumaterial) {
- GPU_material_free(ma->gpumaterial);
- ma->gpumaterial = NULL;
- }
- }
+ for(ma=G.main->mat.first; ma; ma=ma->id.next)
+ GPU_material_free(ma);
+
+ GPU_material_free(&defmaterial);
+
+ for(ob=G.main->object.first; ma; ma=ma->id.next)
+ GPU_lamp_free(ob);
}
/* Lamps and shadow buffers */
void GPU_lamp_update(GPULamp *lamp, float obmat[][4])
{
- VECCOPY(lamp->vec, obmat[2]);
- VECCOPY(lamp->co, obmat[3]);
- Mat4CpyMat4(lamp->obmat, obmat);
- Mat4Invert(lamp->imat, obmat);
+ float mat[4][4];
+
+ Mat4CpyMat4(mat, obmat);
+ Mat4Ortho(mat);
+
+ VECCOPY(lamp->vec, mat[2]);
+ VECCOPY(lamp->co, mat[3]);
+ Mat4CpyMat4(lamp->obmat, mat);
+ Mat4Invert(lamp->imat, mat);
}
-static void gpu_lamp_from_blender(Object *ob, Lamp *la, GPULamp *lamp)
+static void gpu_lamp_from_blender(Object *ob, Object *par, Lamp *la, GPULamp *lamp)
{
float temp, angle, pixsize, wsize;
lamp->ob = ob;
+ lamp->par = par;
lamp->la = la;
lamp->lay = ob->lay;
@@ -1290,65 +1314,83 @@ static void gpu_lamp_from_blender(Object *ob, Lamp *la, GPULamp *lamp)
i_window(-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend, lamp->winmat);
}
-int GPU_lamp_from_blender(Object *ob, Lamp *la)
+static void gpu_lamp_shadow_free(GPULamp *lamp)
{
+ if(lamp->tex)
+ GPU_texture_free(lamp->tex);
+ if(lamp->fb)
+ GPU_framebuffer_free(lamp->fb);
+}
+
+GPULamp *GPU_lamp_from_blender(Object *ob, Object *par)
+{
+ Lamp *la;
GPULamp *lamp;
+ LinkData *link;
- if(ob->gpulamp) {
- //gpu_lamp_from_blender(ob, la, ob->gpulamp);
- return 1;
- }
+ for(link=ob->gpulamp.first; link; link=link->next)
+ if(((GPULamp*)link->data)->par == par)
+ return link->data;
lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
- ob->gpulamp = lamp;
- gpu_lamp_from_blender(ob, la, lamp);
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ la = ob->data;
+ gpu_lamp_from_blender(ob, par, la, lamp);
if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
/* opengl */
lamp->fb = GPU_framebuffer_create();
if(!lamp->fb) {
- GPU_lamp_free(lamp);
- return 0;
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
}
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size);
if(!lamp->tex) {
- GPU_lamp_free(lamp);
- return 0;
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
}
if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex)) {
- GPU_lamp_free(lamp);
- return 0;
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
}
GPU_framebuffer_restore();
}
- return 1;
+ return lamp;
}
-void GPU_lamp_free(GPULamp *lamp)
+void GPU_lamp_free(Object *ob)
{
+ GPULamp *lamp;
+ LinkData *link;
LinkNode *nlink;
Material *ma;
- for(nlink=lamp->materials; nlink; nlink=nlink->next) {
- ma= nlink->link;
- if(ma->gpumaterial) {
- GPU_material_free(ma->gpumaterial);
- ma->gpumaterial= NULL;
+ for(link=ob->gpulamp.first; link; link=link->next) {
+ lamp = link->data;
+
+ for(nlink=lamp->materials; nlink; nlink=nlink->next) {
+ ma= nlink->link;
+ if(ma->gpumaterial) {
+ GPU_material_free(ma);
+ ma->gpumaterial= NULL;
+ }
}
- }
- BLI_linklist_free(lamp->materials, NULL);
+ BLI_linklist_free(lamp->materials, NULL);
- if(lamp->tex)
- GPU_texture_free(lamp->tex);
- if(lamp->fb)
- GPU_framebuffer_free(lamp->fb);
+ gpu_lamp_shadow_free(lamp);
+
+ MEM_freeN(lamp);
+ }
- MEM_freeN(lamp);
+ BLI_freelistN(&ob->gpulamp);
}
int GPU_lamp_has_shadow_buffer(GPULamp *lamp)