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:
authorErwin Coumans <blender@erwincoumans.com>2006-02-13 08:45:32 +0300
committerErwin Coumans <blender@erwincoumans.com>2006-02-13 08:45:32 +0300
commite4790aef46f7ca0b4ab01c34f043be9e7b1fa7f1 (patch)
tree0d83145e454cc7b5947ec657dbd9e415aac9d809 /source/gameengine/Ketsji
parent6c325d74f534d259820c2b2d94d5b73b3acf0a35 (diff)
Improved OpenGL Shader Language support for game engine. The python interface is much simplified. Drawback is that scripts need to be updated next release. Testfiles:
http://www.continuousphysics.com/ftp/pub/test/index.php?dir=blender/&file=demos-2.42.zip patch by Charlie Carley (snailrose @ elysiun.com)
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp20
-rw-r--r--source/gameengine/Ketsji/BL_Material.h20
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp512
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h86
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp402
-rw-r--r--source/gameengine/Ketsji/BL_Texture.h62
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp490
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h51
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp18
11 files changed, 1051 insertions, 614 deletions
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 29012904ea1..63ba0924b1c 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -54,6 +54,8 @@ BL_Material::BL_Material()
material_index = 0;
amb=0.5f;
num_enabled = 0;
+ num_users = 1;
+ share = false;
int i;
for(i=0; i<4; i++)
@@ -114,3 +116,21 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){
}
+void BL_Material::SetSharedMaterial(bool v)
+{
+ if((v && num_users == -1) || num_users > 1 )
+ share = true;
+ else
+ share = false;
+}
+
+bool BL_Material::IsShared()
+{
+ return share;
+}
+
+void BL_Material::SetUsers(int num)
+{
+ num_users = num;
+}
+
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index cf753414245..7a813cc6c72 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -20,7 +20,7 @@ struct EnvMap;
although the more you add the slower the search time will be.
we will go for three, which should be enough
*/
-#define MAXTEX 3//match in RAS_TexVert
+#define MAXTEX 3//match in RAS_TexVert & RAS_OpenGLRasterizer
// different mapping modes
class BL_Mapping
@@ -39,6 +39,10 @@ class BL_Material
private:
unsigned int rgb[4];
MT_Point2 uv[4];
+
+ int num_users;
+ bool share;
+
public:
// -----------------------------------
BL_Material();
@@ -82,6 +86,9 @@ public:
void SetConversionUV(MT_Point2 *uv);
void GetConversionUV(MT_Point2 *uv);
+ void SetSharedMaterial(bool v);
+ bool IsShared();
+ void SetUsers(int num);
};
// BL_Material::IdMode
@@ -132,9 +139,14 @@ enum BL_ras_mode
// BL_Material::mapping[index]::mapping
enum BL_MappingFlag
{
- USEREFL=1,
- USEENV=2,
- USEOBJ=4
+ USEENV =1,
+ // --
+ USEREFL =2,
+ USEOBJ =4,
+ USENORM =8,
+ USEORCO =16,
+ USEUV =32,
+ DISABLE =64
};
// BL_Material::BL_Mapping::projplane
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index f6aa8f625d6..bd9983a2ba7 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -23,6 +23,8 @@
#include "MEM_guardedalloc.h"
#include "RAS_GLExtensionManager.h"
+#include "RAS_MeshObject.h"
+#include "RAS_IRasterizer.h"
//using namespace bgl;
#define spit(x) std::cout << x << std::endl;
@@ -32,19 +34,20 @@ const bool BL_Shader::Ok()const
return (mShader !=0 && mOk && mUse);
}
+
BL_Shader::BL_Shader(PyTypeObject *T)
: PyObjectPlus(T),
mShader(0),
- mVert(0),
- mFrag(0),
mPass(1),
mOk(0),
mUse(0),
vertProg(""),
fragProg(""),
mError(0),
- mLog(0)
-
+ mAttr(0),
+ mPreDefLoc(-1),
+ mPreDefType(-1),
+ mDeleteTexture(0)
{
// if !RAS_EXT_support._ARB_shader_objects this class will not be used
@@ -53,7 +56,8 @@ BL_Shader::BL_Shader(PyTypeObject *T)
mSampler[i].pass = 0;
mSampler[i].unit = -1;
mSampler[i].loc = -1;
- mSampler[i].glTexture =0;
+ mSampler[i].gl_texture = 0;
+ mSampler[i].flag=0;
}
}
@@ -62,23 +66,18 @@ using namespace bgl;
BL_Shader::~BL_Shader()
{
#ifdef GL_ARB_shader_objects
- if(mLog) {
- MEM_freeN(mLog);
- mLog=0;
+ for (int i=0; i<MAXTEX; i++)
+ {
+ if(mSampler[i].flag & OWN)
+ {
+ if(mSampler[i].gl_texture)
+ mSampler[i].gl_texture->DeleteTex();
+ }
}
if( mShader ) {
bgl::blDeleteObjectARB(mShader);
mShader = 0;
}
- if( mFrag ) {
- bgl::blDeleteObjectARB(mFrag);
- mFrag = 0;
- }
- if( mVert ) {
- bgl::blDeleteObjectARB(mVert);
- mVert = 0;
- }
-
vertProg = 0;
fragProg = 0;
mOk = 0;
@@ -92,8 +91,8 @@ bool BL_Shader::LinkProgram()
{
#ifdef GL_ARB_shader_objects
- GLint vertlen = 0, fraglen=0, proglen=0;
- GLint vertstatus=0, fragstatus=0, progstatus=0;
+ int vertlen = 0, fraglen=0, proglen=0;
+ int vertstatus=0, fragstatus=0, progstatus=0;
unsigned int tmpVert=0, tmpFrag=0, tmpProg=0;
int char_len=0;
@@ -118,28 +117,44 @@ bool BL_Shader::LinkProgram()
bgl::blShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0);
bgl::blCompileShaderARB(tmpVert);
bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertlen);
+
// print info if any
- if( vertlen > 1){
- PrintInfo(vertlen,tmpVert, &char_len);
- goto programError;
+ if( vertlen > 0){
+ STR_String str("",vertlen);
+ bgl::blGetInfoLogARB(tmpVert, vertlen, &char_len, str.Ptr());
+ if(char_len >0) {
+ spit("---- Vertex Shader Error ----");
+ spit(str.ReadPtr());
+ }
+ str.Clear();
}
// check for compile errors
bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB, &vertstatus);
- if(!vertstatus)
+ if(!vertstatus) {
+ spit("---- Vertex shader failed to compile ----");
goto programError;
+ }
// -- fragment shader ----------------
tmpFrag = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
bgl::blShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0);
bgl::blCompileShaderARB(tmpFrag);
bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fraglen);
- if(fraglen >1 ){
- PrintInfo(fraglen,tmpFrag, &char_len);
- goto programError;
+ if(fraglen >0 ){
+ STR_String str("",fraglen);
+ bgl::blGetInfoLogARB(tmpFrag, fraglen, &char_len, str.Ptr());
+ if(char_len >0) {
+ spit("---- Fragment Shader Error ----");
+ spit(str.ReadPtr());
+ }
+ str.Clear();
}
+
bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, &fragstatus);
- if(!fragstatus)
+ if(!fragstatus){
+ spit("---- Fragment shader failed to compile ----");
goto programError;
+ }
// -- program ------------------------
@@ -150,22 +165,29 @@ bool BL_Shader::LinkProgram()
bgl::blLinkProgramARB(tmpProg);
bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, &proglen);
bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, &progstatus);
- if(!progstatus)
- goto programError;
+
if(proglen > 0) {
- // print success
- PrintInfo(proglen,tmpProg, &char_len);
- if(char_len >0)
- spit(mLog);
- mError = 0;
+ STR_String str("",proglen);
+ bgl::blGetInfoLogARB(tmpProg, proglen, &char_len, str.Ptr());
+ if(char_len >0) {
+ spit("---- GLSL Program ----");
+ spit(str.ReadPtr());
+ }
+ str.Clear();
+ }
+
+ if(!progstatus){
+ spit("---- GLSL program failed to link ----");
+ goto programError;
}
// set
mShader = tmpProg;
- mVert = tmpVert;
- mFrag = tmpFrag;
+ bgl::blDeleteObjectARB(tmpVert);
+ bgl::blDeleteObjectARB(tmpFrag);
mOk = 1;
+ mError = 0;
return true;
programError:
@@ -183,32 +205,15 @@ programError:
tmpProg=0;
}
- mOk = 0;
- mUse=0;
- mError = 1;
- spit("----------");
- spit("GLSL Error ");
- if(mLog)
- spit(mLog);
- spit("--------------------");
+ mOk = 0;
+ mUse = 0;
+ mError = 1;
return false;
#else
return false;
#endif//GL_ARB_shader_objects
}
-void BL_Shader::PrintInfo(int len, unsigned int handle, int* num)
-{
-#ifdef GL_ARB_shader_objects
- GLsizei number;
- mLog = (char*)MEM_mallocN(sizeof(char)*len, "print_log");
- //MT_assert(mLog, "Failed to create memory");
- bgl::blGetInfoLogARB(handle, len, &number, mLog);
- *num = number;
-#endif//GL_ARB_shader_objects
-}
-
-
char *BL_Shader::GetVertPtr()
{
return vertProg?vertProg:0;
@@ -234,34 +239,303 @@ unsigned int BL_Shader::GetProg()
return mShader;
}
-unsigned int BL_Shader::GetVertexShader()
-{
- return mVert;
-}
-
-unsigned int BL_Shader::GetFragmentShader()
-{
- return mFrag;
-}
-
const uSampler* BL_Shader::getSampler(int i)
{
MT_assert(i<=MAXTEX);
return &mSampler[i];
}
+void BL_Shader::SetSampler(int loc, int unit)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ bgl::blUniform1iARB(loc, unit);
+ }
+#endif
+}
+
+
void BL_Shader::InitializeSampler(
int type,
int unit,
int pass,
- unsigned int texture)
+ BL_Texture* texture)
{
MT_assert(unit<=MAXTEX);
- mSampler[unit].glTexture = texture;
+ mSampler[unit].gl_texture = texture;
mSampler[unit].loc =-1;
mSampler[unit].pass=0;
mSampler[unit].type=type;
mSampler[unit].unit=unit;
+ mSampler[unit].flag = 0;
+}
+
+
+void BL_Shader::SetProg(bool enable)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ if( mShader != 0 && mOk && enable) {
+ bgl::blUseProgramObjectARB(mShader);
+ }
+ else {
+ bgl::blUseProgramObjectARB(0);
+ }
+ }
+#endif
+}
+
+void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
+{
+#ifdef GL_ARB_shader_objects
+ if(!Ok()) return;
+
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ MT_Matrix4x4 model;
+ model.setValue(ms.m_OpenGLMatrix);
+ MT_Matrix4x4 view;
+ rasty->GetViewMatrix(view);
+ switch (mPreDefType)
+ {
+ case MODELMATRIX:
+ {
+ SetUniform(mPreDefLoc, model);
+ break;
+ }
+ case MODELMATRIX_TRANSPOSE:
+ {
+ SetUniform(mPreDefLoc, model, true);
+ break;
+ }
+ case MODELMATRIX_INVERSE:
+ {
+ model.invert();
+ SetUniform(mPreDefLoc, model);
+ break;
+ }
+ case MODELMATRIX_INVERSETRANSPOSE:
+ {
+ model.invert();
+ SetUniform(mPreDefLoc, model, true);
+ break;
+ }
+ case MODELVIEWMATRIX:
+ {
+ SetUniform(mPreDefLoc, view*model);
+ break;
+ }
+
+ case MODELVIEWMATRIX_TRANSPOSE:
+ {
+ MT_Matrix4x4 mat(view*model);
+ SetUniform(mPreDefLoc, mat, true);
+ break;
+ }
+ case MODELVIEWMATRIX_INVERSE:
+ {
+ MT_Matrix4x4 mat(view*model);
+ mat.invert();
+ SetUniform(mPreDefLoc, mat);
+ break;
+ }
+ case MODELVIEWMATRIX_INVERSETRANSPOSE:
+ {
+ MT_Matrix4x4 mat(view*model);
+ mat.invert();
+ SetUniform(mPreDefLoc, mat, true);
+ break;
+ }
+ case CAM_POS:
+ {
+ MT_Point3 pos(rasty->GetCameraPosition());
+ SetUniform(mPreDefLoc, pos);
+ break;
+ }
+ case VIEWMATRIX:
+ {
+ SetUniform(mPreDefLoc, view);
+ break;
+ }
+ case VIEWMATRIX_TRANSPOSE:
+ {
+ SetUniform(mPreDefLoc, view, true);
+ break;
+ }
+ case VIEWMATRIX_INVERSE:
+ {
+ view.invert();
+ SetUniform(mPreDefLoc, view);
+ break;
+ }
+ case VIEWMATRIX_INVERSETRANSPOSE:
+ {
+ view.invert();
+ SetUniform(mPreDefLoc, view, true);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif
+}
+
+
+int BL_Shader::GetAttribLocation(const STR_String& name)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ return bgl::blGetAttribLocationARB(mShader, name.ReadPtr());
+ }
+#endif
+ return -1;
+}
+
+void BL_Shader::BindAttribute(const STR_String& attr, int loc)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ bgl::blBindAttribLocationARB(mShader, loc, attr.ReadPtr());
+ }
+#endif
+}
+
+int BL_Shader::GetUniformLocation(const STR_String& name)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ return bgl::blGetUniformLocationARB(mShader, name.ReadPtr());
+ }
+#endif
+ return -1;
+}
+
+void BL_Shader::SetUniform(int uniform, const MT_Tuple2& vec)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ float value[2];
+ vec.getValue(value);
+ bgl::blUniform2fvARB(uniform, 1, value);
+ }
+#endif
+
+}
+
+void BL_Shader::SetUniform(int uniform, const MT_Tuple3& vec)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ float value[3];
+ vec.getValue(value);
+ bgl::blUniform3fvARB(uniform, 1, value);
+ }
+#endif
+}
+
+void BL_Shader::SetUniform(int uniform, const MT_Tuple4& vec)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ float value[4];
+ vec.getValue(value);
+ bgl::blUniform4fvARB(uniform, 1, value);
+ }
+#endif
+}
+
+void BL_Shader::SetUniform(int uniform, const unsigned int& val)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ bgl::blUniform1iARB(uniform, val);
+ }
+#endif
+}
+
+void BL_Shader::SetUniform(int uniform, const float& val)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ bgl::blUniform1fARB(uniform, val);
+ }
+#endif
+}
+
+void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ float value[16];
+ vec.getValue(value);
+ bgl::blUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value);
+ }
+#endif
+}
+
+void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose)
+{
+#ifdef GL_ARB_shader_objects
+ if( RAS_EXT_support._ARB_fragment_shader &&
+ RAS_EXT_support._ARB_vertex_shader &&
+ RAS_EXT_support._ARB_shader_objects
+ )
+ {
+ float value[9];
+ value[0] = vec[0][0]; value[1] = vec[1][0]; value[2] = vec[2][0];
+ value[3] = vec[0][1]; value[4] = vec[1][1]; value[5] = vec[2][1];
+ value[6] = vec[0][2]; value[7] = vec[1][2]; value[7] = vec[2][2];
+ bgl::blUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value);
+ }
+#endif
}
PyObject* BL_Shader::_getattr(const STR_String& attr)
@@ -289,9 +563,11 @@ PyMethodDef BL_Shader::Methods[] =
KX_PYMETHODTABLE( BL_Shader, setUniform2i ),
KX_PYMETHODTABLE( BL_Shader, setUniform3i ),
KX_PYMETHODTABLE( BL_Shader, setUniform4i ),
+ KX_PYMETHODTABLE( BL_Shader, setAttrib ),
KX_PYMETHODTABLE( BL_Shader, setUniformfv ),
KX_PYMETHODTABLE( BL_Shader, setUniformiv ),
+ KX_PYMETHODTABLE( BL_Shader, setUniformDef ),
KX_PYMETHODTABLE( BL_Shader, setSampler ),
KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ),
@@ -332,7 +608,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
// already set...
Py_Return;
}
-
char *v,*f;
int apply=0;
if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
@@ -360,11 +635,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
{
#ifdef GL_ARB_shader_objects
bgl::blDeleteObjectARB(mShader);
- bgl::blDeleteObjectARB(mFrag);
- bgl::blDeleteObjectARB(mVert);
mShader = 0;
- mFrag = 0;
- mVert = 0;
vertProg = 0;
fragProg = 0;
mOk = 0;
@@ -397,18 +668,26 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
Py_INCREF(Py_None);
return Py_None;
}
-
if(mShader==0) {
PyErr_Format(PyExc_TypeError, "invalid shader object");
return NULL;
}
- GLint stat = 0;
+ int stat = 0;
bgl::blValidateProgramARB(mShader);
bgl::blGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat);
- return PyInt_FromLong(0);
-#else
- Py_Return;
+
+ if(stat > 0) {
+ int char_len=0;
+ STR_String str("",stat);
+ bgl::blGetInfoLogARB(mShader, stat, &char_len, str.Ptr());
+ if(char_len >0) {
+ spit("---- GLSL Validation ----");
+ spit(str.ReadPtr());
+ }
+ str.Clear();
+ }
#endif//GL_ARB_shader_objects
+ Py_Return;
}
@@ -424,25 +703,22 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
int index=-1;
if(PyArg_ParseTuple(args, "si", &uniform, &index))
{
- if(mShader==0)
- {
+ if(mShader==0) {
PyErr_Format(PyExc_ValueError, "invalid shader object");
return NULL;
}
+
int loc= bgl::blGetUniformLocationARB(mShader, uniform);
- if( loc==-1 )
- {
+ if( loc==-1 ) {
spit("Invalid uniform value: " << uniform << ".");
Py_Return;
- }else
- {
+ }
+
+ else {
if(index <= MAXTEX)
- {
mSampler[index].loc = loc;
- }else
- {
+ else
spit("Invalid texture sample index: " << index);
- }
Py_Return;
}
}
@@ -990,3 +1266,63 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
Py_Return;
#endif//GL_ARB_shader_objects
}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" )
+{
+#ifdef GL_ARB_shader_objects
+ if(mError) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ int attr=0;
+ if(PyArg_ParseTuple(args, "i", &attr ))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ mAttr=SHD_TANGENT;
+ bgl::blUseProgramObjectARB(mShader);
+ bgl::blBindAttribLocationARB(mShader, mAttr, "Tangent");
+ Py_Return;
+ }
+ return NULL;
+#endif
+ Py_Return;
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
+{
+#ifdef GL_ARB_shader_objects
+ if(mError) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ char *uniform="";
+ int nloc;
+ if(PyArg_ParseTuple(args, "si",&uniform, &nloc))
+ {
+ if(mShader==0) {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= bgl::blGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ mPreDefLoc = loc;
+ mPreDefType = nloc;
+ Py_Return;
+ }
+ }
+ return NULL;
+
+#endif
+}
+
+
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index 25db6a0b9f4..6536fdc8175 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -3,6 +3,13 @@
#include "PyObjectPlus.h"
#include "BL_Material.h"
+#include "BL_Texture.h"
+// --
+#include "MT_Matrix4x4.h"
+#include "MT_Matrix3x3.h"
+#include "MT_Tuple2.h"
+#include "MT_Tuple3.h"
+#include "MT_Tuple4.h"
// -----------------------------------
// user state management
@@ -12,20 +19,26 @@ typedef struct uSampler
int pass;
int unit;
int loc;
- unsigned int glTexture;
+ BL_Texture* gl_texture;
+ int flag;
}uSampler;
#define SAMP_2D 1
#define SAMP_CUBE 2
+#define ATTRIBMAX 1
+
+// uSampler::flag;
+enum
+{
+ OWN=1
+};
// ----------------
class BL_Shader : public PyObjectPlus
{
Py_Header;
private:
- unsigned int mShader,
- mVert,
- mFrag;
+ unsigned int mShader;
int mPass;
bool mOk;
bool mUse;
@@ -33,14 +46,41 @@ private:
char* vertProg;
char* fragProg;
bool mError;
- char* mLog;
+
+ int mAttr;
+ int mPreDefLoc;
+ int mPreDefType;
+ bool mDeleteTexture;
bool LinkProgram();
- void PrintInfo( int len, unsigned int handle,int *num);
public:
BL_Shader(PyTypeObject *T=&Type);
virtual ~BL_Shader();
+ enum AttribTypes{
+ SHD_TANGENT =1
+ };
+
+ enum GenType {
+ MODELVIEWMATRIX,
+ MODELVIEWMATRIX_TRANSPOSE,
+ MODELVIEWMATRIX_INVERSE,
+ MODELVIEWMATRIX_INVERSETRANSPOSE,
+
+ // Model matrix
+ MODELMATRIX,
+ MODELMATRIX_TRANSPOSE,
+ MODELMATRIX_INVERSE,
+ MODELMATRIX_INVERSETRANSPOSE,
+
+ // View Matrix
+ VIEWMATRIX,
+ VIEWMATRIX_TRANSPOSE,
+ VIEWMATRIX_INVERSE,
+ VIEWMATRIX_INVERSETRANSPOSE,
+ CAM_POS
+ };
+
char* GetVertPtr();
char* GetFragPtr();
void SetVertPtr( char *vert );
@@ -53,18 +93,28 @@ public:
// ---
// access
const uSampler* getSampler(int i);
- const bool Ok()const;
+ void SetSampler(int loc, int unit);
+ const bool Ok()const;
unsigned int GetProg();
- unsigned int GetVertexShader();
- unsigned int GetFragmentShader();
-
- void InitializeSampler(
- int type,
- int unit,
- int pass,
- unsigned int texture
- );
+ void SetProg(bool enable);
+ int GetAttribute(){return mAttr;};
+
+ void InitializeSampler( int type, int unit, int pass, BL_Texture* texture );
+
+ void Update( const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty );
+
+ // form tuhopuu2
+ virtual int GetAttribLocation(const STR_String& name);
+ virtual void BindAttribute(const STR_String& attr, int loc);
+ virtual int GetUniformLocation(const STR_String& name);
+ virtual void SetUniform(int uniform, const MT_Tuple2& vec);
+ virtual void SetUniform(int uniform, const MT_Tuple3& vec);
+ virtual void SetUniform(int uniform, const MT_Tuple4& vec);
+ virtual void SetUniform(int uniform, const unsigned int& val);
+ virtual void SetUniform(int uniform, const float& val);
+ virtual void SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose=false);
+ virtual void SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose=false);
// -----------------------------------
// python interface
@@ -94,6 +144,10 @@ public:
KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix4 );
KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix3 );
+ KX_PYMETHOD_DOC( BL_Shader, setUniformDef );
+
+ KX_PYMETHOD_DOC( BL_Shader, setAttrib );
+
// these come from within the material buttons
// sampler2d/samplerCube work
KX_PYMETHOD_DOC( BL_Shader, setSampler);
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 7cabb65a3ba..4ff31b885ba 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -23,19 +23,22 @@
#include "BKE_image.h"
#include "BLI_blenlib.h"
-#include "RAS_GLExtensionManager.h"
+#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
+#include "RAS_OpenGLRasterizer/ARB_multitexture.h"
+#include "RAS_ICanvas.h"
+#include "RAS_Rect.h"
+
+#include "KX_GameObject.h"
+
using namespace bgl;
#define spit(x) std::cout << x << std::endl;
#include "MEM_guardedalloc.h"
-
-
extern "C" {
// envmaps
#include "IMB_imbuf.h"
-
void my_envmap_split_ima(EnvMap *env);
void my_free_envmapdata(EnvMap *env);
}
@@ -50,15 +53,14 @@ static int smaller_pow2(int num) {
return num;
}
-
-
BL_Texture::BL_Texture()
: mTexture(0),
mError(0),
mOk(0),
mNeedsDeleted(0),
mType(0),
- mName("")
+ mName(""),
+ mUnit(0)
{
// --
}
@@ -71,14 +73,14 @@ BL_Texture::~BL_Texture()
void BL_Texture::DeleteTex()
{
if( mNeedsDeleted ) {
- glDeleteTextures(1, (GLuint*)&(*mTexture));
+ glDeleteTextures(1, (GLuint*)&mTexture);
mNeedsDeleted = 0;
mOk = 0;
}
}
-bool BL_Texture::InitFromImage( Image *img, bool mipmap)
+bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
{
if(!img || img->ok==0 ) {
mError = true;
@@ -94,17 +96,20 @@ bool BL_Texture::InitFromImage( Image *img, bool mipmap)
return mOk;
}
}
- mTexture = &img->bindcode;
+ mTexture = img->bindcode;
+
mName = img->id.name;
- mType = BL_TEX2D;
-
+ mType = GL_TEXTURE_2D;
+ mUnit = unit;
+
// smoke em if we got em
- if (*mTexture != 0) {
- glBindTexture(GL_TEXTURE_2D, *mTexture );
+ if (mTexture != 0) {
+ glBindTexture(GL_TEXTURE_2D, mTexture );
Validate();
return mOk;
}
- glGenTextures(1, (GLuint*)mTexture);
+ mNeedsDeleted = 1;
+ glGenTextures(1, (GLuint*)&mTexture);
InitGLTex(img->ibuf->rect, img->ibuf->x, img->ibuf->y, mipmap);
Validate();
return mOk;
@@ -117,7 +122,7 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
return;
}
- glBindTexture(GL_TEXTURE_2D, *mTexture );
+ glBindTexture(GL_TEXTURE_2D, mTexture );
if( mipmap ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -141,7 +146,7 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
- glBindTexture(GL_TEXTURE_2D, *mTexture );
+ glBindTexture(GL_TEXTURE_2D, mTexture );
if( mipmap ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
@@ -158,7 +163,7 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
}
-bool BL_Texture::InitCubeMap( EnvMap *cubemap )
+bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap )
{
#ifdef GL_ARB_texture_cube_map
if(!RAS_EXT_support._ARB_texture_cube_map) {
@@ -186,13 +191,14 @@ bool BL_Texture::InitCubeMap( EnvMap *cubemap )
EnvMap *CubeMap = cubemap;
mNeedsDeleted = 1;
- mBlankTexture = 0;
- mType = BL_TEXCUBE;
- mTexture = &mBlankTexture;
+ mType = GL_TEXTURE_CUBE_MAP_ARB;
+ mTexture = 0;
mName = CubeMap->ima->id.name;
+ mUnit = unit;
- glGenTextures(1, (GLuint*)(mTexture));
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *mTexture );
+
+ glGenTextures(1, (GLuint*)&mTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture );
bool needs_split = false;
if(!CubeMap->cube[0]) needs_split = true;
@@ -202,72 +208,49 @@ bool BL_Texture::InitCubeMap( EnvMap *cubemap )
my_envmap_split_ima(CubeMap);
}
- int x = cubemap->ima->ibuf->x;
- int y = cubemap->ima->ibuf->y;
- unsigned int *data= (unsigned int *)malloc(x*y*sizeof(unsigned int));
+ int x = CubeMap->ima->ibuf->x;
+ int y = CubeMap->ima->ibuf->y;
// -----------------------------------
x = CubeMap->cube[0]->ibuf->x;
y = CubeMap->cube[0]->ibuf->y;
// check the first image, and assume the rest
- if (!is_pow2(x) || !is_pow2(y))
- {
+ if (!is_pow2(x) || !is_pow2(y)) {
spit("invalid envmap size please render with CubeRes @ power of two");
- free(data);
- data = 0;
+ my_free_envmapdata(CubeMap);
mError = true;
mOk = false;
return mOk;
}
- memcpy(data, CubeMap->cube[0]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- // -----------------------------------
- x = CubeMap->cube[1]->ibuf->x;
- y = CubeMap->cube[1]->ibuf->y;
- memcpy(data, CubeMap->cube[1]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- // -----------------------------------
- x = CubeMap->cube[2]->ibuf->x;
- y = CubeMap->cube[2]->ibuf->y;
- memcpy(data, CubeMap->cube[2]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- // -----------------------------------
- x = CubeMap->cube[3]->ibuf->x;
- y = CubeMap->cube[3]->ibuf->y;
- memcpy(data, CubeMap->cube[3]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- // -----------------------------------
- x = CubeMap->cube[4]->ibuf->x;
- y = CubeMap->cube[4]->ibuf->y;
- memcpy(data, CubeMap->cube[4]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- // -----------------------------------
- x = CubeMap->cube[5]->ibuf->x;
- y = CubeMap->cube[5]->ibuf->y;
- memcpy(data, CubeMap->cube[5]->ibuf->rect, (x*y*sizeof(unsigned int)));
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ /*
+ */
+
+#define SetCubeMapFace(face, num) \
+ glTexImage2D(face, 0,GL_RGBA, \
+ CubeMap->cube[num]->ibuf->x, \
+ CubeMap->cube[num]->ibuf->y, \
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, \
+ CubeMap->cube[num]->ibuf->rect)
+
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5);
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3);
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0);
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 1);
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 2);
+ SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 4);
glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT );
-
- if(data) {
- free(data);
- data = 0;
- }
+
if(needs_split) {
- // okay we allocated, swap back to orig and free used
cubemap->ima = CubeMap->ima;
my_free_envmapdata(CubeMap);
}
+
mOk = IsValid();
return mOk;
@@ -289,7 +272,7 @@ STR_String BL_Texture::GetName() const
bool BL_Texture::IsValid()
{
- return (mTexture && *mTexture!= 0)?glIsTexture(*mTexture)!=0:false;
+ return (mTexture!= 0)?glIsTexture(mTexture)!=0:false;
}
@@ -301,7 +284,7 @@ void BL_Texture::Validate()
bool BL_Texture::Ok()
{
- return ( mTexture?((!mError || mOk ) && *mTexture!= 0):0 );
+ return (mTexture!= 0);
}
@@ -310,15 +293,282 @@ unsigned int BL_Texture::GetTextureType() const
return mType;
}
+int BL_Texture::GetMaxUnits()
+{
+ GLint unit=0;
+#ifdef GL_ARB_multitexture
+ if(RAS_EXT_support._ARB_multitexture) {
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
+ return (MAXTEX>=unit?unit:MAXTEX);
+ }
+#endif
+ return 0;
+}
+
+void BL_Texture::ActivateFirst()
+{
+#ifdef GL_ARB_multitexture
+ if(RAS_EXT_support._ARB_multitexture)
+ bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
+#endif
+}
+
+void BL_Texture::ActivateUnit(int unit)
+{
+#ifdef GL_ARB_multitexture
+ if(RAS_EXT_support._ARB_multitexture) {
+ if(unit <= MAXTEX)
+ bgl::blActiveTextureARB(GL_TEXTURE0_ARB+unit);
+ }
+#endif
+}
+
-BL_Texture::operator const unsigned int () const
+void BL_Texture::DisableUnit()
{
- return mTexture? *mTexture:0;
+#ifdef GL_ARB_multitexture
+ if(RAS_EXT_support._ARB_multitexture)
+ bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
+#endif
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+#ifdef GL_ARB_texture_cube_map
+ if(RAS_EXT_support._ARB_texture_cube_map)
+ glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+#endif
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
}
-bool BL_Texture::SetGLTex(unsigned int tex)
+
+void BL_Texture::DisableAllTextures()
{
- return false;
+#ifdef GL_ARB_multitexture
+ glDisable(GL_BLEND);
+ for(int i=0; i<MAXTEX; i++) {
+ if(RAS_EXT_support._ARB_multitexture)
+ bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+#ifdef GL_ARB_texture_cube_map
+ if(RAS_EXT_support._ARB_texture_cube_map)
+ glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+#endif//GL_ARB_texture_cube_map
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ }
+#endif
+}
+
+
+void BL_Texture::ActivateTexture()
+{
+#ifdef GL_ARB_multitexture
+ if(RAS_EXT_support._ARB_multitexture)
+ bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
+#ifdef GL_ARB_texture_cube_map
+ if(mType == GL_TEXTURE_CUBE_MAP_ARB && RAS_EXT_support._ARB_texture_cube_map ) {
+ glDisable(GL_TEXTURE_2D);
+ glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTexture );
+ glEnable(GL_TEXTURE_CUBE_MAP_ARB);
+ } else
+#endif
+ {
+ glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ glBindTexture( GL_TEXTURE_2D, mTexture );
+ glEnable(GL_TEXTURE_2D);
+ }
+#endif
+}
+
+void BL_Texture::SetMapping(int mode)
+{
+
+ if(!(mode &USEREFL)) {
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ return;
+ }
+
+#ifdef GL_ARB_texture_cube_map
+ if( mType == GL_TEXTURE_CUBE_MAP_ARB &&
+ RAS_EXT_support._ARB_texture_cube_map &&
+ mode &USEREFL)
+ {
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glEnable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ return;
+ }
+ else
+#endif
+ {
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ }
+}
+
+
+void BL_Texture::setTexEnv(BL_Material *mat, bool modulate)
+{
+#ifndef GL_ARB_texture_env_combine
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ return;
+#else
+ if(modulate || !RAS_EXT_support._ARB_texture_env_combine){
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ return;
+ }
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
+
+ GLfloat blend_operand = GL_SRC_COLOR;
+ GLfloat blend_operand_prev = GL_SRC_COLOR;
+ GLfloat alphaOp = GL_SRC_ALPHA;
+
+ GLenum combiner = GL_COMBINE_RGB_ARB;
+ GLenum source0 = GL_SOURCE0_RGB_ARB;
+ GLenum source1 = GL_SOURCE1_RGB_ARB;
+ GLenum source2 = GL_SOURCE2_RGB_ARB;
+ GLenum op0 = GL_OPERAND0_RGB_ARB;
+ GLenum op1 = GL_OPERAND1_RGB_ARB;
+ GLenum op2 = GL_OPERAND2_RGB_ARB;
+
+ // switch to alpha combiners
+ if( mat->flag[mUnit] &TEXALPHA ) {
+ combiner = GL_COMBINE_ALPHA_ARB;
+ source0 = GL_SOURCE0_ALPHA_ARB;
+ source1 = GL_SOURCE1_ALPHA_ARB;
+ source2 = GL_SOURCE2_ALPHA_ARB;
+ op0 = GL_OPERAND0_ALPHA_ARB;
+ op1 = GL_OPERAND1_ALPHA_ARB;
+ op2 = GL_OPERAND2_ALPHA_ARB;
+ blend_operand = GL_SRC_ALPHA;
+ blend_operand_prev = GL_SRC_ALPHA;
+ // invert
+ if(mat->flag[mUnit] &TEXNEG) {
+ blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
+ blend_operand = GL_ONE_MINUS_SRC_ALPHA;
+ }
+ }
+ else {
+ if(mat->flag[mUnit] &TEXNEG) {
+ blend_operand_prev=GL_ONE_MINUS_SRC_COLOR;
+ blend_operand = GL_ONE_MINUS_SRC_COLOR;
+ }
+ }
+ bool using_alpha = false;
+
+ if(mat->flag[mUnit] &USEALPHA){
+ alphaOp = GL_ONE_MINUS_SRC_ALPHA;
+ using_alpha=true;
+ }
+ else if(mat->flag[mUnit] &USENEGALPHA){
+ alphaOp = GL_SRC_ALPHA;
+ using_alpha = true;
+ }
+
+ switch( mat->blend_mode[mUnit] ) {
+ case BLEND_MIX:
+ {
+ // ------------------------------
+ if(!using_alpha) {
+ GLfloat base_col[4];
+ base_col[0] = base_col[1] = base_col[2] = 0.f;
+ base_col[3] = 1.f-mat->color_blend[mUnit];
+ glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
+ }
+ glTexEnvf( GL_TEXTURE_ENV, combiner, GL_INTERPOLATE_ARB);
+ glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB);
+ glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
+ glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
+ glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
+ if(!using_alpha)
+ glTexEnvf( GL_TEXTURE_ENV, source2, GL_CONSTANT_ARB );
+ else
+ glTexEnvf( GL_TEXTURE_ENV, source2, GL_TEXTURE );
+
+ glTexEnvf( GL_TEXTURE_ENV, op2, alphaOp);
+ }break;
+ case BLEND_MUL:
+ {
+ // ------------------------------
+ glTexEnvf( GL_TEXTURE_ENV, combiner, GL_MODULATE);
+ glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB);
+ glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev);
+ glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
+ if(using_alpha)
+ glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
+ else
+ glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
+ }break;
+ case BLEND_ADD:
+ {
+ // ------------------------------
+ glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD_SIGNED_ARB);
+ glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
+ glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
+ glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
+ if(using_alpha)
+ glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
+ else
+ glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
+ }break;
+ case BLEND_SUB:
+ {
+ // ------------------------------
+ glTexEnvf( GL_TEXTURE_ENV, combiner, GL_SUBTRACT_ARB);
+ glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
+ glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
+ glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
+ glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
+ }break;
+ case BLEND_SCR:
+ {
+ // ------------------------------
+ glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD);
+ glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
+ glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
+ glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
+ if(using_alpha)
+ glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
+ else
+ glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
+ } break;
+ }
+ glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
+#endif //!GL_ARB_texture_env_combine
+}
+
+int BL_Texture::GetPow2(int n)
+{
+ if(!is_pow2(n))
+ n = smaller_pow2(n);
+
+ return n;
}
extern "C" {
@@ -384,7 +634,5 @@ void my_free_envmapdata(EnvMap *env)
}
-}
-
-unsigned int BL_Texture::mBlankTexture = 0;
+} // extern C
diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h
index 51bf7270d2d..2df14580e65 100644
--- a/source/gameengine/Ketsji/BL_Texture.h
+++ b/source/gameengine/Ketsji/BL_Texture.h
@@ -1,9 +1,20 @@
#ifndef __BL_TEXTURE_H__
#define __BL_TEXTURE_H__
+
#include <vector>
+#include <map>
+
+#include "MT_Matrix4x4.h"
+#include "KX_Camera.h"
+
// --
struct Image;
struct EnvMap;
+class BL_Material;
+class RTData;
+class RAS_Rect;
+class RAS_ICanvas;
+
// --
#include "STR_String.h"
@@ -11,14 +22,13 @@ class BL_Texture
{
private:
// -----------------------------------
- unsigned int* mTexture;
+ unsigned int mTexture;
bool mError;
bool mOk;
bool mNeedsDeleted;
unsigned int mType;
STR_String mName;
- static unsigned int mBlankTexture;
- std::vector<EnvMap*>mCubeMem;
+ int mUnit;
// -----------------------------------
void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap );
void InitGLTex(unsigned int *p,int x,int y,bool mipmap );
@@ -27,27 +37,45 @@ public:
BL_Texture();
~BL_Texture( );
- operator const unsigned int () const;
+ //operator const unsigned int () const;
bool Ok();
+ int GetUnit() {return mUnit;}
+ void SetUnit(int unit) {mUnit = unit;}
STR_String GetName() const;
unsigned int GetTextureType() const;
- void DeleteTex();
- bool InitFromImage( Image *img, bool mipmap);
- bool InitCubeMap( EnvMap *cubemap );
- //
- bool SetGLTex(unsigned int tex);
-
- void PopCubeMap();
- bool IsValid();
- void Validate();
-};
+ void DeleteTex();
-enum TexType{
- BL_TEX2D = 1,
- BL_TEXCUBE = 2
+ bool InitFromImage(int unit, Image *img, bool mipmap);
+ bool InitCubeMap(int unit,EnvMap *cubemap );
+
+ bool IsValid();
+ void Validate();
+
+ static void ActivateFirst();
+ static void DisableAllTextures();
+ static void ActivateUnit(int unit);
+ static int GetMaxUnits();
+ static int GetPow2(int x);
+
+ /** todo
+ void CreateRenderTexture(RAS_Rect r, RTData d);
+ void ReadDepth(RAS_Rect r, RTData d);
+ static void BeginDepth(RAS_ICanvas *can, RTData d);
+ static void EndDepth(RAS_ICanvas *can,RTData d);
+ void SetDepthMapping(MT_Matrix4x4& p, MT_Matrix4x4& m);
+ */
+
+ void ActivateTexture();
+ void SetMapping(int mode);
+ void DisableUnit();
+ void setTexEnv(BL_Material *mat, bool modulate=false);
};
+/* Render to texture support, managed by the scene
+ TODO
+*/
+
#endif//__BL_TEXTURE_H__
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index b530edbd17c..d416ef55613 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -91,13 +91,11 @@ KX_BlenderMaterial::KX_BlenderMaterial(
m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
// figure max
- #ifdef GL_ARB_multitexture
int enabled = mMaterial->num_enabled;
- mMaterial->num_enabled = enabled>=bgl::max_texture_units?bgl::max_texture_units:enabled;
- #else
- mMaterial->num_enabled=0;
- #endif
+ int max = BL_Texture::GetMaxUnits();
+ mMaterial->num_enabled = enabled>=max?max:enabled;
+ // base class
m_enabled = mMaterial->num_enabled;
// test the sum of the various modes for equality
@@ -114,7 +112,6 @@ KX_BlenderMaterial::KX_BlenderMaterial(
}
-
KX_BlenderMaterial::~KX_BlenderMaterial()
{
// cleanup work
@@ -132,204 +129,100 @@ TFace* KX_BlenderMaterial::GetTFace(void) const
void KX_BlenderMaterial::OnConstruction()
{
// for each unique material...
- #ifdef GL_ARB_multitexture
-/* will be used to switch textures
- if(!gTextureDict)
- gTextureDict = PyDict_New();
-*/
int i;
for(i=0; i<mMaterial->num_enabled; i++) {
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
- #ifdef GL_ARB_texture_cube_map
+ BL_Texture::ActivateUnit(i);
if( mMaterial->mapping[i].mapping & USEENV ) {
if(!RAS_EXT_support._ARB_texture_cube_map) {
spit("CubeMap textures not supported");
continue;
}
- if(!mTextures[i].InitCubeMap( mMaterial->cubemap[i] ) )
+ if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
spit("unable to initialize image("<<i<<") in "<<
mMaterial->matname<< ", image will not be available");
}
else {
- #endif//GL_ARB_texture_cube_map
if( mMaterial->img[i] ) {
- if( ! mTextures[i].InitFromImage(mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
+ 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");
}
- #ifdef GL_ARB_texture_cube_map
}
- #endif//GL_ARB_texture_cube_map
- /*PyDict_SetItemString(gTextureDict, mTextures[i].GetName().Ptr(), PyInt_FromLong(mTextures[i]));*/
}
- #endif//GL_ARB_multitexture
-
mBlendFunc[0] =0;
mBlendFunc[1] =0;
}
void KX_BlenderMaterial::OnExit()
{
- #ifdef GL_ARB_multitexture
-
- #ifdef GL_ARB_shader_objects
- if( RAS_EXT_support._ARB_shader_objects && mShader ) {
+ if( mShader ) {
//note, the shader here is allocated, per unique material
//and this function is called per face
- bgl::blUseProgramObjectARB(0);
+ mShader->SetProg(0);
delete mShader;
mShader = 0;
}
- #endif //GL_ARB_shader_objects
+ BL_Texture::ActivateFirst();
for(int i=0; i<mMaterial->num_enabled; i++) {
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
-
+ BL_Texture::ActivateUnit(i);
mTextures[i].DeleteTex();
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- #ifdef GL_ARB_texture_cube_map
- if(RAS_EXT_support._ARB_texture_cube_map)
- glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- #endif//GL_ARB_texture_cube_map
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ mTextures[i].DisableUnit();
}
-
- /*if (gTextureDict) {
- PyDict_Clear(gTextureDict);
- Py_DECREF(gTextureDict);
- gTextureDict = 0;
- }*/
-
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
-
- #ifdef GL_ARB_texture_cube_map
- if(RAS_EXT_support._ARB_texture_cube_map)
- glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- #endif//GL_ARB_texture_cube_map
-
- glDisable(GL_TEXTURE_2D);
- #endif//GL_ARB_multitexture
-
- // make sure multi texture units
- // revert back to blender...
- // --
if( mMaterial->tface )
set_tpage(mMaterial->tface);
}
-void KX_BlenderMaterial::DisableTexData()
+void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
{
- glDisable(GL_BLEND);
- #ifdef GL_ARB_multitexture
- int i=(MAXTEX>=bgl::max_texture_units?bgl::max_texture_units:MAXTEX)-1;
- for(; i>=0; i--) {
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- #ifdef GL_ARB_texture_cube_map
- if(RAS_EXT_support._ARB_texture_cube_map)
- glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- #endif//GL_ARB_texture_cube_map
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- }
- #endif//GL_ARB_multitexture
-}
-
-
-void KX_BlenderMaterial::setShaderData( bool enable )
-{
- #ifdef GL_ARB_multitexture
- #ifdef GL_ARB_shader_objects
-
MT_assert(RAS_EXT_support._ARB_shader_objects && mShader);
int i;
if( !enable || !mShader->Ok() ) {
// frame cleanup.
- bgl::blUseProgramObjectARB( 0 );
- DisableTexData();
+ mShader->SetProg(false);
+ BL_Texture::DisableAllTextures();
return;
}
- DisableTexData();
- bgl::blUseProgramObjectARB( mShader->GetProg() );
+ BL_Texture::DisableAllTextures();
+ mShader->SetProg(true);
+ BL_Texture::ActivateFirst();
+
// for each enabled unit
for(i=0; i<mMaterial->num_enabled; i++) {
-
const uSampler *samp = mShader->getSampler(i);
- if( samp->loc == -1 || samp->glTexture == 0 ) continue;
-
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
-
- #ifdef GL_ARB_texture_cube_map
- if( mMaterial->mapping[i].mapping &USEENV ) {
- glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, samp->glTexture /* mTextures[i]*/ );
- glEnable( GL_TEXTURE_CUBE_MAP_ARB );
- }
- else {
- #endif//GL_ARB_texture_cube_map
- glBindTexture( GL_TEXTURE_2D, samp->glTexture /*mTextures[i]*/ );
- glEnable( GL_TEXTURE_2D );
- #ifdef GL_ARB_texture_cube_map
- }
- #endif//GL_ARB_texture_cube_map
- // use a sampler
- bgl::blUniform1iARB(samp->loc, i );
+ BL_Texture *tex = samp->gl_texture;
+ if( samp->loc == -1 || !tex || !tex->Ok() )
+ continue;
+ tex->ActivateTexture();
+ mShader->SetSampler(samp->loc, i);
}
-
if(!mUserDefBlend) {
setDefaultBlending();
}else
{
- glEnable(GL_BLEND);
// tested to be valid enums
+ glEnable(GL_BLEND);
glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
}
-
- #endif//GL_ARB_shader_objects
- #endif//GL_ARB_multitexture
}
-void KX_BlenderMaterial::setTexData( bool enable )
+void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
{
- #ifdef GL_ARB_multitexture
- int i;
-
- #ifdef GL_ARB_shader_objects
- if(RAS_EXT_support._ARB_shader_objects) {
- // switch back to fixed func
- bgl::blUseProgramObjectARB( 0 );
- }
- #endif//GL_ARB_shader_objects
+ if(RAS_EXT_support._ARB_shader_objects && mShader)
+ mShader->SetProg(false);
- if( !enable ) {
- // frame cleanup.
- DisableTexData();
+ BL_Texture::DisableAllTextures();
+ if( !enable )
return;
- }
-
- DisableTexData();
+
+ BL_Texture::ActivateFirst();
if( mMaterial->IdMode == DEFAULT_BLENDER ) {
setDefaultBlending();
@@ -337,71 +230,40 @@ void KX_BlenderMaterial::setTexData( bool enable )
}
if( mMaterial->IdMode == TEXFACE ) {
-
// no material connected to the object
- if( mTextures[0] ) {
- if( !mTextures[0].Ok() ) return;
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
- glBindTexture( GL_TEXTURE_2D, mTextures[0] );
- glEnable(GL_TEXTURE_2D);
- setTextureEnvironment( -1 ); // modulate
- setEnvMap( (mMaterial->mapping[0].mapping &USEREFL)!=0 );
+ if( mTextures[0].Ok() ) {
+ mTextures[0].ActivateTexture();
+ mTextures[0].setTexEnv(0, true);
+ mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
setDefaultBlending();
}
return;
}
- // for each enabled unit
+ int mode = 0,i=0;
for(i=0; (i<mMaterial->num_enabled); i++) {
if( !mTextures[i].Ok() ) continue;
- bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
-
- #ifdef GL_ARB_texture_cube_map
- // use environment maps
- if( mMaterial->mapping[i].mapping &USEENV && RAS_EXT_support._ARB_texture_cube_map ) {
- glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTextures[i] );
- glEnable(GL_TEXTURE_CUBE_MAP_ARB);
- setTextureEnvironment( i );
-
- if( mMaterial->mapping[i].mapping &USEREFL )
- setEnvMap( true, true );
- else if(mMaterial->mapping[i].mapping &USEOBJ)
- setObjectMatrixData(i);
- else
- setTexMatrixData( i );
- }
- // 2d textures
- else {
- #endif//GL_ARB_texture_cube_map
- glBindTexture( GL_TEXTURE_2D, mTextures[i] );
- glEnable( GL_TEXTURE_2D );
- setTextureEnvironment( i );
-
- if( mMaterial->mapping[i].mapping &USEREFL ){
- setEnvMap( true );
- }
- else if(mMaterial->mapping[i].mapping &USEOBJ){
- setObjectMatrixData(i);
- }
- else {
- setTexMatrixData( i );
- }
+ mTextures[i].ActivateTexture();
+ mTextures[i].setTexEnv(mMaterial);
+ mode = mMaterial->mapping[i].mapping;
- #ifdef GL_ARB_texture_cube_map
- }
- #endif//GL_ARB_texture_cube_map
+ if(mode &USEOBJ)
+ setObjectMatrixData(i, ras);
+ else
+ mTextures[i].SetMapping(mode);
+
+ if(!(mode &USEOBJ))
+ setTexMatrixData( i );
}
+
if(!mUserDefBlend) {
setDefaultBlending();
- }else
- {
+ }
+ else {
glEnable(GL_BLEND);
- // tested to be valid enums
glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
}
-
- #endif//GL_ARB_multitexture
}
void
@@ -409,20 +271,25 @@ KX_BlenderMaterial::ActivatShaders(
RAS_IRasterizer* rasty,
TCachingInfo& cachingInfo)const
{
+ KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
+
+ // reset...
+ if(tmp->mMaterial->IsShared())
+ cachingInfo =0;
+
if (GetCachingInfo() != cachingInfo) {
- KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
if (!cachingInfo)
- tmp->setShaderData( false );
+ tmp->setShaderData( false, rasty);
cachingInfo = GetCachingInfo();
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) {
- tmp->setShaderData( true );
+ tmp->setShaderData( true, rasty);
rasty->EnableTextures(true);
}
else {
- tmp->setShaderData( false );
+ tmp->setShaderData( false, rasty);
rasty->EnableTextures(false);
}
@@ -463,12 +330,13 @@ KX_BlenderMaterial::ActivatShaders(
1.0
);
- // Lagan's patch...
- // added material factor
rasty->SetAmbient(mMaterial->amb);
if (mMaterial->material)
rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
+
+ tmp->applyTexGen(rasty);
+
}
void
@@ -477,20 +345,19 @@ KX_BlenderMaterial::ActivateMat(
TCachingInfo& cachingInfo
)const
{
+ KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
if (GetCachingInfo() != cachingInfo) {
- KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
-
if (!cachingInfo)
- tmp->setTexData( false );
+ tmp->setTexData( false,rasty );
cachingInfo = GetCachingInfo();
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
- tmp->setTexData( true );
+ tmp->setTexData( true,rasty );
rasty->EnableTextures(true);
}
else{
- tmp->setTexData( false );
+ tmp->setTexData( false,rasty);
rasty->EnableTextures(false);
}
@@ -526,15 +393,14 @@ KX_BlenderMaterial::ActivateMat(
mMaterial->matcolor[2]*mMaterial->emit,
1.0
);
-
- // Lagan's patch...
- // added material factor
rasty->SetAmbient(mMaterial->amb);
-
if (mMaterial->material)
rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
+
+ tmp->applyTexGen(rasty);
}
+
bool
KX_BlenderMaterial::Activate(
RAS_IRasterizer* rasty,
@@ -542,24 +408,20 @@ KX_BlenderMaterial::Activate(
)const
{
bool dopass = false;
- #ifdef GL_ARB_shader_objects
- if( RAS_EXT_support._ARB_shader_objects &&
- ( mShader && mShader->Ok() ) ) {
-
+ if( RAS_EXT_support._ARB_shader_objects && ( mShader && mShader->Ok() ) ) {
if( (mPass++) < mShader->getNumPass() ) {
ActivatShaders(rasty, cachingInfo);
dopass = true;
return dopass;
}
else {
- bgl::blUseProgramObjectARB( 0 );
+ mShader->SetProg(false);
mPass = 0;
dopass = false;
return dopass;
}
}
else {
- #endif//GL_ARB_shader_objects
switch (mPass++)
{
case 0:
@@ -571,143 +433,17 @@ KX_BlenderMaterial::Activate(
dopass = false;
break;
}
- #ifdef GL_ARB_shader_objects
}
- #endif//GL_ARB_shader_objects
return dopass;
}
-void KX_BlenderMaterial::setTextureEnvironment( int textureIndex )
+void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
{
-#ifndef GL_ARB_texture_env_combine
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- return;
-#else
- if(textureIndex == -1 || !RAS_EXT_support._ARB_texture_env_combine){
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- return;
- }
-
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
-
- GLfloat blend_operand = GL_SRC_COLOR;
- GLfloat blend_operand_prev = GL_SRC_COLOR;
-
- GLenum combiner = GL_COMBINE_RGB_ARB;
- GLenum source0 = GL_SOURCE0_RGB_ARB;
- GLenum source1 = GL_SOURCE1_RGB_ARB;
- GLenum source2 = GL_SOURCE2_RGB_ARB;
- GLenum op0 = GL_OPERAND0_RGB_ARB;
- GLenum op1 = GL_OPERAND1_RGB_ARB;
- GLenum op2 = GL_OPERAND2_RGB_ARB;
- GLfloat alphaOp = GL_SRC_ALPHA;
-
- // switch to alpha combiners
- if( (mMaterial->flag[textureIndex] &TEXALPHA) ) {
- combiner = GL_COMBINE_ALPHA_ARB;
- source0 = GL_SOURCE0_ALPHA_ARB;
- source1 = GL_SOURCE1_ALPHA_ARB;
- source2 = GL_SOURCE2_ALPHA_ARB;
- op0 = GL_OPERAND0_ALPHA_ARB;
- op1 = GL_OPERAND1_ALPHA_ARB;
- op2 = GL_OPERAND2_ALPHA_ARB;
- blend_operand = GL_SRC_ALPHA;
-
- // invert
- if(mMaterial->flag[textureIndex] &TEXNEG) {
- blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
- blend_operand = GL_ONE_MINUS_SRC_ALPHA;
- }
- }
- else {
- if(mMaterial->flag[textureIndex] &TEXNEG) {
- blend_operand_prev=GL_ONE_MINUS_SRC_COLOR;
- blend_operand = GL_ONE_MINUS_SRC_COLOR;
- }
- }
- bool using_alpha = false;
-
- if(mMaterial->flag[textureIndex] &USEALPHA){
- alphaOp = GL_ONE_MINUS_SRC_ALPHA;
- using_alpha=true;
- }
- else if(mMaterial->flag[textureIndex] &USENEGALPHA){
- alphaOp = GL_SRC_ALPHA;
- using_alpha = true;
- }
-
- switch( mMaterial->blend_mode[textureIndex] ) {
- case BLEND_MIX:
- {
- // ------------------------------
- if(!using_alpha) {
- GLfloat base_col[4];
- base_col[0] = base_col[1] = base_col[2] = 0.f;
- base_col[3] = 1.f-mMaterial->color_blend[textureIndex];
- glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
- }
- glTexEnvf( GL_TEXTURE_ENV, combiner, GL_INTERPOLATE_ARB);
- glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB);
- glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
- glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
- glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
- if(!using_alpha)
- glTexEnvf( GL_TEXTURE_ENV, source2, GL_CONSTANT_ARB );
- else
- glTexEnvf( GL_TEXTURE_ENV, source2, GL_TEXTURE );
-
- glTexEnvf( GL_TEXTURE_ENV, op2, alphaOp);
- }break;
- case BLEND_MUL:
- {
- // ------------------------------
- glTexEnvf( GL_TEXTURE_ENV, combiner, GL_MODULATE);
- glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB);
- glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev);
- glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
- if(using_alpha)
- glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
- else
- glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
- }break;
- case BLEND_ADD:
- {
- // ------------------------------
- glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD_SIGNED_ARB);
- glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
- glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
- glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
- if(using_alpha)
- glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
- else
- glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
- }break;
- case BLEND_SUB:
- {
- // ------------------------------
- glTexEnvf( GL_TEXTURE_ENV, combiner, GL_SUBTRACT_ARB);
- glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
- glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
- glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
- glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
- }break;
- case BLEND_SCR:
- {
- // ------------------------------
- glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD);
- glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB );
- glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev );
- glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE );
- if(using_alpha)
- glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp);
- else
- glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand);
- } break;
- }
- glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
-#endif //!GL_ARB_texture_env_combine
+ if(mShader && RAS_EXT_support._ARB_shader_objects)
+ mShader->Update(ms, rasty);
}
+
bool KX_BlenderMaterial::setDefaultBlending()
{
if( mMaterial->transp &TF_ADD) {
@@ -726,40 +462,6 @@ bool KX_BlenderMaterial::setDefaultBlending()
return false;
}
-void KX_BlenderMaterial::setEnvMap(bool val, bool cube)
-{
- #ifdef GL_ARB_texture_cube_map
- if( cube && RAS_EXT_support._ARB_texture_cube_map )
- {
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
- glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glEnable(GL_TEXTURE_GEN_R);
- }
- else {
- #endif//GL_ARB_texture_cube_map
- if( val ) {
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glEnable(GL_TEXTURE_GEN_R);
- }
- else {
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- }
- #ifdef GL_ARB_texture_cube_map
- }
- #endif//GL_ARB_texture_cube_map
-}
-
-
void KX_BlenderMaterial::setTexMatrixData(int i)
{
glMatrixMode(GL_TEXTURE);
@@ -791,17 +493,13 @@ static void GetProjPlane(BL_Material *mat, int index,int num, float*param)
param[2] = 1.f;
}
-
-void KX_BlenderMaterial::setObjectMatrixData(int i)
+void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras)
{
- // will work without cubemaps
- // but a cubemap will look the best
KX_GameObject *obj =
(KX_GameObject*)
mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame);
- if(!obj)
- return;
+ if(!obj) return;
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
@@ -824,9 +522,8 @@ void KX_BlenderMaterial::setObjectMatrixData(int i)
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
- float matr[16];
- glGetFloatv(GL_MODELVIEW_MATRIX, matr);
- MT_Matrix4x4 mvmat(matr);
+ MT_Matrix4x4 mvmat;
+ ras->GetViewMatrix(mvmat);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
@@ -846,6 +543,28 @@ void KX_BlenderMaterial::setObjectMatrixData(int i)
}
+void KX_BlenderMaterial::applyTexGen(RAS_IRasterizer *ras)
+{
+ if(mShader && RAS_EXT_support._ARB_shader_objects)
+ if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT);
+
+ for(int i=0; i<mMaterial->num_enabled; i++) {
+ int mode = mMaterial->mapping[i].mapping;
+
+ if( mode &(USEREFL|USEOBJ))
+ ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_GEN, i);
+ else if(mode &USEORCO)
+ ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_ORCO, i);
+ else if(mode &USENORM)
+ ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_NORM, i);
+ else if(mode &USEUV)
+ ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_UV1, i);
+ else
+ ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
+ }
+}
+
// ------------------------------------
void KX_BlenderMaterial::UpdateIPO(
@@ -877,9 +596,6 @@ PyMethodDef KX_BlenderMaterial::Methods[] =
KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ),
KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ),
KX_PYMETHODTABLE( KX_BlenderMaterial, setBlending ),
-// KX_PYMETHODTABLE( KX_BlenderMaterial, getTexture ),
-// KX_PYMETHODTABLE( KX_BlenderMaterial, setTexture ),
-
{NULL,NULL} //Sentinel
};
@@ -956,14 +672,15 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
mShader = new BL_Shader();
for(int i= 0; i<mMaterial->num_enabled; i++) {
if(mMaterial->mapping[i].mapping & USEENV )
- mShader->InitializeSampler(SAMP_CUBE, i, 0, mTextures[i]);
+ mShader->InitializeSampler(SAMP_CUBE, i, 0, &mTextures[i]);
else
- mShader->InitializeSampler(SAMP_2D, i, 0, mTextures[i]);
+ mShader->InitializeSampler(SAMP_2D, i, 0, &mTextures[i]);
}
mModified = true;
}
if(mShader && !mShader->GetError()) {
+ mMaterial->SetSharedMaterial(true);
Py_INCREF(mShader);
return mShader;
}else
@@ -992,6 +709,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
#endif//GL_ARB_shader_objects
}
+
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
{
return PyInt_FromLong( mMaterial->material_index );
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index a250dcf81c4..ad229509224 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -23,7 +23,7 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial
public:
// --------------------------------
KX_BlenderMaterial(
- class KX_Scene* scene, // light/obj list
+ class KX_Scene* scene,
BL_Material* mat,
bool skin,
int lightlayer,
@@ -34,25 +34,32 @@ public:
virtual ~KX_BlenderMaterial();
// --------------------------------
- virtual TCachingInfo GetCachingInfo(void) const
- {
- // --
+ virtual TCachingInfo GetCachingInfo(void) const {
return (void*) this;
}
- // --------------------------------
- virtual bool Activate(
+ virtual
+ bool Activate(
RAS_IRasterizer* rasty,
- TCachingInfo& cachingInfo) const;
+ TCachingInfo& cachingInfo
+ ) const;
+
+ virtual
+ void ActivateMeshSlot(
+ const KX_MeshSlot & ms,
+ RAS_IRasterizer* rasty
+ ) const;
void ActivateMat(
- RAS_IRasterizer* rasty,
- TCachingInfo& cachingInfo)const;
-
+ RAS_IRasterizer* rasty,
+ TCachingInfo& cachingInfo
+ )const;
+
void ActivatShaders(
RAS_IRasterizer* rasty,
- TCachingInfo& cachingInfo)const;
- // --------------------------------
+ TCachingInfo& cachingInfo
+ )const;
+
TFace* GetTFace(void) const;
@@ -73,36 +80,34 @@ public:
KX_PYMETHOD_DOC( KX_BlenderMaterial, setTexture );
KX_PYMETHOD_DOC( KX_BlenderMaterial, setBlending );
+
// --------------------------------
// pre calculate to avoid pops/lag at startup
virtual void OnConstruction( );
-
private:
BL_Material* mMaterial;
BL_Shader* mShader;
KX_Scene* mScene;
BL_Texture mTextures[MAXTEX]; // texture array
-
bool mUserDefBlend;
unsigned int mBlendFunc[2];
bool mModified;
+
// message centers
- void setTexData( bool enable );
- void setShaderData( bool enable );
+ void setTexData( bool enable,RAS_IRasterizer *ras);
+ void setShaderData( bool enable, RAS_IRasterizer *ras);
- void setTextureEnvironment( int textureIndex );
- void setEnvMap( bool val, bool cube=false);
- void setTexMatrixData(int i);
bool setDefaultBlending();
- void setObjectMatrixData(int i);
+ void setObjectMatrixData(int i, RAS_IRasterizer *ras);
+ void setTexMatrixData(int i);
+
+ void setLightData();
+ void applyTexGen(RAS_IRasterizer *ras);
// cleanup stuff
- void DisableTexData();
void OnExit();
- //void DisableNonEnabled();
- // --
mutable int mPass;
};
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 42e5d550e57..85fdc51826a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -449,6 +449,7 @@ KX_GameObject::MarkVisible(
}
}
+
void KX_GameObject::addLinearVelocity(const MT_Vector3& lin_vel,bool local)
{
if (m_pPhysicsController1)
@@ -1129,7 +1130,6 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
return NULL;
}
-
/* ---------------------------------------------------------------------
* Some stuff taken from the header
* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 98544cf14d0..0b65109cb8d 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -526,7 +526,6 @@ public:
void
);
-
/**
* Was this object marked visible? (only for the ewxplicit
* visibility system).
@@ -609,7 +608,6 @@ public:
KX_PYMETHOD(KX_GameObject,GetParent);
KX_PYMETHOD(KX_GameObject,GetPhysicsId);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
-
private :
/**
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 6f7b73ee4fa..ceb5da67877 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -73,6 +73,7 @@
#include "SND_DeviceManager.h"
#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
+#include "BL_Shader.h"
#include "KX_PyMath.h"
@@ -756,6 +757,23 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
KX_MACRO_addTypesToDict(d, BL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE);
+
+ /* 9. UniformTypes */
+ KX_MACRO_addTypesToDict(d, SHD_TANGENT, BL_Shader::SHD_TANGENT);
+ KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX, BL_Shader::MODELVIEWMATRIX);
+ KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_TRANSPOSE, BL_Shader::MODELVIEWMATRIX_TRANSPOSE);
+ KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSE, BL_Shader::MODELVIEWMATRIX_INVERSE);
+ KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSETRANSPOSE, BL_Shader::MODELVIEWMATRIX_INVERSETRANSPOSE);
+ KX_MACRO_addTypesToDict(d, MODELMATRIX, BL_Shader::MODELMATRIX);
+ KX_MACRO_addTypesToDict(d, MODELMATRIX_TRANSPOSE, BL_Shader::MODELMATRIX_TRANSPOSE);
+ KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSE, BL_Shader::MODELMATRIX_INVERSE);
+ KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSETRANSPOSE, BL_Shader::MODELMATRIX_INVERSETRANSPOSE);
+ KX_MACRO_addTypesToDict(d, VIEWMATRIX, BL_Shader::VIEWMATRIX);
+ KX_MACRO_addTypesToDict(d, VIEWMATRIX_TRANSPOSE, BL_Shader::VIEWMATRIX_TRANSPOSE);
+ KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSE, BL_Shader::VIEWMATRIX_INVERSE);
+ KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSETRANSPOSE, BL_Shader::VIEWMATRIX_INVERSETRANSPOSE);
+ KX_MACRO_addTypesToDict(d, CAM_POS, BL_Shader::CAM_POS);
+
// Check for errors
if (PyErr_Occurred())
{