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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-07-10 16:47:20 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-07-10 16:47:20 +0400
commit99fdf27af92b9bd9d05c108f2c2c8a240c5536bc (patch)
tree0e7d2c4b425a5d3906a7841e5919e384e0bc27a4 /source/gameengine/Ketsji
parent3d7358539df4526ffc2c2bbd40cf2001c5acf374 (diff)
Sync with Apricot Game Engine
============================= * Clean up and optimizations in skinned/deformed mesh code. * Compatibility fixes and clean up in the rasterizer. * Changes related to GLSL shadow buffers which should have no effect, to keep the code in sync with apricot.
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp80
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.h15
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp6
-rw-r--r--source/gameengine/Ketsji/BL_Material.h7
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp100
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h1
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp80
-rw-r--r--source/gameengine/Ketsji/KX_Light.h16
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp41
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h8
13 files changed, 313 insertions, 91 deletions
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 06e012123b1..dd45d522b9f 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -1,9 +1,11 @@
#include "DNA_customdata_types.h"
+#include "DNA_material_types.h"
#include "BL_BlenderShader.h"
+#include "BL_Material.h"
-#if 0
+#ifdef BLENDER_GLSL
#include "GPU_extensions.h"
#include "GPU_material.h"
#endif
@@ -13,29 +15,32 @@
const bool BL_BlenderShader::Ok()const
{
-#if 0
+#ifdef BLENDER_GLSL
return (mGPUMat != 0);
+#else
+ return 0;
#endif
-
- return false;
}
-BL_BlenderShader::BL_BlenderShader(struct Material *ma)
+BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
:
-#if 0
+#ifdef BLENDER_GLSL
mGPUMat(0),
#endif
- mBound(false)
+ mBound(false),
+ mLightLayer(lightlayer)
{
-#if 0
- if(ma)
- mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH);
+#ifdef BLENDER_GLSL
+ if(ma) {
+ GPU_material_from_blender(ma);
+ mGPUMat = ma->gpumaterial;
+ }
#endif
}
BL_BlenderShader::~BL_BlenderShader()
{
-#if 0
+#ifdef BLENDER_GLSL
if(mGPUMat) {
GPU_material_unbind(mGPUMat);
mGPUMat = 0;
@@ -43,16 +48,12 @@ BL_BlenderShader::~BL_BlenderShader()
#endif
}
-void BL_BlenderShader::ApplyShader()
-{
-}
-
void BL_BlenderShader::SetProg(bool enable)
{
-#if 0
+#ifdef BLENDER_GLSL
if(mGPUMat) {
if(enable) {
- GPU_material_bind(mGPUMat);
+ GPU_material_bind(mGPUMat, mLightLayer);
mBound = true;
}
else {
@@ -65,7 +66,7 @@ void BL_BlenderShader::SetProg(bool enable)
int BL_BlenderShader::GetAttribNum()
{
-#if 0
+#ifdef BLENDER_GLSL
GPUVertexAttribs attribs;
int i, enabled = 0;
@@ -82,17 +83,19 @@ int BL_BlenderShader::GetAttribNum()
enabled = BL_MAX_ATTRIB;
return enabled;
-#endif
-
+#else
return 0;
+#endif
}
-void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
+void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
{
-#if 0
+#ifdef BLENDER_GLSL
GPUVertexAttribs attribs;
int i, attrib_num;
+ ras->SetAttribNum(0);
+
if(!mGPUMat)
return;
@@ -109,14 +112,24 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
if(attribs.layer[i].glindex > attrib_num)
continue;
- if(attribs.layer[i].type == CD_MTFACE)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ if(attribs.layer[i].type == CD_MTFACE) {
+ if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
+ else
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ }
else if(attribs.layer[i].type == CD_TANGENT)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
else if(attribs.layer[i].type == CD_ORCO)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex);
else if(attribs.layer[i].type == CD_NORMAL)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex);
+ else if(attribs.layer[i].type == CD_MCOL)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex);
+ else
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex);
}
ras->EnableTextures(true);
@@ -128,8 +141,8 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
{
-#if 0
- float obmat[4][4], viewmat[4][4];
+#ifdef BLENDER_GLSL
+ float obmat[4][4], viewmat[4][4], viewinvmat[4][4];
if(!mGPUMat || !mBound)
return;
@@ -142,7 +155,20 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
model.getValue((float*)obmat);
view.getValue((float*)viewmat);
- GPU_material_bind_uniforms(mGPUMat, obmat, viewmat);
+ view.invert();
+ view.getValue((float*)viewinvmat);
+
+ GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat);
+#endif
+}
+
+bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
+{
+#ifdef BLENDER_GLSL
+ /* to avoid unneeded state switches */
+ return (blshader && mGPUMat == blshader->mGPUMat && mLightLayer == blshader->mLightLayer);
+#else
+ return true;
#endif
}
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h
index 4cab0e644c3..b758d1a9cba 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.h
+++ b/source/gameengine/Ketsji/BL_BlenderShader.h
@@ -2,7 +2,7 @@
#ifndef __BL_GPUSHADER_H__
#define __BL_GPUSHADER_H__
-#if 0
+#ifdef BLENDER_GLSL
#include "GPU_material.h"
#endif
@@ -12,7 +12,10 @@
#include "MT_Tuple3.h"
#include "MT_Tuple4.h"
+#include "RAS_IPolygonMaterial.h"
+
struct Material;
+class BL_Material;
#define BL_MAX_ATTRIB 16
@@ -23,22 +26,24 @@ struct Material;
class BL_BlenderShader
{
private:
-#if 0
+#ifdef BLENDER_GLSL
GPUMaterial *mGPUMat;
#endif
bool mBound;
+ int mLightLayer;
public:
- BL_BlenderShader(struct Material *ma);
+ BL_BlenderShader(struct Material *ma, int lightlayer);
virtual ~BL_BlenderShader();
const bool Ok()const;
void SetProg(bool enable);
- void ApplyShader();
- void SetTexCoords(class RAS_IRasterizer* ras);
int GetAttribNum();
+ void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty);
+
+ bool Equals(BL_BlenderShader *blshader);
};
#endif//__BL_GPUSHADER_H__
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index f5312ccd023..7e3d6984f19 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -105,7 +105,8 @@ void BL_Material::GetConversionRGB(unsigned int *nrgb) {
*nrgb = rgb[3];
}
-void BL_Material::SetConversionUV(MT_Point2 *nuv) {
+void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) {
+ uvName = name;
uv[0] = *nuv++;
uv[1] = *nuv++;
uv[2] = *nuv++;
@@ -118,7 +119,8 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){
*nuv++ = uv[2];
*nuv = uv[3];
}
-void BL_Material::SetConversionUV2(MT_Point2 *nuv) {
+void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) {
+ uv2Name = name;
uv2[0] = *nuv++;
uv2[1] = *nuv++;
uv2[2] = *nuv++;
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index ddb6662830a..568f7e171de 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -83,13 +83,16 @@ public:
MT_Point2 uv[4];
MT_Point2 uv2[4];
+ STR_String uvName;
+ STR_String uv2Name;
+
void SetConversionRGB(unsigned int *rgb);
void GetConversionRGB(unsigned int *rgb);
- void SetConversionUV(MT_Point2 *uv);
+ void SetConversionUV(const STR_String& name, MT_Point2 *uv);
void GetConversionUV(MT_Point2 *uv);
- void SetConversionUV2(MT_Point2 *uv);
+ void SetConversionUV2(const STR_String& name, MT_Point2 *uv);
void GetConversionUV2(MT_Point2 *uv);
void SetSharedMaterial(bool v);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 02b1ffd432a..0f445a9f32e 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -38,6 +38,8 @@ extern "C" {
// ------------------------------------
#define spit(x) std::cout << x << std::endl;
+BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
+
//static PyObject *gTextureDict = 0;
KX_BlenderMaterial::KX_BlenderMaterial(
@@ -126,32 +128,31 @@ void KX_BlenderMaterial::OnConstruction()
// when material are reused between objects
return;
- if(mMaterial->glslmat) {
+ if(mMaterial->glslmat)
SetBlenderGLSLShader();
- }
- else {
- // for each unique material...
- int i;
- for(i=0; i<mMaterial->num_enabled; i++) {
- if( mMaterial->mapping[i].mapping & USEENV ) {
- if(!GLEW_ARB_texture_cube_map) {
- spit("CubeMap textures not supported");
- continue;
- }
- if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
+
+ // for each unique material...
+ int i;
+ for(i=0; i<mMaterial->num_enabled; i++) {
+ if( mMaterial->mapping[i].mapping & USEENV ) {
+ if(!GLEW_ARB_texture_cube_map) {
+ spit("CubeMap textures not supported");
+ continue;
+ }
+ if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
+ spit("unable to initialize image("<<i<<") in "<<
+ mMaterial->matname<< ", image will not be available");
+ }
+
+ else {
+ if( mMaterial->img[i] ) {
+ if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
spit("unable to initialize image("<<i<<") in "<<
- mMaterial->matname<< ", image will not be available");
- }
-
- else {
- if( mMaterial->img[i] ) {
- if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
- spit("unable to initialize image("<<i<<") in "<<
- mMaterial->matname<< ", image will not be available");
- }
+ mMaterial->matname<< ", image will not be available");
}
}
}
+
mBlendFunc[0] =0;
mBlendFunc[1] =0;
mConstructed = true;
@@ -168,7 +169,11 @@ void KX_BlenderMaterial::OnExit()
}
if( mBlenderShader ) {
- mBlenderShader->SetProg(false);
+ if(mBlenderShader == mLastBlenderShader) {
+ mBlenderShader->SetProg(false);
+ mLastBlenderShader = NULL;
+ }
+
delete mBlenderShader;
mBlenderShader = 0;
}
@@ -225,14 +230,23 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
{
if( !enable || !mBlenderShader->Ok() ) {
// frame cleanup.
- mBlenderShader->SetProg(false);
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
BL_Texture::DisableAllTextures();
return;
}
- BL_Texture::DisableAllTextures();
- mBlenderShader->SetProg(true);
- mBlenderShader->ApplyShader();
+ if(!mBlenderShader->Equals(mLastBlenderShader)) {
+ BL_Texture::DisableAllTextures();
+
+ if(mLastBlenderShader)
+ mLastBlenderShader->SetProg(false);
+
+ mBlenderShader->SetProg(true);
+ mLastBlenderShader= mBlenderShader;
+ }
}
void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
@@ -298,7 +312,12 @@ KX_BlenderMaterial::ActivatShaders(
// reset...
if(tmp->mMaterial->IsShared())
cachingInfo =0;
-
+
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
+
if (GetCachingInfo() != cachingInfo) {
if (!cachingInfo)
@@ -372,7 +391,7 @@ KX_BlenderMaterial::ActivateBlenderShaders(
}
ActivatGLMaterials(rasty);
- mBlenderShader->SetTexCoords(rasty);
+ mBlenderShader->SetAttribs(rasty, mMaterial);
}
void
@@ -382,6 +401,12 @@ KX_BlenderMaterial::ActivateMat(
)const
{
KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
+
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
+
if (GetCachingInfo() != cachingInfo) {
if (!cachingInfo)
tmp->setTexData( false,rasty );
@@ -460,17 +485,29 @@ KX_BlenderMaterial::Activate(
return dopass;
}
+bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
+{
+ if(!RAS_IPolyMaterial::UsesLighting(rasty))
+ return false;
+
+ if(mShader && mShader->Ok());
+ else if(mBlenderShader && mBlenderShader->Ok())
+ return false;
+
+ return true;
+}
+
void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
{
if(mShader && GLEW_ARB_shader_objects)
mShader->Update(ms, rasty);
- if(mBlenderShader && GLEW_ARB_shader_objects)
+ else if(mBlenderShader && GLEW_ARB_shader_objects)
mBlenderShader->Update(ms, rasty);
}
void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
{
- if(!mBlenderShader) {
+ if(mShader || !mBlenderShader) {
rasty->SetSpecularity(
mMaterial->speccolor[0]*mMaterial->spec_f,
mMaterial->speccolor[1]*mMaterial->spec_f,
@@ -506,6 +543,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
ras->SetAttribNum(0);
if(mShader && GLEW_ARB_shader_objects) {
if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) {
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0);
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1);
ras->SetAttribNum(2);
}
@@ -793,7 +831,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
void KX_BlenderMaterial::SetBlenderGLSLShader(void)
{
if(!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mMaterial->material);
+ mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer);
if(!mBlenderShader->Ok()) {
delete mBlenderShader;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 62e96b71937..bf6d2095e7c 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -94,6 +94,7 @@ private:
BL_Material* mMaterial;
BL_Shader* mShader;
BL_BlenderShader* mBlenderShader;
+ static BL_BlenderShader *mLastBlenderShader;
KX_Scene* mScene;
BL_Texture mTextures[MAXTEX]; // texture array
bool mUserDefBlend;
@@ -106,6 +107,7 @@ private:
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
void ActivateTexGen( RAS_IRasterizer *ras ) const;
+ bool UsesLighting(RAS_IRasterizer *rasty) const;
// message centers
void setTexData( bool enable,RAS_IRasterizer *ras);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index db13d30e2f1..2ac4f909077 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -1306,7 +1306,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
return meshproxy;
}
}
- return NULL;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 56a06786679..20187a193ba 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -55,6 +55,7 @@
#include "KX_Scene.h"
#include "MT_CmMatrix4x4.h"
#include "KX_Camera.h"
+#include "KX_Light.h"
#include "KX_PythonInit.h"
#include "KX_PyConstraintBinding.h"
#include "PHY_IPhysicsEnvironment.h"
@@ -614,6 +615,9 @@ void KX_KetsjiEngine::Render()
// pass the scene's worldsettings to the rasterizer
SetWorldSettings(scene->GetWorldInfo());
+ // shadow buffers
+ RenderShadowBuffers(scene);
+
// Avoid drawing the scene with the active camera twice when it's viewport is enabled
if(cam && !cam->GetViewport())
{
@@ -885,8 +889,48 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
viewport.GetTop()
);
-}
+}
+
+void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
+{
+ CListValue *lightlist = scene->GetLightList();
+ int i, drawmode;
+ for(i=0; i<lightlist->GetCount(); i++) {
+ KX_LightObject *light = (KX_LightObject*)lightlist->GetValue(i);
+
+ light->Update();
+
+ if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
+ /* make temporary camera */
+ RAS_CameraData camdata = RAS_CameraData();
+ KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false);
+ cam->SetName("__shadow__cam__");
+
+ MT_Transform camtrans;
+
+ /* switch drawmode for speed */
+ drawmode = m_rasterizer->GetDrawingMode();
+ m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
+
+ /* binds framebuffer object, sets up camera .. */
+ light->BindShadowBuffer(m_rasterizer, cam, camtrans);
+
+ /* update scene */
+ scene->UpdateMeshTransformations();
+ scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
+
+ /* render */
+ m_rasterizer->ClearDepthBuffer();
+ scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+ /* unbind framebuffer object, restore drawmode, free camera */
+ light->UnbindShadowBuffer(m_rasterizer);
+ m_rasterizer->SetDrawingMode(drawmode);
+ cam->Release();
+ }
+ }
+}
// update graphics
void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 4c09bc3fcd5..77b69ec2d9e 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -179,6 +179,7 @@ private:
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
void PostRenderFrame();
void RenderDebugProperties();
+ void RenderShadowBuffers(KX_Scene *scene);
void SetBackGround(KX_WorldInfo* worldinfo);
void SetWorldSettings(KX_WorldInfo* worldinfo);
void DoSound(KX_Scene* scene);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 7decc5bc769..4e3d6180d22 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -36,14 +36,20 @@
#endif
#include "KX_Light.h"
+#include "KX_Camera.h"
+#include "RAS_IRasterizer.h"
#include "RAS_IRenderTools.h"
#include "KX_PyMath.h"
+#ifdef BLENDER_GLSL
+#include "GPU_material.h"
+#endif
KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
class RAS_IRenderTools* rendertools,
const RAS_LightObject& lightobj,
+ struct GPULamp *gpulamp,
PyTypeObject* T
)
:
@@ -53,12 +59,12 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
m_lightobj = lightobj;
m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr();
m_rendertools->AddLight(&m_lightobj);
+ m_gpulamp = gpulamp;
};
KX_LightObject::~KX_LightObject()
{
-
m_rendertools->RemoveLight(&m_lightobj);
}
@@ -78,6 +84,78 @@ CValue* KX_LightObject::GetReplica()
return replica;
}
+void KX_LightObject::Update()
+{
+#ifdef BLENDER_GLSL
+ if(m_gpulamp) {
+ float obmat[4][4];
+ double *dobmat = GetOpenGLMatrixPtr()->getPointer();
+
+ for(int i=0; i<4; i++)
+ for(int j=0; j<4; j++, dobmat++)
+ obmat[i][j] = (float)*dobmat;
+
+ GPU_lamp_update(m_gpulamp, obmat);
+ }
+#endif
+}
+
+bool KX_LightObject::HasShadowBuffer()
+{
+#ifdef BLENDER_GLSL
+ return (m_gpulamp && GPU_lamp_has_shadow_buffer(m_gpulamp));
+#else
+ return false;
+#endif
+}
+
+int KX_LightObject::GetShadowLayer()
+{
+#ifdef BLENDER_GLSL
+ if(m_gpulamp)
+ return GPU_lamp_shadow_layer(m_gpulamp);
+ else
+#endif
+ return 0;
+}
+
+void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans)
+{
+#ifdef BLENDER_GLSL
+ float viewmat[4][4], winmat[4][4];
+ int winsize;
+
+ /* bind framebuffer */
+ GPU_lamp_shadow_buffer_bind(m_gpulamp, viewmat, &winsize, winmat);
+
+ /* setup camera transformation */
+ MT_Matrix4x4 modelviewmat((float*)viewmat);
+ MT_Matrix4x4 projectionmat((float*)winmat);
+
+ MT_Transform trans = MT_Transform((float*)viewmat);
+ camtrans.invert(trans);
+
+ cam->SetModelviewMatrix(modelviewmat);
+ cam->SetProjectionMatrix(projectionmat);
+
+ cam->NodeSetLocalPosition(camtrans.getOrigin());
+ cam->NodeSetLocalOrientation(camtrans.getBasis());
+ cam->NodeUpdateGS(0,true);
+
+ /* setup rasterizer transformations */
+ ras->SetProjectionMatrix(projectionmat);
+ ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(),
+ cam->GetCameraLocation(), cam->GetCameraOrientation());
+#endif
+}
+
+void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
+{
+#ifdef BLENDER_GLSL
+ GPU_lamp_shadow_buffer_unbind(m_gpulamp);
+#endif
+}
+
PyObject* KX_LightObject::_getattr(const STR_String& attr)
{
if (attr == "layer")
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 236d3e4e12e..62eb26c61a8 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -32,19 +32,33 @@
#include "RAS_LightObject.h"
#include "KX_GameObject.h"
+struct GPULamp;
+class KX_Camera;
+class RAS_IRasterizer;
+class RAS_IRenderTools;
+class MT_Transform;
+
class KX_LightObject : public KX_GameObject
{
Py_Header;
protected:
RAS_LightObject m_lightobj;
class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj
+ struct GPULamp *m_gpulamp;
static char doc[];
public:
- KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, PyTypeObject *T = &Type);
+ KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct GPULamp *gpulamp, PyTypeObject *T = &Type);
virtual ~KX_LightObject();
virtual CValue* GetReplica();
RAS_LightObject* GetLightData() { return &m_lightobj;}
+
+ /* GLSL shadow */
+ bool HasShadowBuffer();
+ int GetShadowLayer();
+ void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
+ void UnbindShadowBuffer(class RAS_IRasterizer *ras);
+ void Update();
virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index c5f6230b2f2..065800379d8 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -888,6 +888,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
else if (bHasArmature)
{
BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
+ newobj,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
true,
@@ -899,7 +900,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
else if (bHasDvert)
{
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
- oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
+ newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
);
newobj->m_pDeformer = meshdeformer;
}
@@ -1004,12 +1005,13 @@ void KX_Scene::UpdateMeshTransformations()
}
}
-void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam)
+void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer)
{
int intersect = KX_Camera::INTERSECT;
KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
- bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right();
-
+ bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer)));
+ bool dotest = visible || node->Left() || node->Right();
+
/* If the camera is inside the box, assume intersect. */
if (dotest && !node->inside( cam->NodeGetWorldPosition()))
{
@@ -1033,19 +1035,19 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam
break;
case KX_Camera::INTERSECT:
if (gameobj)
- MarkVisible(rasty, gameobj,cam);
+ MarkVisible(rasty, gameobj, cam, layer);
if (node->Left())
- MarkVisible(node->Left(), rasty,cam);
+ MarkVisible(node->Left(), rasty, cam, layer);
if (node->Right())
- MarkVisible(node->Right(), rasty,cam);
+ MarkVisible(node->Right(), rasty, cam, layer);
break;
case KX_Camera::INSIDE:
- MarkSubTreeVisible(node, rasty, true,cam);
+ MarkSubTreeVisible(node, rasty, true, cam, layer);
break;
}
}
-void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam)
+void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer)
{
if (node->Client())
{
@@ -1068,16 +1070,23 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
}
}
if (node->Left())
- MarkSubTreeVisible(node->Left(), rasty, visible,cam);
+ MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer);
if (node->Right())
- MarkSubTreeVisible(node->Right(), rasty, visible,cam);
+ MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer);
}
-void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam)
+void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam,int layer)
{
// User (Python/Actuator) has forced object invisible...
if (!gameobj->GetVisible())
return;
+
+ // Shadow lamp layers
+ if(layer && !(gameobj->GetLayer() & layer)) {
+ gameobj->MarkVisible(false);
+ return;
+ }
+
// If Frustum culling is off, the object is always visible.
bool vis = !cam->GetFrustumCulling();
@@ -1127,20 +1136,20 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
}
}
-void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam)
+void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
{
// FIXME: When tree is operational
#if 1
// do this incrementally in the future
for (int i = 0; i < m_objectlist->GetCount(); i++)
{
- MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam);
+ MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
}
#else
if (cam->GetFrustumCulling())
- MarkVisible(m_objecttree, rasty, cam);
+ MarkVisible(m_objecttree, rasty, cam, layer);
else
- MarkSubTreeVisible(m_objecttree, rasty, true, cam);
+ MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer);
#endif
}
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 733df2f69a1..28dee1b5893 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -260,9 +260,9 @@ protected:
/**
* Visibility testing functions.
*/
- void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam);
- void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam);
- void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam);
+ void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0);
+ void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0);
+ void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0);
double m_suspendedtime;
double m_suspendeddelta;
@@ -483,7 +483,7 @@ public:
void SetNetworkScene(NG_NetworkScene *newScene);
void SetWorldInfo(class KX_WorldInfo* wi);
KX_WorldInfo* GetWorldInfo();
- void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam);
+ void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam, int layer=0);
void UpdateMeshTransformations();
KX_Camera* GetpCamera();
SND_Scene* GetSoundScene();