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:
authorBenoit Bolsee <benoit.bolsee@online.be>2016-06-10 01:28:19 +0300
committerBenoit Bolsee <benoit.bolsee@online.be>2016-06-11 23:24:18 +0300
commitc0bf881ebfa93784946ee3d03ccf15122c1b74c3 (patch)
tree5a3f2e87a27ea5837913d684b2bae113226025d2
parentfa9bb2ffe97334a5c686b954673af118c41d1a6d (diff)
BL_Shader.setUniformEyef(name)
defines a uniform that reflects the eye being rendered in stereo mode: 0.0 for the left eye, 0.5 for the right eye. In non stereo mode, the value of the uniform is fixed to 0.0. The typical use of this uniform is in stereo mode to sample stereo textures containing the left and right eye images in a top-bottom order. python: shader = obj.meshes[0].materials[mat].getShader() shader.setUniformEyef("eye") shader: uniform float eye; uniform sampler2D tex; void main(void) { vec4 color; float ty, tx; tx = gl_TexCoord[0].x; ty = eye+gl_TexCoord[0].y*0.5; // ty will be between 0 and 0.5 for the left eye render // and 0.5 and 1.0 for the right eye render. color = texture(tex, vec2(tx, ty)); ... }
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_Shader.rst10
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp156
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h4
3 files changed, 112 insertions, 58 deletions
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst b/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst
index f4f5c0d62ba..a389f68ee04 100644
--- a/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst
+++ b/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst
@@ -214,6 +214,16 @@ base class --- :class:`PyObjectPlus`
:arg iList: a list (2, 3 or 4 elements) of integer values
:type iList: list[integer]
+ .. method:: setUniformEyef(name)
+
+ Set a uniform with a float value that reflects the eye being render in stereo mode:
+ 0.0 for the left eye, 0.5 for the right eye. In non stereo mode, the value of the uniform
+ is fixed to 0.0. The typical use of this uniform is in stereo mode to sample stereo textures
+ containing the left and right eye images in a top-bottom order.
+
+ :arg name: the uniform name
+ :type name: string
+
.. method:: validate()
Validate the shader object.
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index 6613780a0f8..72815cadc70 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -32,6 +32,7 @@
#include "MT_Matrix4x4.h"
#include "MT_Matrix3x3.h"
#include "KX_PyMath.h"
+#include "KX_PythonInit.h"
#include "MEM_guardedalloc.h"
#include "RAS_MeshObject.h"
@@ -67,15 +68,16 @@ BL_Uniform::~BL_Uniform()
#endif
}
-void BL_Uniform::Apply(class BL_Shader *shader)
+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;
- }
+ if (!mDirty)
+ return false;
+ mDirty = false;
switch (mType) {
case UNI_FLOAT:
{
@@ -83,6 +85,15 @@ void BL_Uniform::Apply(class BL_Shader *shader)
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;
@@ -138,7 +149,7 @@ void BL_Uniform::Apply(class BL_Shader *shader)
break;
}
}
- mDirty = false;
+ return mDirty;
#endif
}
@@ -274,11 +285,10 @@ void BL_Shader::ApplyShader()
return;
}
- for (unsigned int i = 0; i < mUniforms.size(); i++) {
- mUniforms[i]->Apply(this);
- }
-
mDirty = false;
+ for (unsigned int i=0; i<mUniforms.size(); i++) {
+ mDirty |= mUniforms[i]->Apply(this);
+ }
#endif
}
@@ -314,64 +324,70 @@ bool BL_Shader::LinkProgram()
return false;
}
- // -- 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);
+ 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;
}
-
- 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;
}
- // -- 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);
+ 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;
}
- MEM_freeN(logInf);
- logInf = 0;
+ glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*)&fragstatus);
+ if (!fragstatus) {
+ spit("---- Fragment shader failed to compile ----");
+ goto programError;
+ }
}
-
- glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint *)&fragstatus);
-
- if (!fragstatus) {
- spit("---- Fragment shader failed to compile ----");
+
+ if (!tmpFrag && !tmpVert) {
+ spit("---- No shader given ----");
goto programError;
}
// -- program ------------------------
// set compiled vert/frag shader & link
tmpProg = glCreateProgramObjectARB();
- glAttachObjectARB(tmpProg, tmpVert);
- glAttachObjectARB(tmpProg, tmpFrag);
+ 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);
@@ -396,8 +412,12 @@ bool BL_Shader::LinkProgram()
// set
mShader = tmpProg;
- glDeleteObjectARB(tmpVert);
- glDeleteObjectARB(tmpFrag);
+ if (tmpVert) {
+ glDeleteObjectARB(tmpVert);
+ }
+ if (tmpFrag) {
+ glDeleteObjectARB(tmpFrag);
+ }
mOk = 1;
mError = 0;
return true;
@@ -748,6 +768,7 @@ PyMethodDef BL_Shader::Methods[] = {
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),
@@ -1019,6 +1040,27 @@ KX_PYMETHODDEF_DOC(BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ")
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) {
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index aef4b42a85a..5de715d67d4 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -64,10 +64,11 @@ public:
UNI_FLOAT4,
UNI_MAT3,
UNI_MAT4,
+ UNI_FLOAT_EYE,
UNI_MAX
};
- void Apply(class BL_Shader *shader);
+ bool Apply(class BL_Shader *shader);
void SetData(int location, int type, bool transpose = false);
int GetLocation() { return mLoc; }
void *getData() { return mData; }
@@ -226,6 +227,7 @@ public:
KX_PYMETHOD_DOC(BL_Shader, setUniform3i);
KX_PYMETHOD_DOC(BL_Shader, setUniform2i);
KX_PYMETHOD_DOC(BL_Shader, setUniform1i);
+ KX_PYMETHOD_DOC(BL_Shader, setUniformEyef);
KX_PYMETHOD_DOC(BL_Shader, setUniformfv);
KX_PYMETHOD_DOC(BL_Shader, setUniformiv);
KX_PYMETHOD_DOC(BL_Shader, setUniformMatrix4);