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-01-08 12:37:15 +0300
committerErwin Coumans <blender@erwincoumans.com>2006-01-08 12:37:15 +0300
commitc94455c14d28221f6e05f33ba42e23a5d3245a28 (patch)
tree733dfaccbbcd71cf66e2d33b1868f64f78189eeb /source/gameengine/Ketsji
parent88a8508b347dda050557e72dfad105023e5095aa (diff)
more linux game engine work. hopefully works now!
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp132
-rw-r--r--source/gameengine/Ketsji/BL_Material.h155
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp914
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h117
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp389
-rw-r--r--source/gameengine/Ketsji/BL_Texture.h53
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp2
-rw-r--r--source/gameengine/Ketsji/SConscript5
8 files changed, 1765 insertions, 2 deletions
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
new file mode 100644
index 00000000000..b77750c1644
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -0,0 +1,132 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+
+#include <iostream>
+
+#include "BL_Material.h"
+#include "MT_assert.h"
+
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+MTex* getImageFromMaterial(Material *mat, int index)
+{
+ if(!mat) return 0;
+
+ if(!(index >=0 && index <=10) ) return 0;
+
+ MTex *m = mat->mtex[index];
+ return m?m:0;
+}
+
+int getNumTexChannels( Material *mat )
+{
+ int count = -1;
+ if(!mat) return -1;
+
+ for(count =0; (count < 10) && mat->mtex[count] != 0; count++) {}
+ return count;
+}
+
+BL_Material::BL_Material()
+{
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+ rgb[3] = 0;
+ IdMode = 0;
+ ras_mode = 0;
+ tile = 0;
+ matname = "NoMaterial";
+ matcolor[0] = 0.5f;
+ matcolor[1] = 0.5f;
+ matcolor[2] = 0.5f;
+ matcolor[3] = 0.5f;
+ speccolor[0] = 1.f;
+ speccolor[1] = 1.f;
+ speccolor[2] = 1.f;
+ transp = 0;
+ hard = 50.f;
+ spec_f = 0.5f;
+ alpha = 1.f;
+ emit = 0.f;
+ mode = 0;
+ material = 0;
+ tface = 0;
+ material_index = 0;
+ amb=0.5f;
+ num_enabled = 0;
+
+ int i;
+ for(i=0; i<4; i++)
+ uv[i] = MT_Point2(0.f,1.f);
+
+ for(i=0; i<MAXTEX; i++) // :(
+ {
+ mapping[i].mapping = 0;
+ mapping[i].offsets[0] = 0.f;
+ mapping[i].offsets[1] = 0.f;
+ mapping[i].offsets[2] = 0.f;
+ mapping[i].scale[0] = 1.f;
+ mapping[i].scale[1] = 1.f;
+ mapping[i].scale[2] = 1.f;
+ mapping[i].projplane[0] = PROJX;
+ mapping[i].projplane[1] = PROJY;
+ mapping[i].projplane[2] = PROJZ;
+ mapping[i].objconame = "";
+ mtexname[i] = "NULL";
+ imageId[i]="NULL";
+ flag[i] = 0;
+ texname[i] = "NULL";
+ tilexrep[i] = 1;
+ tileyrep[i] = 1;
+ color_blend[i] = 1.f;
+ blend_mode[i] = 0;
+ img[i] = 0;
+ cubemap[i] = 0;
+ }
+}
+
+void BL_Material::SetConversionRGB(unsigned int *nrgb) {
+ rgb[0]=*nrgb++;
+ rgb[1]=*nrgb++;
+ rgb[2]=*nrgb++;
+ rgb[3]=*nrgb;
+}
+
+void BL_Material::GetConversionRGB(unsigned int *nrgb) {
+ *nrgb++ = rgb[0];
+ *nrgb++ = rgb[1];
+ *nrgb++ = rgb[2];
+ *nrgb = rgb[3];
+}
+
+void BL_Material::SetConversionUV(MT_Point2 *nuv) {
+ uv[0] = *nuv++;
+ uv[1] = *nuv++;
+ uv[2] = *nuv++;
+ uv[3] = *nuv;
+}
+
+void BL_Material::GetConversionUV(MT_Point2 *nuv){
+ *nuv++ = uv[0];
+ *nuv++ = uv[1];
+ *nuv++ = uv[2];
+ *nuv = uv[3];
+}
+
+
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
new file mode 100644
index 00000000000..a55756addb8
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -0,0 +1,155 @@
+#ifndef __BL_MATERIAL_H__
+#define __BL_MATERIAL_H__
+
+#include "STR_String.h"
+#include "MT_Point2.h"
+
+// --
+struct MTex;
+struct Material;
+struct Image;
+struct TFace;
+struct MTex;
+struct Material;
+struct EnvMap;
+// --
+
+/** max units
+ this will default to users available units
+ to build with more available, just increment this value
+ 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
+
+// different mapping modes
+class BL_Mapping
+{
+public:
+ int mapping;
+ float scale[3];
+ float offsets[3];
+ int projplane[3];
+ STR_String objconame;
+};
+
+// base material struct
+class BL_Material
+{
+private:
+ unsigned int rgb[4];
+ MT_Point2 uv[4];
+public:
+ // -----------------------------------
+ BL_Material();
+
+ int IdMode;
+ unsigned int ras_mode;
+
+ STR_String texname[MAXTEX];
+ unsigned int flag[MAXTEX];
+ int tile,tilexrep[MAXTEX],tileyrep[MAXTEX];
+ STR_String matname;
+ STR_String mtexname[MAXTEX];
+
+ float matcolor[4];
+ float speccolor[3];
+ short transp, pad;
+
+ float hard, spec_f;
+ float alpha, emit, color_blend[MAXTEX], ref;
+ float amb;
+
+ int blend_mode[MAXTEX];
+
+ int mode;
+ int num_enabled;
+
+ int material_index;
+
+ BL_Mapping mapping[MAXTEX];
+ STR_String imageId[MAXTEX];
+
+
+ Material* material;
+ TFace* tface;
+ Image* img[MAXTEX];
+ EnvMap* cubemap[MAXTEX];
+
+ void SetConversionRGB(unsigned int *rgb);
+ void GetConversionRGB(unsigned int *rgb);
+
+ void SetConversionUV(MT_Point2 *uv);
+ void GetConversionUV(MT_Point2 *uv);
+
+};
+
+// BL_Material::IdMode
+enum BL_IdMode {
+ DEFAULT_BLENDER=-1,
+ TEXFACE,
+ ONETEX,
+ TWOTEX,
+ GREATERTHAN2
+};
+
+// BL_Material::blend_mode[index]
+enum BL_BlendMode
+{
+ BLEND_MIX=1,
+ BLEND_ADD,
+ BLEND_SUB,
+ BLEND_MUL,
+ BLEND_SCR
+};
+
+// -------------------------------------
+// BL_Material::flag[index]
+enum BL_flag
+{
+ MIPMAP=1, // set to use mipmaps
+ CALCALPHA=2, // additive
+ USEALPHA=4, // use actual alpha channel
+ TEXALPHA=8, // use alpha combiner functions
+ TEXNEG=16, // negate blending
+ HASIPO=32
+};
+
+// BL_Material::ras_mode
+enum BL_ras_mode
+{
+ POLY_VIS=1,
+ COLLIDER=2,
+ ZSORT=4,
+ TRANSP=8,
+ TRIANGLE=16,
+ USE_LIGHT=32
+};
+
+// -------------------------------------
+// BL_Material::mapping[index]::mapping
+enum BL_MappingFlag
+{
+ USEREFL=1,
+ USEENV=2,
+ USEOBJ=4
+};
+
+// BL_Material::BL_Mapping::projplane
+enum BL_MappingProj
+{
+ PROJN=0,
+ PROJX,
+ PROJY,
+ PROJZ
+};
+
+// ------------------------------------
+//extern void initBL_Material(BL_Material* mat);
+extern MTex* getImageFromMaterial(Material *mat, int index);
+extern int getNumTexChannels( Material *mat );
+// ------------------------------------
+
+#endif
+
+
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
new file mode 100644
index 00000000000..ec804228f61
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -0,0 +1,914 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+
+#include <iostream>
+#include "BL_Shader.h"
+#include "BL_Material.h"
+
+#include "MT_assert.h"
+#include "MT_Matrix4x4.h"
+#include "MT_Matrix3x3.h"
+#include "KX_PyMath.h"
+
+#include "RAS_GLExtensionManager.h"
+
+//using namespace bgl;
+#define spit(x) std::cout << x << std::endl;
+
+
+const bool BL_Shader::Ok()const
+{
+ return (mShader !=0 && mOk && mUse);
+}
+
+BL_Shader::BL_Shader(int n, PyTypeObject *T)
+: PyObjectPlus(T),
+ mShader(0),
+ mVert(0),
+ mFrag(0),
+ mPass(1),
+ vertProg(""),
+ fragProg(""),
+ mOk(0),
+ mUse(0)
+{
+ // if !RAS_EXT_support._ARB_shader_objects this class will not be used
+
+ mBlending.src = -1;
+ mBlending.dest = -1;
+ mBlending.const_color[0] = 0.0;
+ mBlending.const_color[1] = 0.0;
+ mBlending.const_color[2] = 0.0;
+ mBlending.const_color[3] = 1.0;
+
+ for (int i=0; i<MAXTEX; i++)
+ {
+ mSampler[i].type = 0;
+ mSampler[i].pass = 0;
+ mSampler[i].unit = -1;
+ mSampler[i].loc = -1;
+ mSampler[i].glTexture =0;
+ }
+}
+
+using namespace bgl;
+
+BL_Shader::~BL_Shader()
+{
+#ifdef GL_ARB_shader_objects
+ if( mShader ) {
+ glDeleteObjectARB(mShader);
+ mShader = 0;
+ }
+ if( mFrag ) {
+ glDeleteObjectARB(mFrag);
+ mFrag = 0;
+ }
+ if( mVert ) {
+ glDeleteObjectARB(mVert);
+ mVert = 0;
+ }
+
+ vertProg = 0;
+ fragProg = 0;
+ mOk = 0;
+
+ glUseProgramObjectARB(0);
+#endif//GL_ARB_shader_objects
+}
+
+
+bool BL_Shader::LinkProgram()
+{
+#ifdef GL_ARB_shader_objects
+ if(!vertProg || !fragProg ) return false;
+
+ int vertstat,fragstat,progstat;
+
+ // vertex prog
+ unsigned int vert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ glShaderSourceARB(vert, 1, (const char**) &vertProg, 0);
+ glCompileShaderARB(vert);
+ glGetObjectParameterivARB(vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertstat);
+ // errors if any
+ printInfo(vert);
+
+ // fragment prog
+ unsigned int frag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ glShaderSourceARB(frag, 1,(const char**) &fragProg, 0);
+ glCompileShaderARB(frag);
+ glGetObjectParameterivARB(frag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fragstat);
+ // errors if any
+ printInfo(frag);
+
+ if(!vertstat || !fragstat) return false;
+
+ // main prog
+ unsigned int prog = glCreateProgramObjectARB();
+ glAttachObjectARB(prog,vert);
+ glAttachObjectARB(prog,frag);
+
+ glLinkProgramARB(prog);
+ glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &progstat);
+ // info on how it compiled &| linked
+ printInfo(prog);
+
+ if(!progstat)
+ return false;
+
+ // assign
+ mShader = prog;
+ mVert = vert;
+ mFrag = frag;
+ mOk = 1;
+ return true;
+#else
+ return false;
+#endif//GL_ARB_shader_objects
+}
+
+void BL_Shader::printInfo(unsigned int pr)
+{
+#ifdef GL_ARB_shader_objects
+#ifndef GLcharARB
+typedef char GLcharARB;
+#endif
+int length=0;
+ glGetObjectParameterivARB(pr, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
+
+ if(length > 1)
+ {
+ GLcharARB*logger = (GLcharARB*)malloc(sizeof(GLcharARB)*length);
+ int chars=0;
+
+ glGetInfoLogARB(pr, length, &chars, logger);
+ if(chars>0)
+ std::cout << (logger) << std::endl;
+
+ if(logger)
+ free(logger);
+ }
+#endif//GL_ARB_shader_objects
+}
+
+char *BL_Shader::GetVertPtr()
+{
+ return vertProg?vertProg:0;
+}
+
+char *BL_Shader::GetFragPtr()
+{
+ return fragProg?fragProg:0;
+}
+
+void BL_Shader::SetVertPtr( char *vert )
+{
+ vertProg = vert;
+}
+
+void BL_Shader::SetFragPtr( char *frag )
+{
+ fragProg = frag;
+}
+
+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];
+}
+
+const uBlending *BL_Shader::getBlending( int pass )
+{
+ return &mBlending;
+}
+
+
+
+void BL_Shader::InitializeSampler(
+ int type,
+ int unit,
+ int pass,
+ unsigned int texture)
+{
+ MT_assert(unit<=MAXTEX);
+ mSampler[unit].glTexture = texture;
+ mSampler[unit].loc =-1;
+ mSampler[unit].pass=0;
+ mSampler[unit].type=type;
+ mSampler[unit].unit=unit;
+}
+
+PyObject* BL_Shader::_getattr(const STR_String& attr)
+{
+ _getattr_up(PyObjectPlus);
+}
+
+
+PyMethodDef BL_Shader::Methods[] =
+{
+ // creation
+ KX_PYMETHODTABLE( BL_Shader, setSource ),
+ KX_PYMETHODTABLE( BL_Shader, delSource ),
+ KX_PYMETHODTABLE( BL_Shader, getVertexProg ),
+ KX_PYMETHODTABLE( BL_Shader, getFragmentProg ),
+ KX_PYMETHODTABLE( BL_Shader, setNumberOfPasses ),
+ KX_PYMETHODTABLE( BL_Shader, validate),
+ /// access functions
+ KX_PYMETHODTABLE( BL_Shader, isValid),
+ KX_PYMETHODTABLE( BL_Shader, setUniform1f ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform2f ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform3f ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform4f ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform1i ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform2i ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform3i ),
+ KX_PYMETHODTABLE( BL_Shader, setUniform4i ),
+
+ KX_PYMETHODTABLE( BL_Shader, setUniformfv ),
+ KX_PYMETHODTABLE( BL_Shader, setUniformiv ),
+
+ KX_PYMETHODTABLE( BL_Shader, setSampler ),
+ KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ),
+ KX_PYMETHODTABLE( BL_Shader, setUniformMatrix3 ),
+ // KX_PYMETHODTABLE( BL_Shader, setBlending ),
+
+ {NULL,NULL} //Sentinel
+};
+
+
+PyTypeObject BL_Shader::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "BL_Shader",
+ sizeof(BL_Shader),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0,
+ __repr,
+ 0
+};
+
+
+PyParentObject BL_Shader::Parents[] = {
+ &PyObjectPlus::Type,
+ &BL_Shader::Type,
+ NULL
+};
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" )
+{
+#ifdef GL_ARB_shader_objects
+ if(mShader !=0 && mOk )
+ {
+ // already set...
+ Py_Return;
+ }
+
+ char *v,*f;
+ int apply=0;
+ if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
+ {
+ vertProg = v;
+ fragProg = f;
+ if( LinkProgram() )
+ {
+ glUseProgramObjectARB( mShader );
+ mUse = apply!=0;
+ Py_Return;
+ }
+ else
+ {
+ vertProg = 0;
+ fragProg = 0;
+ mUse = 0;
+ glUseProgramObjectARB( 0 );
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
+{
+#ifdef GL_ARB_shader_objects
+ glDeleteObjectARB(mShader);
+ glDeleteObjectARB(mFrag);
+ glDeleteObjectARB(mVert);
+ mShader = 0;
+ mFrag = 0;
+ mVert = 0;
+ vertProg = 0;
+ fragProg = 0;
+ mOk = 0;
+ mUse = 0;
+ glUseProgramObjectARB(0);
+#endif
+ Py_Return;
+
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" )
+{
+ return PyInt_FromLong( ( mShader !=0 && mOk ) );
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" )
+{
+ return PyString_FromString(vertProg?vertProg:"");
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" )
+{
+ return PyString_FromString(fragProg?fragProg:"");
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
+{
+#ifdef GL_ARB_shader_objects
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_TypeError, "invalid shader object");
+ return NULL;
+ }
+
+ int stat = 0;
+ glValidateProgramARB(mShader);
+ glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat);
+ printInfo(mShader);
+
+ return PyInt_FromLong((stat!=0));
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ int index=-1;
+ if(PyArg_ParseTuple(args, "si", &uniform, &index))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader, uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ if(index <= MAXTEX)
+ {
+ mSampler[index].loc = loc;
+ }else
+ {
+ spit("Invalid texture sample index: " << index);
+ }
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" )
+{
+ int pass = 1;
+ if(!PyArg_ParseTuple(args, "i", &pass))
+ return NULL;
+
+ mPass = pass;
+ Py_Return;
+}
+
+/// access functions
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ float value=0;
+ if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
+ {
+ if( mShader==0 )
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader, uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB( mShader );
+ glUniform1fARB( loc, value );
+ Py_Return;
+ }
+
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ float array[2]={ 0,0 };
+ if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] ))
+ {
+ if( mShader==0 )
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB( mShader );
+ glUniform2fARB(loc, array[0],array[1] );
+ Py_Return;
+ }
+
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ float array[3]={0,0,0};
+ if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2]))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform3fARB(loc, array[0],array[1],array[2]);
+ Py_Return;
+ }
+
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ float array[4]={0,0,0,0};
+ if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform4fARB(loc, array[0],array[1],array[2], array[3]);
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ int value=0;
+ if(PyArg_ParseTuple(args, "si", &uniform, &value ))
+ {
+ if( mShader==0 )
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader, uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB( mShader );
+ glUniform1iARB( loc, value );
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ int array[2]={ 0,0 };
+ if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] ))
+ {
+ if( mShader==0 )
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB( mShader );
+ glUniform2iARB(loc, array[0],array[1] );
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ int array[3]={0,0,0};
+ if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform3iARB(loc, array[0],array[1],array[2]);
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ")
+{
+#ifdef GL_ARB_shader_objects
+ char *uniform="";
+ int array[4]={0,0,0, 0};
+ if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] ))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform4iARB(loc, array[0],array[1],array[2], array[3]);
+ Py_Return;
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )")
+{
+#ifdef GL_ARB_shader_objects
+ char*uniform = "";
+ PyObject *listPtr =0;
+ float array_data[4] = {0.f,0.f,0.f,0.f};
+
+ if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ if(PySequence_Check(listPtr))
+ {
+ unsigned int list_size = PySequence_Size(listPtr);
+
+ for(unsigned int i=0; (i<list_size && i<=4); i++)
+ {
+ PyObject *item = PySequence_GetItem(listPtr, i);
+ array_data[i] = (float)PyFloat_AsDouble(item);
+ Py_DECREF(item);
+ }
+ switch(list_size)
+ {
+ case 2:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform2fARB(loc, array_data[0],array_data[1]);
+ Py_Return;
+ } break;
+ case 3:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform3fARB(loc, array_data[0],array_data[1], array_data[2]);
+ Py_Return;
+ }break;
+ case 4:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform4fARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
+ Py_Return;
+ }break;
+ default:
+ {
+ PyErr_Format(PyExc_TypeError, "Invalid list size");
+ return NULL;
+ }break;
+ }
+ }
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )")
+{
+#ifdef GL_ARB_shader_objects
+ char*uniform = "";
+ PyObject *listPtr =0;
+ int array_data[4] = {0,0,0,0};
+
+ if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ if(PySequence_Check(listPtr))
+ {
+ unsigned int list_size = PySequence_Size(listPtr);
+
+ for(unsigned int i=0; (i<list_size && i<=4); i++)
+ {
+ PyObject *item = PySequence_GetItem(listPtr, i);
+ array_data[i] = PyInt_AsLong(item);
+ Py_DECREF(item);
+ }
+ switch(list_size)
+ {
+ case 2:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform2iARB(loc, array_data[0],array_data[1]);
+ Py_Return;
+ } break;
+ case 3:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform3iARB(loc, array_data[0],array_data[1], array_data[2]);
+ Py_Return;
+ }break;
+ case 4:
+ {
+ glUseProgramObjectARB(mShader);
+ glUniform4iARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
+ Py_Return;
+ }break;
+ default:
+ {
+ PyErr_Format(PyExc_TypeError, "Invalid list size");
+ return NULL;
+ }break;
+ }
+ }
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4,
+"setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" )
+{
+#ifdef GL_ARB_shader_objects
+ float matr[16] = {
+ 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1
+ };
+
+ char *uniform="";
+ PyObject *matrix=0;
+ int transp=1; // MT_ is row major so transpose by default....
+ if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ if (PyObject_IsMT_Matrix(matrix, 4))
+ {
+ MT_Matrix4x4 mat;
+ if (PyMatTo(matrix, mat))
+ {
+ mat.getValue(matr);
+ glUseProgramObjectARB(mShader);
+ glUniformMatrix4fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
+ Py_Return;
+ }
+ }
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
+"setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" )
+{
+#ifdef GL_ARB_shader_objects
+ float matr[9] = {
+ 1,0,0,
+ 0,1,0,
+ 0,0,1,
+ };
+
+ char *uniform="";
+ PyObject *matrix=0;
+ int transp=1; // MT_ is row major so transpose by default....
+ if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
+ {
+ if(mShader==0)
+ {
+ PyErr_Format(PyExc_ValueError, "invalid shader object");
+ return NULL;
+ }
+ int loc= glGetUniformLocationARB(mShader , uniform);
+ if( loc==-1 )
+ {
+ spit("Invalid uniform value: " << uniform << ".");
+ Py_Return;
+ }else
+ {
+ if (PyObject_IsMT_Matrix(matrix, 3))
+ {
+ MT_Matrix3x3 mat;
+ if (PyMatTo(matrix, mat))
+ {
+ mat.getValue(matr);
+ glUseProgramObjectARB(mShader);
+ glUniformMatrix3fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
+ Py_Return;
+ }
+ }
+ }
+ }
+ return NULL;
+#else
+ Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setBlending, "setBlending(src, dest)" )
+{
+ int src, dest;
+ if(PyArg_ParseTuple(args, "ii", &src, &dest))
+ {
+ mBlending.src = src;
+ mBlending.dest = dest;
+ Py_Return;
+ }
+ return NULL;
+}
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
new file mode 100644
index 00000000000..19e0cb8e9b3
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -0,0 +1,117 @@
+#ifndef __BL_SHADER_H__
+#define __BL_SHADER_H__
+
+#include "PyObjectPlus.h"
+#include "BL_Material.h"
+
+// -----------------------------------
+// user state management
+typedef struct uSampler
+{
+ unsigned int type;
+ int pass;
+ int unit;
+ int loc;
+ unsigned int glTexture;
+}uSampler;
+
+#define SAMP_2D 1
+#define SAMP_CUBE 2
+
+
+// -----------------------------------
+typedef struct uBlending
+{
+ unsigned int pass;
+ int src; // GL_ blend func values
+ int dest;
+ float const_color[4];
+}uBlending;
+// -----------------------------------
+
+// ----------------
+class BL_Shader : public PyObjectPlus
+{
+ Py_Header;
+private:
+ unsigned int mShader,
+ mVert,
+ mFrag;
+ int mPass;
+ bool mOk;
+ bool mUse;
+ uSampler mSampler[MAXTEX];
+ uBlending mBlending;
+ char* vertProg;
+ char* fragProg;
+ bool LinkProgram();
+ void printInfo(unsigned int pr);
+
+public:
+ BL_Shader(int n, PyTypeObject *T=&Type);
+ virtual ~BL_Shader();
+
+ char* GetVertPtr();
+ char* GetFragPtr();
+ void SetVertPtr( char *vert );
+ void SetFragPtr( char *frag );
+
+ // ---
+ int getNumPass() {return mPass;}
+ bool use() {return mUse;}
+
+ // ---
+ // access
+ const uSampler* getSampler(int i);
+ const uBlending* getBlending( int pass );
+ const bool Ok()const;
+
+ unsigned int GetProg();
+ unsigned int GetVertexShader();
+ unsigned int GetFragmentShader();
+
+ void InitializeSampler(
+ int type,
+ int unit,
+ int pass,
+ unsigned int texture
+ );
+
+ // -----------------------------------
+ // python interface
+ virtual PyObject* _getattr(const STR_String& attr);
+
+ KX_PYMETHOD_DOC( BL_Shader, setSource );
+ KX_PYMETHOD_DOC( BL_Shader, delSource );
+ KX_PYMETHOD_DOC( BL_Shader, getVertexProg );
+ KX_PYMETHOD_DOC( BL_Shader, getFragmentProg );
+ KX_PYMETHOD_DOC( BL_Shader, setNumberOfPasses );
+
+ // -----------------------------------
+ KX_PYMETHOD_DOC( BL_Shader, isValid);
+ KX_PYMETHOD_DOC( BL_Shader, validate);
+ KX_PYMETHOD_DOC( BL_Shader, setUniform4f );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform3f );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform2f );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform1f );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform4i );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform3i );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform2i );
+ KX_PYMETHOD_DOC( BL_Shader, setUniform1i );
+
+ KX_PYMETHOD_DOC( BL_Shader, setUniformfv );
+ KX_PYMETHOD_DOC( BL_Shader, setUniformiv );
+
+ KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix4 );
+ KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix3 );
+
+ // these come from within the material buttons
+ // sampler2d/samplerCube work
+ KX_PYMETHOD_DOC( BL_Shader, setSampler);
+ // user blending funcs
+ KX_PYMETHOD_DOC( BL_Shader, setBlending );
+};
+
+
+
+#endif//__BL_SHADER_H__
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
new file mode 100644
index 00000000000..f03bfffc8ec
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -0,0 +1,389 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include <iostream>
+
+#include "BL_Material.h"
+#include "BL_Texture.h"
+#include "MT_assert.h"
+
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+#include "IMB_imbuf_types.h"
+#include "BKE_image.h"
+//#include "IMB_imbuf.h"
+#include "BLI_blenlib.h"
+
+#include "RAS_GLExtensionManager.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);
+}
+
+// (n&(n-1)) zeros the least significant bit of n
+static int is_pow2(int num) {
+ return ((num)&(num-1))==0;
+}
+static int smaller_pow2(int num) {
+ while (!is_pow2(num))
+ num= num&(num-1);
+ return num;
+}
+
+
+
+BL_Texture::BL_Texture()
+: mTexture(0),
+ mError(0),
+ mOk(0),
+ mNeedsDeleted(0),
+ mType(0),
+ mName("")
+{
+ // --
+}
+
+BL_Texture::~BL_Texture()
+{
+ // --
+}
+
+void BL_Texture::DeleteTex()
+{
+ if( mNeedsDeleted ) {
+ glDeleteTextures(1, (GLuint*)&(*mTexture));
+ mNeedsDeleted = 0;
+ mOk = 0;
+ }
+}
+
+
+bool BL_Texture::InitFromImage( Image *img, bool mipmap)
+{
+ if(!img || img->ok==0 ) {
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ if( img->ibuf==0 ) {
+ load_image(img, IB_rect, "", 0);
+ if(img->ibuf==0) {
+ img->ok = 0;
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ }
+ mTexture = &img->bindcode;
+ mName = img->id.name;
+ mType = BL_TEX2D;
+
+ // smoke em if we got em
+ if (*mTexture != 0) {
+ glBindTexture(GL_TEXTURE_2D, *mTexture );
+ Validate();
+ return mOk;
+ }
+ glGenTextures(1, (GLuint*)mTexture);
+ InitGLTex(img->ibuf->rect, img->ibuf->x, img->ibuf->y, mipmap);
+ Validate();
+ return mOk;
+}
+
+void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
+{
+ if (!is_pow2(x) || !is_pow2(y) ) {
+ InitNonPow2Tex(pix, x,y,mipmap);
+ return;
+ }
+
+ 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);
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+ }
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+
+void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
+{
+ int nx= smaller_pow2(x);
+ int ny= smaller_pow2(y);
+
+ 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 );
+
+ if( mipmap ) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+ }
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ free(newPixels);
+}
+
+
+bool BL_Texture::InitCubeMap( EnvMap *cubemap )
+{
+#ifdef GL_ARB_texture_cube_map
+ if(!RAS_EXT_support._ARB_texture_cube_map) {
+ spit("cubemaps not supported");
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+
+ else if(!cubemap || cubemap->ima->ok==0 ) {
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+
+ if( cubemap->ima->ibuf==0 ) {
+ load_image(cubemap->ima, IB_rect, "", 0);
+ if(cubemap->ima->ibuf==0) {
+ cubemap->ima->ok = 0;
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ }
+
+ EnvMap *CubeMap = cubemap;
+ mNeedsDeleted = 1;
+ mBlankTexture = 0;
+ mType = BL_TEXCUBE;
+ mTexture = &mBlankTexture;
+ mName = CubeMap->ima->id.name;
+
+ glGenTextures(1, (GLuint*)(mTexture));
+ glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *mTexture );
+ bool needs_split = false;
+
+ if(!CubeMap->cube[0]) needs_split = true;
+
+ if(needs_split){
+ // split it
+ 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));
+
+ // -----------------------------------
+ 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))
+ {
+ spit("invalid envmap size please render with CubeRes @ power of two");
+ free(data);
+ data = 0;
+ 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);
+
+ 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;
+
+#else
+
+ mError = true;
+ mOk = false;
+ return mOk;
+
+#endif//GL_ARB_texture_cube_map
+}
+
+
+STR_String BL_Texture::GetName() const
+{
+ return mName;
+}
+
+
+bool BL_Texture::IsValid()
+{
+ return (mTexture && *mTexture!= 0)?glIsTexture(*mTexture)!=0:false;
+}
+
+
+void BL_Texture::Validate()
+{
+ mOk = IsValid();
+}
+
+
+bool BL_Texture::Ok()
+{
+ return ( mTexture?((!mError || mOk ) && *mTexture!= 0):0 );
+}
+
+
+unsigned int BL_Texture::GetTextureType() const
+{
+ return mType;
+}
+
+
+BL_Texture::operator const unsigned int () const
+{
+ return mTexture? *mTexture:0;
+}
+
+bool BL_Texture::SetGLTex(unsigned int tex)
+{
+ return false;
+}
+
+extern "C" {
+
+void my_envmap_split_ima(EnvMap *env)
+{
+ ImBuf *ibuf;
+ Image *ima;
+ int dx, part;
+
+ my_free_envmapdata(env);
+
+ dx= env->ima->ibuf->y;
+ dx/= 2;
+ if(3*dx != env->ima->ibuf->x) {
+ printf("Incorrect envmap size\n");
+ env->ok= 0;
+ env->ima->ok= 0;
+ }
+ else {
+ for(part=0; part<6; part++) {
+ ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
+ ima= (Image*)MEM_callocN(sizeof(Image), "image");
+ ima->ibuf= ibuf;
+ ima->ok= 1;
+ env->cube[part]= ima;
+ }
+ IMB_rectop(env->cube[0]->ibuf, env->ima->ibuf,
+ 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[1]->ibuf, env->ima->ibuf,
+ 0, 0, dx, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[2]->ibuf, env->ima->ibuf,
+ 0, 0, 2*dx, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[3]->ibuf, env->ima->ibuf,
+ 0, 0, 0, dx, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[4]->ibuf, env->ima->ibuf,
+ 0, 0, dx, dx, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[5]->ibuf, env->ima->ibuf,
+ 0, 0, 2*dx, dx, dx, dx, IMB_rectcpy, 0);
+ env->ok= 2;
+ }
+}
+
+
+void my_free_envmapdata(EnvMap *env)
+{
+ Image *ima;
+ unsigned int a, part;
+
+ for(part=0; part<6; part++) {
+ ima= env->cube[part];
+ if(ima) {
+ if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
+
+ for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
+ if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
+ }
+ MEM_freeN(ima);
+ env->cube[part]= 0;
+ }
+ }
+ env->ok= 0;
+}
+
+
+}
+
+unsigned int BL_Texture::mBlankTexture = 0;
+
diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h
new file mode 100644
index 00000000000..51bf7270d2d
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Texture.h
@@ -0,0 +1,53 @@
+#ifndef __BL_TEXTURE_H__
+#define __BL_TEXTURE_H__
+#include <vector>
+// --
+struct Image;
+struct EnvMap;
+// --
+#include "STR_String.h"
+
+class BL_Texture
+{
+private:
+ // -----------------------------------
+ unsigned int* mTexture;
+ bool mError;
+ bool mOk;
+ bool mNeedsDeleted;
+ unsigned int mType;
+ STR_String mName;
+ static unsigned int mBlankTexture;
+ std::vector<EnvMap*>mCubeMem;
+ // -----------------------------------
+ void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap );
+ void InitGLTex(unsigned int *p,int x,int y,bool mipmap );
+
+public:
+ BL_Texture();
+ ~BL_Texture( );
+
+ operator const unsigned int () const;
+ bool Ok();
+
+ 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();
+};
+
+enum TexType{
+ BL_TEX2D = 1,
+ BL_TEXCUBE = 2
+};
+
+
+#endif//__BL_TEXTURE_H__
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 924bb307da1..e2a11c0035e 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -71,7 +71,7 @@
#include "KX_Scene.h"
#include "SND_DeviceManager.h"
-#include "RAS_OpenGLRasterizer\RAS_GLExtensionManager.h"
+#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
#include "KX_PyMath.h"
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 39a74083ff4..1dc5f0f7170 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -6,7 +6,10 @@ Import ('library_env')
ketsji_env = library_env.Copy ()
-source_files = ['KX_WorldIpoController.cpp',
+source_files = ['BL_Shader.cpp',
+ 'BL_Material.cpp',
+ 'BL_Texture.cpp',
+ 'KX_WorldIpoController.cpp',
'KX_WorldInfo.cpp',
'KX_VisibilityActuator.cpp',
'KX_VertexProxy.cpp',