diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-01-08 12:37:15 +0300 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-01-08 12:37:15 +0300 |
commit | c94455c14d28221f6e05f33ba42e23a5d3245a28 (patch) | |
tree | 733dfaccbbcd71cf66e2d33b1868f64f78189eeb /source/gameengine/Ketsji | |
parent | 88a8508b347dda050557e72dfad105023e5095aa (diff) |
more linux game engine work. hopefully works now!
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r-- | source/gameengine/Ketsji/BL_Material.cpp | 132 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Material.h | 155 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.cpp | 914 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.h | 117 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Texture.cpp | 389 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Texture.h | 53 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/SConscript | 5 |
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', |