diff options
Diffstat (limited to 'source/gameengine/Ketsji/BL_Shader.cpp')
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.cpp | 1478 |
1 files changed, 0 insertions, 1478 deletions
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp deleted file mode 100644 index d344e18c313..00000000000 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file gameengine/Ketsji/BL_Shader.cpp - * \ingroup ketsji - */ - -#include "GPU_glew.h" - -#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 "KX_PythonInit.h" -#include "MEM_guardedalloc.h" - -#include "RAS_MeshObject.h" -#include "RAS_IRasterizer.h" - -#define spit(x) std::cout << x << std::endl; - -#define SORT_UNIFORMS 1 -#define UNIFORM_MAX_LEN (int)sizeof(float) * 16 -#define MAX_LOG_LEN 262144 // bounds - -BL_Uniform::BL_Uniform(int data_size) - : - mLoc(-1), - mDirty(true), - mType(UNI_NONE), - mTranspose(0), - mDataLen(data_size) -{ -#ifdef SORT_UNIFORMS - MT_assert((int)mDataLen <= UNIFORM_MAX_LEN); - mData = (void *)MEM_mallocN(mDataLen, "shader-uniform-alloc"); -#endif -} - -BL_Uniform::~BL_Uniform() -{ -#ifdef SORT_UNIFORMS - if (mData) { - MEM_freeN(mData); - mData = NULL; - } -#endif -} - -bool BL_Uniform::Apply(class BL_Shader *shader) -{ -#ifdef SORT_UNIFORMS - RAS_IRasterizer *ras; - MT_assert(mType > UNI_NONE && mType < UNI_MAX && mData); - - if (!mDirty) - return false; - - mDirty = false; - switch (mType) { - case UNI_FLOAT: - { - float *f = (float *)mData; - glUniform1fARB(mLoc, (GLfloat)*f); - break; - } - case UNI_FLOAT_EYE: - { - float *f = (float*)mData; - ras = KX_GetActiveEngine()->GetRasterizer(); - *f = (ras->GetEye() == RAS_IRasterizer::RAS_STEREO_LEFTEYE) ? 0.0f : 0.5f; - glUniform1fARB(mLoc, (GLfloat)*f); - mDirty = (ras->Stereo()) ? true : false; - break; - } - case UNI_INT: - { - int *f = (int *)mData; - glUniform1iARB(mLoc, (GLint)*f); - break; - } - case UNI_FLOAT2: - { - float *f = (float *)mData; - glUniform2fvARB(mLoc, 1, (GLfloat *)f); - break; - } - case UNI_FLOAT3: - { - float *f = (float *)mData; - glUniform3fvARB(mLoc, 1, (GLfloat *)f); - break; - } - case UNI_FLOAT4: - { - float *f = (float *)mData; - glUniform4fvARB(mLoc, 1, (GLfloat *)f); - break; - } - case UNI_INT2: - { - int *f = (int *)mData; - glUniform2ivARB(mLoc, 1, (GLint *)f); - break; - } - case UNI_INT3: - { - int *f = (int *)mData; - glUniform3ivARB(mLoc, 1, (GLint *)f); - break; - } - case UNI_INT4: - { - int *f = (int *)mData; - glUniform4ivARB(mLoc, 1, (GLint *)f); - break; - } - case UNI_MAT4: - { - float *f = (float *)mData; - glUniformMatrix4fvARB(mLoc, 1, mTranspose ? GL_TRUE : GL_FALSE, (GLfloat *)f); - break; - } - case UNI_MAT3: - { - float *f = (float *)mData; - glUniformMatrix3fvARB(mLoc, 1, mTranspose ? GL_TRUE : GL_FALSE, (GLfloat *)f); - break; - } - } - return mDirty; -#endif -} - -void BL_Uniform::SetData(int location, int type, bool transpose) -{ -#ifdef SORT_UNIFORMS - mType = type; - mLoc = location; - mDirty = true; -#endif -} - -bool BL_Shader::Ok()const -{ - return (mShader != 0 && mOk && mUse); -} - -BL_Shader::BL_Shader() - : - PyObjectPlus(), - mShader(0), - mPass(1), - mOk(0), - mUse(0), - mAttr(0), - vertProg(NULL), - fragProg(NULL), - mError(0), - mDirty(true) -{ - // if !GLEW_ARB_shader_objects this class will not be used - //for (int i=0; i<MAXTEX; i++) { - // mSampler[i] = BL_Sampler(); - //} -} - -BL_Shader::~BL_Shader() -{ - //for (int i=0; i<MAXTEX; i++) { - // if (mSampler[i].mOwn) { - // if (mSampler[i].mTexture) - // mSampler[i].mTexture->DeleteTex(); - // } - //} - ClearUniforms(); - - if (mShader) { - glDeleteObjectARB(mShader); - mShader = 0; - } - - vertProg = NULL; - fragProg = NULL; - mOk = 0; - glUseProgramObjectARB(0); -} - -void BL_Shader::ClearUniforms() -{ - BL_UniformVec::iterator it = mUniforms.begin(); - while (it != mUniforms.end()) { - delete *it; - it++; - } - mUniforms.clear(); - - BL_UniformVecDef::iterator itp = mPreDef.begin(); - while (itp != mPreDef.end()) { - delete *itp; - itp++; - } - mPreDef.clear(); -} - -BL_Uniform *BL_Shader::FindUniform(const int location) -{ -#ifdef SORT_UNIFORMS - BL_UniformVec::iterator it = mUniforms.begin(); - while (it != mUniforms.end()) { - if ((*it)->GetLocation() == location) { - return *it; - } - it++; - } -#endif - return NULL; -} - -void BL_Shader::SetUniformfv(int location, int type, float *param, int size, bool transpose) -{ -#ifdef SORT_UNIFORMS - BL_Uniform *uni = FindUniform(location); - - if (uni) { - memcpy(uni->getData(), param, size); - uni->SetData(location, type, transpose); - } - else { - uni = new BL_Uniform(size); - memcpy(uni->getData(), param, size); - uni->SetData(location, type, transpose); - mUniforms.push_back(uni); - } - - mDirty = true; -#endif -} - -void BL_Shader::SetUniformiv(int location, int type, int *param, int size, bool transpose) -{ -#ifdef SORT_UNIFORMS - BL_Uniform *uni = FindUniform(location); - - if (uni) { - memcpy(uni->getData(), param, size); - uni->SetData(location, type, transpose); - } - else { - uni = new BL_Uniform(size); - memcpy(uni->getData(), param, size); - uni->SetData(location, type, transpose); - mUniforms.push_back(uni); - } - - mDirty = true; -#endif -} - -void BL_Shader::ApplyShader() -{ -#ifdef SORT_UNIFORMS - if (!mDirty) { - return; - } - - mDirty = false; - for (unsigned int i=0; i<mUniforms.size(); i++) { - mDirty |= mUniforms[i]->Apply(this); - } -#endif -} - -void BL_Shader::UnloadShader() -{ - // -} - -bool BL_Shader::LinkProgram() -{ - 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; - char *logInf = NULL; - - if (mError) { - goto programError; - } - - if (!vertProg || !fragProg) { - spit("Invalid GLSL sources"); - return false; - } - - if (!GLEW_ARB_fragment_shader) { - spit("Fragment shaders not supported"); - return false; - } - - if (!GLEW_ARB_vertex_shader) { - spit("Vertex shaders not supported"); - return false; - } - - if (vertProg[0] != 0) { - // -- vertex shader ------------------ - tmpVert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); - glShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0); - glCompileShaderARB(tmpVert); - glGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*)&vertlen); - - // print info if any - if (vertlen > 0 && vertlen < MAX_LOG_LEN) { - logInf = (char*)MEM_mallocN(vertlen, "vert-log"); - glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf); - if (char_len > 0) { - spit("---- Vertex Shader Error ----"); - spit(logInf); - } - MEM_freeN(logInf); - logInf = 0; - } - // check for compile errors - glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*)&vertstatus); - if (!vertstatus) { - spit("---- Vertex shader failed to compile ----"); - goto programError; - } - } - - if (fragProg[0] != 0) { - // -- fragment shader ---------------- - tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); - glShaderSourceARB(tmpFrag, 1, (const char**)&fragProg, 0); - glCompileShaderARB(tmpFrag); - glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*)&fraglen); - if (fraglen > 0 && fraglen < MAX_LOG_LEN) { - logInf = (char*)MEM_mallocN(fraglen, "frag-log"); - glGetInfoLogARB(tmpFrag, fraglen, (GLsizei*)&char_len, logInf); - if (char_len > 0) { - spit("---- Fragment Shader Error ----"); - spit(logInf); - } - MEM_freeN(logInf); - logInf = 0; - } - - glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*)&fragstatus); - if (!fragstatus) { - spit("---- Fragment shader failed to compile ----"); - goto programError; - } - } - - if (!tmpFrag && !tmpVert) { - spit("---- No shader given ----"); - goto programError; - } - - // -- program ------------------------ - // set compiled vert/frag shader & link - tmpProg = glCreateProgramObjectARB(); - if (tmpVert) { - glAttachObjectARB(tmpProg, tmpVert); - } - if (tmpFrag) { - glAttachObjectARB(tmpProg, tmpFrag); - } - glLinkProgramARB(tmpProg); - glGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint *)&proglen); - glGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint *)&progstatus); - - if (proglen > 0 && proglen < MAX_LOG_LEN) { - logInf = (char *)MEM_mallocN(proglen, "prog-log"); - glGetInfoLogARB(tmpProg, proglen, (GLsizei *)&char_len, logInf); - - if (char_len > 0) { - spit("---- GLSL Program ----"); - spit(logInf); - } - - MEM_freeN(logInf); - logInf = 0; - } - - if (!progstatus) { - spit("---- GLSL program failed to link ----"); - goto programError; - } - - // set - mShader = tmpProg; - if (tmpVert) { - glDeleteObjectARB(tmpVert); - } - if (tmpFrag) { - glDeleteObjectARB(tmpFrag); - } - mOk = 1; - mError = 0; - return true; - -programError: - if (tmpVert) { - glDeleteObjectARB(tmpVert); - tmpVert = 0; - } - - if (tmpFrag) { - glDeleteObjectARB(tmpFrag); - tmpFrag = 0; - } - - if (tmpProg) { - glDeleteObjectARB(tmpProg); - tmpProg = 0; - } - - mOk = 0; - mUse = 0; - mError = 1; - return false; -} - -const char *BL_Shader::GetVertPtr() -{ - return vertProg ? vertProg : NULL; -} - -const char *BL_Shader::GetFragPtr() -{ - return fragProg ? fragProg : NULL; -} - -void BL_Shader::SetVertPtr(char *vert) -{ - vertProg = vert; -} - -void BL_Shader::SetFragPtr(char *frag) -{ - fragProg = frag; -} - -unsigned int BL_Shader::GetProg() -{ - return mShader; -} - -//const BL_Sampler *BL_Shader::GetSampler(int i) -//{ -// MT_assert(i<=MAXTEX); -// return &mSampler[i]; -//} - -void BL_Shader::SetSampler(int loc, int unit) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - glUniform1iARB(loc, unit); - } -} - -//void BL_Shader::InitializeSampler(int unit, BL_Texture *texture) -//{ -// MT_assert(unit <= MAXTEX); -// mSampler[unit].mTexture = texture; -// mSampler[unit].mLoc = -1; -// mSampler[unit].mOwn = 0; -//} - -void BL_Shader::SetProg(bool enable) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - if (mShader != 0 && mOk && enable) { - glUseProgramObjectARB(mShader); - } - else { - glUseProgramObjectARB(0); - } - } -} - -void BL_Shader::Update(const RAS_MeshSlot &ms, RAS_IRasterizer *rasty) -{ - if (!Ok() || !mPreDef.size()) { - return; - } - - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - MT_Matrix4x4 model; - model.setValue(ms.m_OpenGLMatrix); - const MT_Matrix4x4 &view = rasty->GetViewMatrix(); - - if (mAttr == SHD_TANGENT) { - ms.m_mesh->SetMeshModified(true); - } - - BL_UniformVecDef::iterator it; - for (it = mPreDef.begin(); it != mPreDef.end(); it++) { - BL_DefUniform *uni = (*it); - - if (uni->mLoc == -1) { - continue; - } - - switch (uni->mType) { - case MODELMATRIX: - { - SetUniform(uni->mLoc, model); - break; - } - case MODELMATRIX_TRANSPOSE: - { - SetUniform(uni->mLoc, model, true); - break; - } - case MODELMATRIX_INVERSE: - { - model.invert(); - SetUniform(uni->mLoc, model); - break; - } - case MODELMATRIX_INVERSETRANSPOSE: - { - model.invert(); - SetUniform(uni->mLoc, model, true); - break; - } - case MODELVIEWMATRIX: - { - SetUniform(uni->mLoc, view * model); - break; - } - case MODELVIEWMATRIX_TRANSPOSE: - { - MT_Matrix4x4 mat(view * model); - SetUniform(uni->mLoc, mat, true); - break; - } - case MODELVIEWMATRIX_INVERSE: - { - MT_Matrix4x4 mat(view * model); - mat.invert(); - SetUniform(uni->mLoc, mat); - break; - } - case MODELVIEWMATRIX_INVERSETRANSPOSE: - { - MT_Matrix4x4 mat(view * model); - mat.invert(); - SetUniform(uni->mLoc, mat, true); - break; - } - case CAM_POS: - { - MT_Point3 pos(rasty->GetCameraPosition()); - SetUniform(uni->mLoc, pos); - break; - } - case VIEWMATRIX: - { - SetUniform(uni->mLoc, view); - break; - } - case VIEWMATRIX_TRANSPOSE: - { - SetUniform(uni->mLoc, view, true); - break; - } - case VIEWMATRIX_INVERSE: - { - MT_Matrix4x4 viewinv = view; - viewinv.invert(); - SetUniform(uni->mLoc, view); - break; - } - case VIEWMATRIX_INVERSETRANSPOSE: - { - MT_Matrix4x4 viewinv = view; - viewinv.invert(); - SetUniform(uni->mLoc, view, true); - break; - } - case CONSTANT_TIMER: - { - SetUniform(uni->mLoc, (float)rasty->GetTime()); - break; - } - default: - break; - } - } - } -} - -int BL_Shader::GetAttribLocation(const char *name) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - return glGetAttribLocationARB(mShader, name); - } - - return -1; -} - -void BL_Shader::BindAttribute(const char *attr, int loc) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - glBindAttribLocationARB(mShader, loc, attr); - } -} - -int BL_Shader::GetUniformLocation(const char *name) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - MT_assert(mShader != 0); - int location = glGetUniformLocationARB(mShader, name); - - if (location == -1) { - spit("Invalid uniform value: " << name << "."); - } - - return location; - } - return -1; -} - -void BL_Shader::SetUniform(int uniform, const MT_Tuple2 &vec) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - float value[2]; - vec.getValue(value); - glUniform2fvARB(uniform, 1, value); - } -} - -void BL_Shader::SetUniform(int uniform, const MT_Tuple3 &vec) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - float value[3]; - vec.getValue(value); - glUniform3fvARB(uniform, 1, value); - } -} - -void BL_Shader::SetUniform(int uniform, const MT_Tuple4 &vec) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - float value[4]; - vec.getValue(value); - glUniform4fvARB(uniform, 1, value); - } -} - -void BL_Shader::SetUniform(int uniform, const unsigned int &val) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - glUniform1iARB(uniform, val); - } -} - -void BL_Shader::SetUniform(int uniform, const int val) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - glUniform1iARB(uniform, val); - } -} - -void BL_Shader::SetUniform(int uniform, const float &val) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - glUniform1fARB(uniform, val); - } -} - -void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4 &vec, bool transpose) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - float value[16]; - // note: getValue gives back column major as needed by OpenGL - vec.getValue(value); - glUniformMatrix4fvARB(uniform, 1, transpose ? GL_TRUE : GL_FALSE, value); - } -} - -void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3 &vec, bool transpose) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - float value[9]; - value[0] = (float)vec[0][0]; - value[1] = (float)vec[1][0]; - value[2] = (float)vec[2][0]; - value[3] = (float)vec[0][1]; - value[4] = (float)vec[1][1]; - value[5] = (float)vec[2][1]; - value[6] = (float)vec[0][2]; - value[7] = (float)vec[1][2]; - value[8] = (float)vec[2][2]; - glUniformMatrix3fvARB(uniform, 1, transpose ? GL_TRUE : GL_FALSE, value); - } -} - -void BL_Shader::SetUniform(int uniform, const float *val, int len) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - if (len == 2) { - glUniform2fvARB(uniform, 1, (GLfloat *)val); - } - else if (len == 3) { - glUniform3fvARB(uniform, 1, (GLfloat *)val); - } - else if (len == 4) { - glUniform4fvARB(uniform, 1, (GLfloat *)val); - } - else { - MT_assert(0); - } - } -} - -void BL_Shader::SetUniform(int uniform, const int *val, int len) -{ - if (GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects) { - if (len == 2) { - glUniform2ivARB(uniform, 1, (GLint *)val); - } - else if (len == 3) { - glUniform3ivARB(uniform, 1, (GLint *)val); - } - else if (len == 4) { - glUniform4ivARB(uniform, 1, (GLint *)val); - } - else { - MT_assert(0); - } - } -} - -#ifdef WITH_PYTHON -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, setUniformEyef), - 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, 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), - KX_PYMETHODTABLE(BL_Shader, setUniformMatrix3), - {NULL, NULL} //Sentinel -}; - -PyAttributeDef BL_Shader::Attributes[] = { - {NULL} //Sentinel -}; - -PyTypeObject BL_Shader::Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "BL_Shader", - sizeof(PyObjectPlus_Proxy), - 0, - py_base_dealloc, - 0, - 0, - 0, - 0, - py_base_repr, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - 0, 0, 0, 0, 0, 0, 0, - Methods, - 0, - 0, - &PyObjectPlus::Type, - 0, 0, 0, 0, 0, 0, - py_base_new -}; - -KX_PYMETHODDEF_DOC(BL_Shader, setSource, " setSource(vertexProgram, fragmentProgram)") -{ - if (mShader != 0 && mOk) { - // already set... - Py_RETURN_NONE; - } - - char *v, *f; - int apply = 0; - - if (PyArg_ParseTuple(args, "ssi:setSource", &v, &f, &apply)) { - vertProg = v; - fragProg = f; - - if (LinkProgram()) { - glUseProgramObjectARB(mShader); - mUse = apply != 0; - Py_RETURN_NONE; - } - - vertProg = NULL; - fragProg = NULL; - mUse = 0; - Py_RETURN_NONE; - } - return NULL; -} - - -KX_PYMETHODDEF_DOC(BL_Shader, delSource, "delSource( )") -{ - ClearUniforms(); - glUseProgramObjectARB(0); - glDeleteObjectARB(mShader); - mShader = 0; - mOk = 0; - mUse = 0; - Py_RETURN_NONE; -} - -KX_PYMETHODDEF_DOC(BL_Shader, isValid, "isValid()") -{ - return PyBool_FromLong((mShader != 0 && mOk)); -} - -KX_PYMETHODDEF_DOC(BL_Shader, getVertexProg, "getVertexProg( )") -{ - return PyUnicode_FromString(vertProg ? vertProg : ""); -} - -KX_PYMETHODDEF_DOC(BL_Shader, getFragmentProg, "getFragmentProg( )") -{ - return PyUnicode_FromString(fragProg ? fragProg : ""); -} - -KX_PYMETHODDEF_DOC(BL_Shader, validate, "validate()") -{ - if (mError) { - Py_RETURN_NONE; - } - - if (mShader == 0) { - PyErr_SetString(PyExc_TypeError, "shader.validate(): BL_Shader, invalid shader object"); - return NULL; - } - - int stat = 0; - glValidateProgramARB(mShader); - glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, (GLint *)&stat); - - if (stat > 0 && stat < MAX_LOG_LEN) { - int char_len = 0; - char *logInf = (char *)MEM_mallocN(stat, "validate-log"); - - glGetInfoLogARB(mShader, stat, (GLsizei *)&char_len, logInf); - - if (char_len > 0) { - spit("---- GLSL Validation ----"); - spit(logInf); - } - MEM_freeN(logInf); - logInf = NULL; - } - Py_RETURN_NONE; -} - - -KX_PYMETHODDEF_DOC(BL_Shader, setSampler, "setSampler(name, index)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int index = -1; - - if (PyArg_ParseTuple(args, "si:setSampler", &uniform, &index)) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { - if (index >= MAXTEX || index < 0) { - spit("Invalid texture sample index: " << index); - } -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT, &index, (sizeof(int))); -#else - SetUniform(loc, index); -#endif - //if (index <= MAXTEX) - // mSampler[index].mLoc = loc; - //else - // spit("Invalid texture sample index: " << index); - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )") -{ - int pass = 1; - - if (!PyArg_ParseTuple(args, "i:setNumberOfPasses", &pass)) { - return NULL; - } - - mPass = 1; - Py_RETURN_NONE; -} - -/// access functions -KX_PYMETHODDEF_DOC(BL_Shader, setUniform1f, "setUniform1f(name, fx)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - float value = 0.0f; - - if (PyArg_ParseTuple(args, "sf:setUniform1f", &uniform, &value)) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT, &value, sizeof(float)); -#else - SetUniform(loc, (float)value); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform2f, "setUniform2f(name, fx, fy)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - float array[2] = {0.0f, 0.0f}; - - if (PyArg_ParseTuple(args, "sff:setUniform2f", &uniform, &array[0], &array[1])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array, (sizeof(float) * 2)); -#else - SetUniform(loc, array, 2); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - float array[3] = {0.0f, 0.0f, 0.0f}; - - if (PyArg_ParseTuple(args, "sfff:setUniform3f", &uniform, &array[0], &array[1], &array[2])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array, (sizeof(float) * 3)); -#else - SetUniform(loc, array, 3); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - float array[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - if (PyArg_ParseTuple(args, "sffff:setUniform4f", &uniform, &array[0], &array[1], &array[2], &array[3])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array, (sizeof(float) * 4)); -#else - SetUniform(loc, array, 4); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformEyef, "setUniformEyef(name)") -{ - if (mError) { - Py_RETURN_NONE; - } - const char *uniform; - float value = 0.0f; - if (PyArg_ParseTuple(args, "s:setUniformEyef", &uniform)) { - int loc = GetUniformLocation(uniform); - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT_EYE, &value, sizeof(float)); -#else - SetUniform(loc, (int)value); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform1i, "setUniform1i(name, ix)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int value = 0; - - if (PyArg_ParseTuple(args, "si:setUniform1i", &uniform, &value)) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT, &value, sizeof(int)); -#else - SetUniform(loc, (int)value); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform2i, "setUniform2i(name, ix, iy)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int array[2] = {0, 0}; - - if (PyArg_ParseTuple(args, "sii:setUniform2i", &uniform, &array[0], &array[1])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT2, array, sizeof(int) * 2); -#else - SetUniform(loc, array, 2); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int array[3] = {0, 0, 0}; - - if (PyArg_ParseTuple(args, "siii:setUniform3i", &uniform, &array[0], &array[1], &array[2])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT3, array, sizeof(int) * 3); -#else - SetUniform(loc, array, 3); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int array[4] = {0, 0, 0, 0}; - - if (PyArg_ParseTuple(args, "siiii:setUniform4i", &uniform, &array[0], &array[1], &array[2], &array[3])) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT4, array, sizeof(int) * 4); -#else - SetUniform(loc, array, 4); -#endif - } - Py_RETURN_NONE; - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformfv, "setUniformfv(float (list2 or list3 or list4))") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform = ""; - PyObject *listPtr = NULL; - float array_data[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - if (PyArg_ParseTuple(args, "sO:setUniformfv", &uniform, &listPtr)) { - int loc = GetUniformLocation(uniform); - if (loc != -1) { - 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: - { - float array2[2] = {array_data[0], array_data[1]}; -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array2, sizeof(float) * 2); -#else - SetUniform(loc, array2, 2); -#endif - Py_RETURN_NONE; - break; - } - case 3: - { - float array3[3] = {array_data[0], array_data[1], array_data[2]}; -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array3, sizeof(float) * 3); -#else - SetUniform(loc, array3, 3); -#endif - Py_RETURN_NONE; - break; - } - case 4: - { - float array4[4] = {array_data[0], array_data[1], array_data[2], array_data[3]}; -#ifdef SORT_UNIFORMS - SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array4, sizeof(float) * 4); -#else - SetUniform(loc, array4, 4); -#endif - Py_RETURN_NONE; - break; - } - default: - { - PyErr_SetString(PyExc_TypeError, - "shader.setUniform4i(name, ix,iy,iz, iw): BL_Shader. invalid list size"); - return NULL; - break; - } - } - } - } - } - return NULL; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformiv, "setUniformiv(uniform_name, (list2 or list3 or list4))") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform = ""; - PyObject *listPtr = NULL; - int array_data[4] = {0, 0, 0, 0}; - - if (!PyArg_ParseTuple(args, "sO:setUniformiv", &uniform, &listPtr)) { - return NULL; - } - - int loc = GetUniformLocation(uniform); - - if (loc == -1) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformiv(...): BL_Shader, first string argument is not a valid uniform value"); - return NULL; - } - - if (!PySequence_Check(listPtr)) { - PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, second argument is not a sequence"); - return NULL; - } - - 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] = PyLong_AsLong(item); - Py_DECREF(item); - } - - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformiv(...): BL_Shader, one or more values in the list is not an int"); - return NULL; - } - - // Sanity checks done! - switch (list_size) { - case 2: - { - int array2[2] = {array_data[0], array_data[1]}; -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int) * 2); -#else - SetUniform(loc, array2, 2); -#endif - Py_RETURN_NONE; - break; - } - case 3: - { - int array3[3] = {array_data[0], array_data[1], array_data[2]}; -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int) * 3); -#else - SetUniform(loc, array3, 3); -#endif - Py_RETURN_NONE; - break; - } - case 4: - { - int array4[4] = {array_data[0], array_data[1], array_data[2], array_data[3]}; -#ifdef SORT_UNIFORMS - SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int) * 4); -#else - SetUniform(loc, array4, 4); -#endif - Py_RETURN_NONE; - break; - } - default: - { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformiv(...): BL_Shader, second argument, invalid list size, expected an int " - "list between 2 and 4"); - return NULL; - break; - } - } - Py_RETURN_NONE; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformMatrix4, - "setUniformMatrix4(uniform_name, mat-4x4, transpose(row-major=true, col-major=false)") -{ - if (mError) { - Py_RETURN_NONE; - } - - float matr[16] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; - - const char *uniform; - PyObject *matrix = NULL; - int transp = 0; // python use column major by default, so no transpose.... - - if (!PyArg_ParseTuple(args, "sO|i:setUniformMatrix4", &uniform, &matrix, &transp)) { - return NULL; - } - - int loc = GetUniformLocation(uniform); - - if (loc == -1) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformMatrix4(...): BL_Shader, first string argument is not a valid uniform value"); - return NULL; - } - - MT_Matrix4x4 mat; - - if (!PyMatTo(matrix, mat)) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformMatrix4(...): BL_Shader, second argument cannot be converted into a 4x4 matrix"); - return NULL; - } - - // Sanity checks done! -#ifdef SORT_UNIFORMS - mat.getValue(matr); - SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float) * 16), (transp != 0)); -#else - SetUniform(loc, mat, (transp != 0)); -#endif - Py_RETURN_NONE; -} - - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformMatrix3, - "setUniformMatrix3(uniform_name, list[3x3], transpose(row-major=true, col-major=false)") -{ - if (mError) { - Py_RETURN_NONE; - } - - float matr[9] = { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f, - }; - - const char *uniform; - PyObject *matrix = NULL; - int transp = 0; // python use column major by default, so no transpose.... - - if (!PyArg_ParseTuple(args, "sO|i:setUniformMatrix3", &uniform, &matrix, &transp)) { - return NULL; - } - - int loc = GetUniformLocation(uniform); - - if (loc == -1) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformMatrix3(...): BL_Shader, first string argument is not a valid uniform value"); - return NULL; - } - - MT_Matrix3x3 mat; - - if (!PyMatTo(matrix, mat)) { - PyErr_SetString(PyExc_TypeError, - "shader.setUniformMatrix3(...): BL_Shader, second argument cannot be converted into a 3x3 matrix"); - return NULL; - } - -#ifdef SORT_UNIFORMS - mat.getValue3x3(matr); - SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float) * 9), (transp != 0)); -#else - SetUniform(loc, mat, (transp != 0)); -#endif - Py_RETURN_NONE; -} - -KX_PYMETHODDEF_DOC(BL_Shader, setAttrib, "setAttrib(enum)") -{ - if (mError) { - Py_RETURN_NONE; - } - - int attr = 0; - - if (!PyArg_ParseTuple(args, "i:setAttrib", &attr)) { - return NULL; - } - - attr = SHD_TANGENT; // user input is ignored for now, there is only 1 attr - - if (mShader == 0) { - PyErr_SetString(PyExc_ValueError, "shader.setAttrib() BL_Shader, invalid shader object"); - return NULL; - } - - mAttr = attr; - glUseProgramObjectARB(mShader); - glBindAttribLocationARB(mShader, mAttr, "Tangent"); - Py_RETURN_NONE; -} - - -KX_PYMETHODDEF_DOC(BL_Shader, setUniformDef, "setUniformDef(name, enum)") -{ - if (mError) { - Py_RETURN_NONE; - } - - const char *uniform; - int nloc = 0; - if (PyArg_ParseTuple(args, "si:setUniformDef", &uniform, &nloc)) { - int loc = GetUniformLocation(uniform); - - if (loc != -1) { - bool defined = false; - BL_UniformVecDef::iterator it = mPreDef.begin(); - while (it != mPreDef.end()) { - if ((*it)->mLoc == loc) { - defined = true; - break; - } - it++; - } - - if (defined) { - Py_RETURN_NONE; - } - - BL_DefUniform *uni = new BL_DefUniform(); - uni->mLoc = loc; - uni->mType = nloc; - uni->mFlag = 0; - mPreDef.push_back(uni); - Py_RETURN_NONE; - } - } - return NULL; -} - -#endif // WITH_PYTHON - -// eof |