improvement of 2d-filter custom shader,

some bugfixes,
now you can use depth buffer and luminance buffer without any settings,
also you can use object's properties in a shader
This commit is contained in:
2008-07-12 10:21:37 +00:00
parent 5f15b164c5
commit a49c9c458a
16 changed files with 173 additions and 102 deletions

View File

@@ -196,9 +196,7 @@ typedef struct bVisibilityActuator {
} bVisibilityActuator;
typedef struct bTwoDFilterActuator{
char pad[2];
/* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
short texture_flag;
char pad[4];
/* Tells what type of 2D Filter */
short type;
/* (flag == 0) means 2D filter is activate and

View File

@@ -2536,11 +2536,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
break;
case ACT_2DFILTER_CUSTOMFILTER:
uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, "");
uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19,
&tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)");
uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19,
&tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)");
uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
break;
}

View File

@@ -483,9 +483,9 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
void KX_BlenderRenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)

View File

@@ -101,7 +101,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);

View File

@@ -1000,7 +1000,7 @@ void BL_ConvertActuators(char* maggiename,
}
tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
_2dfilter->float_arg,_2dfilter->int_arg,_2dfilter->texture_flag,ketsjiEngine->GetRasterizer(),rendertools);
_2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),rendertools);
if (_2dfilter->text)
{

View File

@@ -405,7 +405,20 @@ bool CValue::RemoveProperty(const STR_String & inName)
return false;
}
//
// Get Property Names
//
vector<STR_String> CValue::GetPropertyNames()
{
vector<STR_String> result;
if(!m_pNamedPropertyArray) return result;
for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
!(it == m_pNamedPropertyArray->end());it++)
{
result.push_back((*it).first);
}
return result;
}
//
// Clear all properties

View File

@@ -286,6 +286,7 @@ public:
STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
float GetPropertyNumber(const STR_String& inName,float defnumber);
virtual bool RemoveProperty(const STR_String & inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
virtual vector<STR_String> GetPropertyNames();
virtual void ClearProperties(); // Clear all properties
virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>

View File

@@ -7,7 +7,6 @@
#endif
#include <iostream>
SCA_2DFilterActuator::~SCA_2DFilterActuator()
{
}
@@ -18,7 +17,6 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
short flag,
float float_arg,
int int_arg,
short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T)
@@ -26,11 +24,15 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
m_type(type),
m_flag(flag),
m_int_arg(int_arg),
m_texture_flag(texture_flag),
m_float_arg(float_arg),
m_rasterizer(rasterizer),
m_rendertools(rendertools)
{
m_gameObj = NULL;
if(gameobj){
m_propNames = gameobj->GetPropertyNames();
m_gameObj = gameobj;
}
}
void SCA_2DFilterActuator::SetShaderText(STR_String text)
@@ -52,8 +54,6 @@ CValue* SCA_2DFilterActuator::GetReplica()
bool SCA_2DFilterActuator::Update()
{
bool result = false;
bool bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
@@ -74,7 +74,7 @@ bool SCA_2DFilterActuator::Update()
}
else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
{
m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText, m_texture_flag);
m_rendertools->Update2DFilter(m_propNames, m_gameObj, m_type, m_int_arg, m_shaderText);
}
return true;
}

View File

@@ -5,18 +5,17 @@
#include "RAS_IRenderTools.h"
#include "SCA_IActuator.h"
class SCA_2DFilterActuator : public SCA_IActuator
{
Py_Header;
private:
vector<STR_String> m_propNames;
void * m_gameObj;
RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
short m_flag;
float m_float_arg;
int m_int_arg;
short m_texture_flag;
STR_String m_shaderText;
RAS_IRasterizer* m_rasterizer;
RAS_IRenderTools* m_rendertools;
@@ -29,7 +28,6 @@ public:
short flag,
float float_arg,
int int_arg,
short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T=&Type

View File

@@ -602,9 +602,9 @@ void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
void GPC_RenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void GPC_RenderTools::Render2DFilters(RAS_ICanvas* canvas)

View File

@@ -142,7 +142,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);

View File

@@ -32,6 +32,8 @@ SET(INC
../../../intern/string
../../../intern/moto/include
../../../extern/glew/include
../Expressions
${PYTHON_INC}
)
BLENDERLIB(bf_rasterizer "${SRC}" "${INC}")

View File

@@ -52,6 +52,7 @@
#include <config.h>
#endif
#include "Value.h"
RAS_2DFilterManager::RAS_2DFilterManager():
texturewidth(-1), textureheight(-1),
@@ -73,12 +74,14 @@ numberoffilters(0)
m_filters[passindex] = 0;
m_enabled[passindex] = 0;
texflag[passindex] = 0;
m_gameObjects[passindex] = NULL;
}
texname[0] = texname[1] = texname[2] = -1;
}
RAS_2DFilterManager::~RAS_2DFilterManager()
{
FreeTextures();
}
unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource)
@@ -150,6 +153,27 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
}
return 0;
}
void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
{
texflag[passindex] = 0;
if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
{
texflag[passindex] |= 0x1;
}
if(glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1)
{
texflag[passindex] |= 0x2;
}
if(m_gameObjects[passindex])
{
int objProperties = propNames.size();
int i;
for(i=0; i<objProperties; i++)
if(glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1)
m_properties[passindex].push_back(propNames[i]);
}
}
void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
@@ -177,7 +201,7 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
}
/* send luminance texture to glsl program if it needs */
if(texflag[passindex] & 0x1){
if(texflag[passindex] & 0x2){
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
@@ -203,6 +227,17 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
glUniform1fARB(uniformLoc,textureheight);
}
int i, objProperties = m_properties[passindex].size();
for(i=0; i<objProperties; i++)
{
uniformLoc = glGetUniformLocationARB(m_filters[passindex], m_properties[passindex][i]);
if(uniformLoc != -1)
{
float value = ((CValue*)m_gameObjects[passindex])->GetPropertyNumber(m_properties[passindex][i], 0.0);
glUniform1fARB(uniformLoc,value);
}
}
}
void RAS_2DFilterManager::EndShaderProgram()
@@ -210,14 +245,21 @@ void RAS_2DFilterManager::EndShaderProgram()
glUseProgramObjectARB(0);
}
void RAS_2DFilterManager::SetupTexture()
void RAS_2DFilterManager::FreeTextures()
{
if(texname[0]!=-1 || texname[1]!=-1)
{
glDeleteTextures(2, (GLuint*)texname);
}
glGenTextures(3, (GLuint*)texname);
if(texname[0]!=-1)
glDeleteTextures(1, (GLuint*)&texname[0]);
if(texname[1]!=-1)
glDeleteTextures(1, (GLuint*)&texname[1]);
if(texname[2]!=-1)
glDeleteTextures(1, (GLuint*)&texname[2]);
}
void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
{
FreeTextures();
glGenTextures(1, (GLuint*)&texname[0]);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
@@ -226,23 +268,29 @@ void RAS_2DFilterManager::SetupTexture()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindTexture(GL_TEXTURE_2D, texname[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, 0, GL_DEPTH_COMPONENT,
GL_FLOAT,NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
if(depth){
glGenTextures(1, (GLuint*)&texname[1]);
glBindTexture(GL_TEXTURE_2D, texname[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight,
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindTexture(GL_TEXTURE_2D, texname[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
if(luminance){
glGenTextures(1, (GLuint*)&texname[2]);
glBindTexture(GL_TEXTURE_2D, texname[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
}
void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
@@ -273,62 +321,72 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
textureoffsets[(((i*3)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc);
}
}
SetupTexture();
}
void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
{
bool need_depth=false;
bool need_luminance=false;
int num_filters = 0;
int passindex;
if(!isshadersupported)
return;
for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
{
if(m_filters[passindex] && m_enabled[passindex]){
num_filters ++;
if(texflag[passindex] & 0x1)
need_depth = true;
if(texflag[passindex] & 0x2)
need_luminance = true;
if(need_depth && need_luminance)
break;
}
}
if(num_filters <= 0)
return;
if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
{
UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight());
SetupTextures(need_depth, need_luminance);
}
GLuint viewport[4]={0};
int passindex;
bool first = true;
if(need_depth){
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
}
if(need_luminance){
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
}
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0, 0, texturewidth, textureheight);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
{
if(m_filters[passindex] && m_enabled[passindex])
{
if(first)
{
/* this pass needs depth texture*/
if(texflag[passindex] & 0x1){
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
}
/* this pass needs luminance texture*/
if(texflag[passindex] & 0x2){
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
}
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0, 0, texturewidth, textureheight);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
first = false;
}
StartShaderProgram(passindex);
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -341,15 +399,12 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
}
if(!first)
{
glEnable(GL_DEPTH_TEST);
glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
EndShaderProgram();
}
glEnable(GL_DEPTH_TEST);
glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
EndShaderProgram();
}
void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag)
void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
{
if(!isshadersupported)
return;
@@ -374,16 +429,19 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str
glDeleteObjectARB(m_filters[pass]);
m_enabled[pass] = 0;
m_filters[pass] = 0;
m_gameObjects[pass] = NULL;
m_properties[pass].clear();
texflag[pass] = 0;
return;
}
if(mode == RAS_2DFILTER_CUSTOMFILTER)
{
texflag[pass] = tflag;
if(m_filters[pass])
glDeleteObjectARB(m_filters[pass]);
m_filters[pass] = CreateShaderProgram(text.Ptr());
m_gameObjects[pass] = gameObj;
AnalyseShader(pass, propNames);
m_enabled[pass] = 1;
return;
}

View File

@@ -28,8 +28,6 @@
#ifndef __RAS_I2DFILTER
#define __RAS_I2DFILTER
#define MAX_RENDER_PASS 100
class RAS_2DFilterManager
@@ -37,9 +35,15 @@ class RAS_2DFilterManager
private:
unsigned int CreateShaderProgram(char* shadersource);
unsigned int CreateShaderProgram(int filtermode);
void AnalyseShader(int passindex, vector<STR_String>& propNames);
void StartShaderProgram(int passindex);
void EndShaderProgram();
void SetupTextures(bool depth, bool luminance);
void FreeTextures();
void UpdateOffsetMatrix(int width, int height);
float textureoffsets[18];
float view[4];
/* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/
@@ -54,6 +58,13 @@ private:
short texflag[MAX_RENDER_PASS];
bool isshadersupported;
unsigned int m_filters[MAX_RENDER_PASS];
short m_enabled[MAX_RENDER_PASS];
// stores object properties to send to shaders in each pass
vector<STR_String> m_properties[MAX_RENDER_PASS];
void* m_gameObjects[MAX_RENDER_PASS];
public:
enum RAS_2DFILTER_MODE {
RAS_2DFILTER_ENABLED = -2,
@@ -74,19 +85,12 @@ public:
RAS_2DFILTER_NUMBER_OF_FILTERS
};
unsigned int m_filters[MAX_RENDER_PASS];
short m_enabled[MAX_RENDER_PASS];
RAS_2DFilterManager();
~RAS_2DFilterManager();
void SetupTexture();
void UpdateOffsetMatrix(int width, int height);
void RenderFilters(RAS_ICanvas* canvas);
void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag);
void EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text);
};
#endif

View File

@@ -185,7 +185,7 @@ public:
virtual
void
Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short textureflag)=0;
Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)=0;
virtual
void

View File

@@ -7,7 +7,8 @@ if env['WITH_BF_GLEXT'] == 1:
env['CPPFLAGS'].append('-DWITH_GLEXT')
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include'
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions'
incs += ' ' + env['BF_PYTHON_INC']
if env['OURPLATFORM']=='win32-vc':
cflags = []