From c594a6f25c61decf091fa87ddf5b5ccfbeeb8e78 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 20 Aug 2008 16:29:55 +0000 Subject: Apricot Branch ============== * Make lights and shadows work better with dupligroups, also in the game engine. Previously only one dupli would be created, and shadows didn't work well at all. * Make normal maps + stencil work. * Some glsl refresh and default material fixes. --- source/blender/blenkernel/intern/material.c | 2 +- source/blender/blenkernel/intern/object.c | 4 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/gpu/GPU_material.h | 6 +- source/blender/gpu/intern/gpu_codegen.c | 6 +- source/blender/gpu/intern/gpu_draw.c | 7 +- source/blender/gpu/intern/gpu_material.c | 148 +++++++++++++-------- source/blender/makesdna/DNA_object_types.h | 2 +- source/blender/src/drawscene.c | 4 + source/blender/src/drawview.c | 90 +++++++------ source/blender/src/previewrender.c | 11 +- .../Converter/BL_BlenderDataConversion.cpp | 8 +- source/gameengine/Ketsji/KX_GameObject.cpp | 7 +- source/gameengine/Ketsji/KX_GameObject.h | 19 +++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 13 +- source/gameengine/Ketsji/KX_Light.cpp | 44 +++--- source/gameengine/Ketsji/KX_Light.h | 11 +- source/gameengine/Ketsji/KX_Scene.cpp | 4 + 18 files changed, 244 insertions(+), 144 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index db13be01c91..0e5769217ec 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -100,7 +100,7 @@ void free_material(Material *ma) } if(ma->gpumaterial) - GPU_material_free(ma->gpumaterial); + GPU_material_free(ma); } void init_material(Material *ma) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7430981952f..fa8a7ad67dc 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -270,7 +270,7 @@ void free_object(Object *ob) } if(ob->soft) sbFree(ob->soft); if(ob->fluidsimSettings) fluidsimSettingsFree(ob->fluidsimSettings); - if(ob->gpulamp) GPU_lamp_free(ob->gpulamp); + if(ob->gpulamp.first) GPU_lamp_free(ob); } static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin) @@ -1229,7 +1229,7 @@ Object *copy_object(Object *ob) obn->vnode = NULL; #endif - obn->gpulamp = NULL; + obn->gpulamp.first = obn->gpulamp.last = NULL; return obn; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f6616329031..ffed06bb545 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3400,7 +3400,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->bb= NULL; ob->derivedDeform= NULL; ob->derivedFinal= NULL; - ob->gpulamp= NULL; + ob->gpulamp.first= ob->gpulamp.last= NULL; } /* ************ READ SCENE ***************** */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 781e8c8c578..d9357a7a75e 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -120,7 +120,7 @@ GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]); /* High level functions to create and use GPU materials */ int GPU_material_from_blender(struct Scene *scene, struct Material *ma); -void GPU_material_free(GPUMaterial *material); +void GPU_material_free(struct Material *ma); void GPU_materials_free(); @@ -151,8 +151,8 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr); /* Lamps */ -int GPU_lamp_from_blender(struct Object *ob, struct Lamp *la); -void GPU_lamp_free(GPULamp *lamp); +GPULamp *GPU_lamp_from_blender(struct Object *ob, struct Object *par); +void GPU_lamp_free(struct Object *ob); int GPU_lamp_has_shadow_buffer(GPULamp *lamp); void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index d53e4fed7df..f6286f3f4be 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -362,10 +362,8 @@ void GPU_extensions_exit(void) { extern Material defmaterial; // render module abuse... - if(defmaterial.gpumaterial) { - GPU_material_free(defmaterial.gpumaterial); - defmaterial.gpumaterial = NULL; - } + if(defmaterial.gpumaterial) + GPU_material_free(&defmaterial); if(FUNCTION_HASH) { BLI_ghash_free(FUNCTION_HASH, NULL, (GHashValFreeFP)MEM_freeN); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index bf45def8b41..8db31738005 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -798,7 +798,12 @@ void GPU_set_object_materials(Scene *scene, Object *ob, int glsl, int *do_alpha_ QUATCOPY(GMS.matbuf[1][0], GMS.matbuf[0][0]); QUATCOPY(GMS.matbuf[1][1], GMS.matbuf[0][1]); - GMS.gmatbuf[0]= NULL; + if(glsl) { + GMS.gmatbuf[0]= &defmaterial; + GPU_material_from_blender(GMS.gscene, &defmaterial); + } + + GMS.blendmode[0]= GPU_BLEND_SOLID; } /* setup materials */ 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) diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 8b3a9f17367..35a59a7d717 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -225,7 +225,7 @@ typedef struct Object { void *vnode; /* pointer at object VerseNode */ /*#endif*/ - struct GPULamp *gpulamp; /* for lamps */ + ListBase gpulamp; /* runtime, for lamps only */ } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/blender/src/drawscene.c b/source/blender/src/drawscene.c index 124a09da3a2..ce8b9a1a70e 100644 --- a/source/blender/src/drawscene.c +++ b/source/blender/src/drawscene.c @@ -55,6 +55,8 @@ #include "BSE_view.h" +#include "GPU_material.h" + #include "radio.h" #include "blendef.h" /* old */ @@ -75,6 +77,8 @@ void set_scene(Scene *sce) /* also see scene.c: set_scene_bg() */ exit_paint_modes(); set_last_seq(NULL); + + GPU_materials_free(); G.scene= sce; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 79c94124499..4871562e1e5 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2928,67 +2928,83 @@ void draw_depth(ScrArea *sa, void *spacedata, int (* func)(void *)) static void draw_viewport_fps(ScrArea *sa); -static void gpu_render_lamp_update(View3D *v3d, Object *ob) -{ - Lamp *la; - float viewmat[4][4], winmat[4][4]; - int drawtype, lay, winsize, flag2; - - la= ob->data; - GPU_lamp_from_blender(ob, la); +typedef struct View3DShadow{ + struct View3DShadow*next, *prev; + GPULamp *lamp; +} View3DShadow; - if(ob->gpulamp) { - GPU_lamp_update(ob->gpulamp, ob->obmat); - - if(GPU_lamp_has_shadow_buffer(ob->gpulamp)) { - /* this needs to be done better .. */ - drawtype= v3d->drawtype; - lay= v3d->lay; - flag2= v3d->flag2 & V3D_SOLID_TEX; +static void gpu_render_lamp_update(View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows) +{ + GPULamp *lamp; + View3DShadow *shadow; - v3d->drawtype = OB_SOLID; - v3d->lay &= GPU_lamp_shadow_layer(ob->gpulamp); - v3d->flag2 &= ~V3D_SOLID_TEX; + lamp = GPU_lamp_from_blender(ob, par); - GPU_lamp_shadow_buffer_bind(ob->gpulamp, viewmat, &winsize, winmat); - drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1); - GPU_lamp_shadow_buffer_unbind(ob->gpulamp); + if(lamp) { + GPU_lamp_update(lamp, obmat); - v3d->drawtype= drawtype; - v3d->lay= lay; - v3d->flag2 |= flag2; + if(GPU_lamp_has_shadow_buffer(lamp)) { + shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow"); + shadow->lamp = lamp; + BLI_addtail(shadows, shadow); } } } -static void gpu_render_shadow_buffers(Scene *scene, View3D *v3d) +static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) { + ListBase shadows; + View3DShadow *shadow; Scene *sce; Base *base; Object *ob; + shadows.first= shadows.last= NULL; + + /* update lamp transform and gather shadow lamps */ for(SETLOOPER(G.scene, base)) { ob= base->object; if(ob->type == OB_LAMP) - gpu_render_lamp_update(v3d, ob); + gpu_render_lamp_update(v3d, ob, NULL, ob->obmat, &shadows); if (ob->transflag & OB_DUPLI) { DupliObject *dob; ListBase *lb = object_duplilist(G.scene, ob); - for(dob=lb->first; dob; dob=dob->next) { - Object *ob = dob->ob; - - if(ob->type==OB_LAMP) { - Mat4CpyMat4(ob->obmat, dob->mat); - gpu_render_lamp_update(v3d, ob); - } - } + for(dob=lb->first; dob; dob=dob->next) + if(dob->ob->type==OB_LAMP) + gpu_render_lamp_update(v3d, dob->ob, ob, dob->mat, &shadows); free_object_duplilist(lb); } } + + /* render shadows after updating all lamps, nested object_duplilist + * don't work correct since it's replacing object matrices */ + for(shadow=shadows.first; shadow; shadow=shadow->next) { + /* this needs to be done better .. */ + float viewmat[4][4], winmat[4][4]; + int drawtype, lay, winsize, flag2; + + drawtype= v3d->drawtype; + lay= v3d->lay; + flag2= v3d->flag2 & V3D_SOLID_TEX; + + v3d->drawtype = OB_SOLID; + v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp); + v3d->flag2 &= ~V3D_SOLID_TEX; + + GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); + drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1); + GPU_lamp_shadow_buffer_unbind(shadow->lamp); + + v3d->drawtype= drawtype; + v3d->lay= lay; + v3d->flag2 |= flag2; + } + + BLI_freelistN(&shadows); } void drawview3dspace(ScrArea *sa, void *spacedata) @@ -3016,7 +3032,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) /* shadow buffers, before we setup matrices */ if(draw_glsl_material(NULL, v3d->drawtype)) - gpu_render_shadow_buffers(G.scene, v3d); + gpu_update_lamps_shadows(G.scene, v3d); setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */ setviewmatrixview3d(); /* note: calls where_is_object for camera... */ @@ -3295,7 +3311,7 @@ void drawview3d_render(struct View3D *v3d, float viewmat[][4], int winx, int win /* shadow buffers, before we setup matrices */ if(!shadow && draw_glsl_material(NULL, v3d->drawtype)) - gpu_render_shadow_buffers(G.scene, v3d); + gpu_update_lamps_shadows(G.scene, v3d); if(!winmat) setwinmatrixview3d(winx, winy, NULL); diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 39e0b015ba2..88a37972a51 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -231,17 +231,15 @@ void BIF_preview_changed(short id_code) if(id_code == ID_WO) { for(ma=G.main->mat.first; ma; ma=ma->id.next) { if(ma->gpumaterial) { - GPU_material_free(ma->gpumaterial); - ma->gpumaterial= NULL; + GPU_material_free(ma); allqueue(REDRAWVIEW3D, 0); } } } else if(id_code == ID_LA) { for(ob=G.main->object.first; ob; ob=ob->id.next) { - if(ob->gpulamp) { - GPU_lamp_free(ob->gpulamp); - ob->gpulamp= NULL; + if(ob->gpulamp.first) { + GPU_lamp_free(ob); allqueue(REDRAWVIEW3D, 0); } } @@ -250,8 +248,7 @@ void BIF_preview_changed(short id_code) ma= give_current_material(ob, ob->actcol); if(ma && ma->gpumaterial) { - GPU_material_free(ma->gpumaterial); - ma->gpumaterial= NULL; + GPU_material_free(ma); allqueue(REDRAWVIEW3D, 0); } } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 748f26834cd..d2a64e0c70f 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1465,10 +1465,8 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l lightobj.m_type = RAS_LightObject::LIGHT_NORMAL; } - if(converter->GetGLSLMaterials()) - gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, ob); - else - gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, NULL); + gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, + lightobj, converter->GetGLSLMaterials()); BL_ConvertLampIpos(la, gamelight, converter); @@ -1506,7 +1504,7 @@ static KX_GameObject *gameobject_from_blenderobject( gamelight->AddRef(); kxscene->GetLightList()->Add(gamelight); - + break; } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index ae29db91a92..b98f7fe1b2f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -77,10 +77,11 @@ KX_GameObject::KX_GameObject( SCA_IObject(T), m_bDyna(false), m_layer(0), + m_pBlenderObject(NULL), + m_pBlenderGroupObject(NULL), m_bSuspendDynamics(false), m_bUseObjectColor(false), m_bIsNegativeScaling(false), - m_pBlenderObject(NULL), m_bVisible(true), m_bCulled(true), m_pPhysicsController1(NULL), @@ -286,11 +287,11 @@ void KX_GameObject::ProcessReplica(KX_GameObject* replica) CValue* KX_GameObject::GetReplica() { KX_GameObject* replica = new KX_GameObject(*this); - + // this will copy properties and so on... CValue::AddDataToReplica(replica); ProcessReplica(replica); - + return replica; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index f1ab2d85252..e91cd798264 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -74,6 +74,7 @@ protected: int m_layer; std::vector m_meshes; struct Object* m_pBlenderObject; + struct Object* m_pBlenderGroupObject; bool m_bSuspendDynamics; bool m_bUseObjectColor; @@ -394,6 +395,16 @@ public: { m_pBlenderObject = obj; } + + struct Object* GetBlenderGroupObject( ) + { + return m_pBlenderGroupObject; + } + + void SetBlenderGroupObject( struct Object* obj) + { + m_pBlenderGroupObject = obj; + } bool IsDupliGroup() { @@ -670,6 +681,14 @@ public: void ) { return m_bIsNegativeScaling; } + /** + * Is this a light? + */ + virtual bool + IsLight( + void + ) { return false; } + /** * @section Logic bubbling methods. */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 009592aa66a..ff3e5fc3fba 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -328,8 +328,6 @@ void KX_KetsjiEngine::EndFrame() m_canvas->EndDraw(); - - } //#include "PIL_time.h" @@ -904,11 +902,16 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam) void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) { - CListValue *lightlist = scene->GetLightList(); + CListValue *objectlist = scene->GetObjectList(); int i, drawmode; - for(i=0; iGetCount(); i++) { - KX_LightObject *light = (KX_LightObject*)lightlist->GetValue(i); + for(i=0; iGetCount(); i++) { + KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i); + + if(!gameobj->IsLight()) + continue; + + KX_LightObject *light = (KX_LightObject*)gameobj; light->Update(); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index cb4c4dcf624..f3102bb25d2 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -48,7 +48,7 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, - Object *gpulampob, + bool glsl, PyTypeObject* T ) : @@ -58,16 +58,12 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_lightobj = lightobj; m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); m_rendertools->AddLight(&m_lightobj); - m_gpulampob = gpulampob; - - if(m_gpulampob) - GPU_lamp_from_blender(m_gpulampob, (struct Lamp*)m_gpulampob->data); + m_glsl = glsl; }; KX_LightObject::~KX_LightObject() { - m_rendertools->RemoveLight(&m_lightobj); } @@ -75,7 +71,7 @@ CValue* KX_LightObject::GetReplica() { KX_LightObject* replica = new KX_LightObject(*this); - + // this will copy properties and so on... CValue::AddDataToReplica(replica); @@ -83,17 +79,23 @@ CValue* KX_LightObject::GetReplica() replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr(); m_rendertools->AddLight(&replica->m_lightobj); + return replica; } -bool KX_LightObject::VerifyShader() +GPULamp *KX_LightObject::GetGPULamp() { - return (m_gpulampob && m_gpulampob->gpulamp); + if(m_glsl) + return GPU_lamp_from_blender(GetBlenderObject(), GetBlenderGroupObject()); + else + return false; } void KX_LightObject::Update() { - if(VerifyShader()) { + GPULamp *lamp; + + if((lamp = GetGPULamp())) { float obmat[4][4]; double *dobmat = GetOpenGLMatrixPtr()->getPointer(); @@ -101,30 +103,39 @@ void KX_LightObject::Update() for(int j=0; j<4; j++, dobmat++) obmat[i][j] = (float)*dobmat; - GPU_lamp_update(m_gpulampob->gpulamp, obmat); + GPU_lamp_update(lamp, obmat); } } bool KX_LightObject::HasShadowBuffer() { - return (VerifyShader() && GPU_lamp_has_shadow_buffer(m_gpulampob->gpulamp)); + GPULamp *lamp; + + if((lamp = GetGPULamp())) + return GPU_lamp_has_shadow_buffer(lamp); + else + return false; } int KX_LightObject::GetShadowLayer() { - if(VerifyShader()) - return GPU_lamp_shadow_layer(m_gpulampob->gpulamp); + GPULamp *lamp; + + if((lamp = GetGPULamp())) + return GPU_lamp_shadow_layer(lamp); else return 0; } void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans) { + GPULamp *lamp; float viewmat[4][4], winmat[4][4]; int winsize; /* bind framebuffer */ - GPU_lamp_shadow_buffer_bind(m_gpulampob->gpulamp, viewmat, &winsize, winmat); + lamp = GetGPULamp(); + GPU_lamp_shadow_buffer_bind(lamp, viewmat, &winsize, winmat); /* setup camera transformation */ MT_Matrix4x4 modelviewmat((float*)viewmat); @@ -148,7 +159,8 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) { - GPU_lamp_shadow_buffer_unbind(m_gpulampob->gpulamp); + GPULamp *lamp = GetGPULamp(); + GPU_lamp_shadow_buffer_unbind(lamp); } PyObject* KX_LightObject::_getattr(const STR_String& attr) diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 1adc6793aec..aa7f0e796de 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -32,7 +32,7 @@ #include "RAS_LightObject.h" #include "KX_GameObject.h" -struct Object; +struct GPULamp; class KX_Camera; class RAS_IRasterizer; class RAS_IRenderTools; @@ -44,18 +44,17 @@ class KX_LightObject : public KX_GameObject protected: RAS_LightObject m_lightobj; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj - struct Object *m_gpulampob; + bool m_glsl; static char doc[]; - bool VerifyShader(); - public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct Object *gpulampob, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl, PyTypeObject *T = &Type); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} /* GLSL shadow */ + struct GPULamp *GetGPULamp(); bool HasShadowBuffer(); int GetShadowLayer(); void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans); @@ -64,6 +63,8 @@ public: virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */ virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + + virtual bool IsLight(void) { return true; } }; #endif //__KX_LIGHT diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 8a16609c966..a9651f014d1 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -654,6 +654,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) if (blgroupobj == blenderobj) // this check is also in group_duplilist() continue; + gameobj = (KX_GameObject*)m_logicmgr->FindGameObjByBlendObj(blenderobj); if (gameobj == NULL) { @@ -661,6 +662,9 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // Should not happen as dupli group are created automatically continue; } + + gameobj->SetBlenderGroupObject(blgroupobj); + if ((blenderobj->lay & group->layer)==0) { // object is not visible in the 3D view, will not be instantiated -- cgit v1.2.3