This commit is contained in:
Campbell Barton 2008-11-01 22:04:41 +00:00
parent 5b205ce852
commit 3c9520f92f
67 changed files with 6996 additions and 120 deletions

@ -251,9 +251,9 @@ else:
## ##
CC = 'gcc' CC = 'gcc'
CXX = 'g++' CXX = 'g++'
C_WARN = ' -Wall -Wno-long-double -Wdeclaration-after-statement ' C_WARN = ['-Wdeclaration-after-statement']
CC_WARN = ' -Wall -Wno-long-double' CC_WARN = ['-Wall', '-Wno-long-double']
##FIX_STUBS_WARNINGS = -Wno-unused ##FIX_STUBS_WARNINGS = -Wno-unused

@ -145,9 +145,9 @@ REL_CCFLAGS = ['-O2']
## ##
CC = 'gcc' CC = 'gcc'
CXX = 'g++' CXX = 'g++'
C_WARN = '-Wall -Wdeclaration-after-statement' C_WARN = ['-Wdeclaration-after-statement']
CC_WARN = '-Wall' CC_WARN = ['-Wall']
##FIX_STUBS_WARNINGS = -Wno-unused ##FIX_STUBS_WARNINGS = -Wno-unused

@ -159,9 +159,9 @@ REL_CCFLAGS = ['-O2']
##ARFLAGS = ruv ##ARFLAGS = ruv
##ARFLAGSQUIET = ru ##ARFLAGSQUIET = ru
## ##
C_WARN = '-Wall -Wno-char-subscripts -Wdeclaration-after-statement' C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement']
CC_WARN = '-Wall' CC_WARN = ['-Wall']
##FIX_STUBS_WARNINGS = -Wno-unused ##FIX_STUBS_WARNINGS = -Wno-unused

@ -153,7 +153,7 @@ CXXFLAGS = ['-pipe', '-mwindows', '-funsigned-char', '-fno-strict-aliasing' ]
REL_CFLAGS = [ '-O2' ] REL_CFLAGS = [ '-O2' ]
REL_CCFLAGS = [ '-O2' ] REL_CCFLAGS = [ '-O2' ]
C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ] C_WARN = [ '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
CC_WARN = [ '-Wall' ] CC_WARN = [ '-Wall' ]

@ -161,6 +161,7 @@ CC = 'cl.exe'
CXX = 'cl.exe' CXX = 'cl.exe'
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT'] CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
CXXFLAGS = ['/EHsc']
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']

@ -1,9 +1,5 @@
$Id$ $Id$
Note: The current official release of SCons is 0.98, but
our system still works for 0.97. However, this will be fixed
soon.
Blenders SCons build scripts Blenders SCons build scripts
============================ ============================
@ -31,7 +27,7 @@ $Id$
To build Blender with the SCons scripts you need a full Python To build Blender with the SCons scripts you need a full Python
install, version 2.4 or later (http://www.python.org) and a SCons install, version 2.4 or later (http://www.python.org) and a SCons
installation, version v0.97 (http://www.scons.org). installation, version v1.1.0 (http://www.scons.org).
Check from the page Check from the page
http://www.blender.org/development/building-blender/getting-dependencies/ http://www.blender.org/development/building-blender/getting-dependencies/

@ -854,7 +854,7 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
static int EnumPixelFormats(HDC hdc) { static int EnumPixelFormats(HDC hdc) {
int iPixelFormat; int iPixelFormat;
int i, n, w, weight = 0; int i, n, w, weight = 0;
PIXELFORMATDESCRIPTOR pfd, pfd_fallback; PIXELFORMATDESCRIPTOR pfd;
/* we need a device context to do anything */ /* we need a device context to do anything */
if(!hdc) return 0; if(!hdc) return 0;

@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj",
{138DD16C-CC78-4F6C-A898-C8DA68D89067} = {138DD16C-CC78-4F6C-A898-C8DA68D89067} {138DD16C-CC78-4F6C-A898-C8DA68D89067} = {138DD16C-CC78-4F6C-A898-C8DA68D89067}
{415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292} {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292}
{106AE171-0083-41D6-A949-20DB0E8DC251} = {106AE171-0083-41D6-A949-20DB0E8DC251} {106AE171-0083-41D6-A949-20DB0E8DC251} = {106AE171-0083-41D6-A949-20DB0E8DC251}
{670EC17A-0548-4BBF-A27B-636C7C188139} = {670EC17A-0548-4BBF-A27B-636C7C188139}
{4C3AB78A-52CA-4276-A041-39776E52D8C8} = {4C3AB78A-52CA-4276-A041-39776E52D8C8} {4C3AB78A-52CA-4276-A041-39776E52D8C8} = {4C3AB78A-52CA-4276-A041-39776E52D8C8}
{6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC} {6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC}
{CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}
@ -239,6 +240,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL_gpu", "gpu\BL_gpu.vcproj
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TEX_Video", "..\gameengine\videotexture\TEX_Video.vcproj", "{670EC17A-0548-4BBF-A27B-636C7C188139}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
3D Plugin Debug = 3D Plugin Debug 3D Plugin Debug = 3D Plugin Debug
@ -815,6 +820,18 @@ Global
{138DD16C-CC78-4F6C-A898-C8DA68D89067}.Debug.Build.0 = BlenderPlayer Debug|Win32 {138DD16C-CC78-4F6C-A898-C8DA68D89067}.Debug.Build.0 = BlenderPlayer Debug|Win32
{138DD16C-CC78-4F6C-A898-C8DA68D89067}.Release.ActiveCfg = BlenderPlayer Release|Win32 {138DD16C-CC78-4F6C-A898-C8DA68D89067}.Release.ActiveCfg = BlenderPlayer Release|Win32
{138DD16C-CC78-4F6C-A898-C8DA68D89067}.Release.Build.0 = BlenderPlayer Release|Win32 {138DD16C-CC78-4F6C-A898-C8DA68D89067}.Release.Build.0 = BlenderPlayer Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.3D Plugin Debug.ActiveCfg = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.3D Plugin Release.ActiveCfg = Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Blender Debug.ActiveCfg = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Blender Debug.Build.0 = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Blender Release.ActiveCfg = Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Blender Release.Build.0 = Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.BlenderPlayer Debug.ActiveCfg = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.BlenderPlayer Debug.Build.0 = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.BlenderPlayer Release.ActiveCfg = Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.BlenderPlayer Release.Build.0 = Release|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Debug.ActiveCfg = Debug|Win32
{670EC17A-0548-4BBF-A27B-636C7C188139}.Release.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

@ -124,7 +124,7 @@ ECHO Done
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386 AdditionalOptions="/MACHINE:I386
" "
AdditionalDependencies="SDL.lib freetype2ST.lib ftgl_static.lib gnu_gettext.lib qtmlClient.lib openal_static.lib libsoundsystem.lib libopenalsoundsystem.lib libdummysoundsystem.lib libguardedalloc.lib libbsp.lib libbmfont.lib libghost.lib libstring.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libdecimation.lib libiksolver.lib libpng_st.lib zlib.lib libmoto.lib solid.lib qhull.lib libopennl.lib Bullet.lib python25_d.lib libelbeem.lib libboolop.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib broad.lib complex.lib convex.lib memutil.lib verse.lib Half.lib Iex.lib Imath.lib IlmImf.lib IlmThread.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib glew.lib" AdditionalDependencies="SDL.lib freetype2ST.lib ftgl_static.lib gnu_gettext.lib qtmlClient.lib openal_static.lib libsoundsystem.lib libopenalsoundsystem.lib libdummysoundsystem.lib libguardedalloc.lib libbsp.lib libbmfont.lib libghost.lib libstring.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libdecimation.lib libiksolver.lib libpng_st.lib zlib.lib libmoto.lib solid.lib qhull.lib libopennl.lib Bullet.lib python25_d.lib libelbeem.lib libboolop.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib broad.lib complex.lib convex.lib memutil.lib verse.lib Half.lib Iex.lib Imath.lib IlmImf.lib IlmThread.lib avcodec-51.lib avformat-52.lib avdevice-52.lib avutil-49.lib swscale-0.lib glew.lib"
ShowProgress="0" ShowProgress="0"
OutputFile="..\..\bin\debug\blender.exe" OutputFile="..\..\bin\debug\blender.exe"
LinkIncremental="2" LinkIncremental="2"

@ -382,6 +382,9 @@
<File <File
RelativePath="..\..\..\source\blender\blenlib\intern\freetypefont.c"> RelativePath="..\..\..\source\blender\blenlib\intern\freetypefont.c">
</File> </File>
<File
RelativePath="..\..\..\source\blender\blenlib\intern\graph.c">
</File>
<File <File
RelativePath="..\..\..\source\blender\blenlib\intern\gsqueue.c"> RelativePath="..\..\..\source\blender\blenlib\intern\gsqueue.c">
</File> </File>
@ -458,6 +461,9 @@
<File <File
RelativePath="..\..\..\source\blender\blenlib\BLI_ghash.h"> RelativePath="..\..\..\source\blender\blenlib\BLI_ghash.h">
</File> </File>
<File
RelativePath="..\..\..\source\blender\blenlib\BLI_graph.h">
</File>
<File <File
RelativePath="..\..\..\source\blender\blenlib\BLI_heap.h"> RelativePath="..\..\..\source\blender\blenlib\BLI_heap.h">
</File> </File>

@ -121,6 +121,9 @@
<Filter <Filter
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\..\source\blender\src\autoarmature.c">
</File>
<File <File
RelativePath="..\..\..\source\blender\src\B.blend.c"> RelativePath="..\..\..\source\blender\src\B.blend.c">
</File> </File>

@ -1245,9 +1245,11 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
} }
} }
avgSharpness /= sharpCount; if(sharpCount) {
if (avgSharpness>1.0) { avgSharpness /= sharpCount;
avgSharpness = 1.0; if (avgSharpness>1.0) {
avgSharpness = 1.0;
}
} }
if (seam && seamEdges < 2) if (seam && seamEdges < 2)
@ -1543,9 +1545,11 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
} }
} }
avgSharpness /= sharpCount; if(sharpCount) {
if (avgSharpness>1.0) { avgSharpness /= sharpCount;
avgSharpness = 1.0; if (avgSharpness>1.0) {
avgSharpness = 1.0;
}
} }
if (seam && seamEdges < 2) if (seam && seamEdges < 2)

@ -64,6 +64,7 @@
#ifdef WITH_FFMPEG #ifdef WITH_FFMPEG
#include <ffmpeg/avcodec.h> #include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h> #include <ffmpeg/avformat.h>
//#include <ffmpeg/avdevice.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16) #if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1 #define FFMPEG_OLD_FRAME_RATE 1
@ -236,6 +237,7 @@ void do_init_ffmpeg()
if (!ffmpeg_init) { if (!ffmpeg_init) {
ffmpeg_init = 1; ffmpeg_init = 1;
av_register_all(); av_register_all();
//avdevice_register_all();
} }
} }

@ -246,8 +246,8 @@ PyObject *Matrix_Invert(MatrixObject * self)
/*calculate the classical adjoint*/ /*calculate the classical adjoint*/
if(self->rowSize == 2) { if(self->rowSize == 2) {
mat[0] = self->matrix[1][1]; mat[0] = self->matrix[1][1];
mat[1] = -self->matrix[1][0]; mat[1] = -self->matrix[0][1];
mat[2] = -self->matrix[0][1]; mat[2] = -self->matrix[1][0];
mat[3] = self->matrix[0][0]; mat[3] = self->matrix[0][0];
} else if(self->rowSize == 3) { } else if(self->rowSize == 3) {
Mat3Adj((float (*)[3]) mat,(float (*)[3]) *self->matrix); Mat3Adj((float (*)[3]) mat,(float (*)[3]) *self->matrix);

@ -439,12 +439,19 @@ static void render_envmap(Render *re, EnvMap *env)
if(re->test_break()==0) { if(re->test_break()==0) {
RenderLayer *rl= envre->result->layers.first; RenderLayer *rl= envre->result->layers.first;
int y;
char *alpha;
ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect, 0); ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect, 0);
ibuf->rect_float= rl->rectf; ibuf->rect_float= rl->rectf;
IMB_rect_from_float(ibuf); IMB_rect_from_float(ibuf);
ibuf->rect_float= NULL; ibuf->rect_float= NULL;
/* envmap renders without alpha */
alpha= ((char *)ibuf->rect)+3;
for(y= ibuf->x*ibuf->y - 1; y>=0; y--, alpha+=4)
*alpha= 255;
env->cube[part]= ibuf; env->cube[part]= ibuf;
} }

@ -451,13 +451,13 @@ static void compute_radiance(ScatterTree *tree, float *co, float *rad)
VECCOPY(rdsum, result.rdsum); VECCOPY(rdsum, result.rdsum);
VECADD(backrdsum, result.rdsum, result.backrdsum); VECADD(backrdsum, result.rdsum, result.backrdsum);
if(rdsum[0] > 0.0f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0]; if(rdsum[0] > 1e-16f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0];
if(rdsum[1] > 0.0f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1]; if(rdsum[1] > 1e-16f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1];
if(rdsum[2] > 0.0f) rad[2]= tree->ss[2]->color*rad[2]/rdsum[2]; if(rdsum[2] > 1e-16f) rad[2]= tree->ss[2]->color*rad[2]/rdsum[2];
if(backrdsum[0] > 0.0f) backrad[0]= tree->ss[0]->color*backrad[0]/backrdsum[0]; if(backrdsum[0] > 1e-16f) backrad[0]= tree->ss[0]->color*backrad[0]/backrdsum[0];
if(backrdsum[1] > 0.0f) backrad[1]= tree->ss[1]->color*backrad[1]/backrdsum[1]; if(backrdsum[1] > 1e-16f) backrad[1]= tree->ss[1]->color*backrad[1]/backrdsum[1];
if(backrdsum[2] > 0.0f) backrad[2]= tree->ss[2]->color*backrad[2]/backrdsum[2]; if(backrdsum[2] > 1e-16f) backrad[2]= tree->ss[2]->color*backrad[2]/backrdsum[2];
rad[0]= MAX2(rad[0], backrad[0]); rad[0]= MAX2(rad[0], backrad[0]);
rad[1]= MAX2(rad[1], backrad[1]); rad[1]= MAX2(rad[1], backrad[1]);
@ -504,20 +504,20 @@ static void sum_leaf_radiance(ScatterTree *tree, ScatterNode *node)
} }
} }
if(node->area > 0) { if(node->area > 1e-16f) {
inv= 1.0/node->area; inv= 1.0/node->area;
node->rad[0] *= inv; node->rad[0] *= inv;
node->rad[1] *= inv; node->rad[1] *= inv;
node->rad[2] *= inv; node->rad[2] *= inv;
} }
if(node->backarea > 0) { if(node->backarea > 1e-16f) {
inv= 1.0/node->backarea; inv= 1.0/node->backarea;
node->backrad[0] *= inv; node->backrad[0] *= inv;
node->backrad[1] *= inv; node->backrad[1] *= inv;
node->backrad[2] *= inv; node->backrad[2] *= inv;
} }
if(totrad > 0.0f) { if(totrad > 1e-16f) {
inv= 1.0/totrad; inv= 1.0/totrad;
node->co[0] *= inv; node->co[0] *= inv;
node->co[1] *= inv; node->co[1] *= inv;
@ -578,20 +578,20 @@ static void sum_branch_radiance(ScatterTree *tree, ScatterNode *node)
node->backarea += subnode->backarea; node->backarea += subnode->backarea;
} }
if(node->area > 0) { if(node->area > 1e-16f) {
inv= 1.0/node->area; inv= 1.0/node->area;
node->rad[0] *= inv; node->rad[0] *= inv;
node->rad[1] *= inv; node->rad[1] *= inv;
node->rad[2] *= inv; node->rad[2] *= inv;
} }
if(node->backarea > 0) { if(node->backarea > 1e-16f) {
inv= 1.0/node->backarea; inv= 1.0/node->backarea;
node->backrad[0] *= inv; node->backrad[0] *= inv;
node->backrad[1] *= inv; node->backrad[1] *= inv;
node->backrad[2] *= inv; node->backrad[2] *= inv;
} }
if(totrad > 0.0f) { if(totrad > 1e-16f) {
inv= 1.0/totrad; inv= 1.0/totrad;
node->co[0] *= inv; node->co[0] *= inv;
node->co[1] *= inv; node->co[1] *= inv;

@ -1808,7 +1808,7 @@ static int ui_do_but_TEX(uiBut *but)
((G.qual & LR_COMMANDKEY) || (G.qual & LR_CTRLKEY)) && ((G.qual & LR_COMMANDKEY) || (G.qual & LR_CTRLKEY)) &&
((dev==XKEY) || (dev==CKEY) || (dev==VKEY)) ) { ((dev==XKEY) || (dev==CKEY) || (dev==VKEY)) ) {
char buf[UI_MAX_DRAW_STR]={0}; char buf[UI_MAX_DRAW_STR+1]={0};
/* paste */ /* paste */
if (dev==VKEY) { if (dev==VKEY) {

@ -364,6 +364,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
initGameKeys(); initGameKeys();
initPythonConstraintBinding(); initPythonConstraintBinding();
initMathutils(); initMathutils();
initVideoTexture();
if (sceneconverter) if (sceneconverter)
{ {

@ -40,6 +40,7 @@ SUBDIRS(
SceneGraph SceneGraph
Physics/Bullet Physics/Bullet
Physics/Sumo Physics/Sumo
VideoTexture
) )
IF(WITH_PLAYER) IF(WITH_PLAYER)

@ -59,6 +59,14 @@ public:
void SetMapping(int mode); void SetMapping(int mode);
void DisableUnit(); void DisableUnit();
void setTexEnv(BL_Material *mat, bool modulate=false); void setTexEnv(BL_Material *mat, bool modulate=false);
unsigned int swapTexture (unsigned int newTex) {
// swap texture codes
unsigned int tmp = mTexture;
mTexture = newTex;
// return original texture code
return tmp;
}
}; };
#endif//__BL_TEXTURE_H__ #endif//__BL_TEXTURE_H__

@ -67,6 +67,9 @@ public:
MTFace* GetMTFace(void) const; MTFace* GetMTFace(void) const;
unsigned int* GetMCol(void) const; unsigned int* GetMCol(void) const;
BL_Texture * getTex (unsigned int idx) {
return (idx < MAXTEX) ? mTextures + idx : NULL;
}
// for ipos // for ipos
void UpdateIPO( void UpdateIPO(

@ -793,7 +793,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
{ {
class KX_Scene* scene; class KX_Scene* scene;
scene = PHY_GetActiveScene(); scene = KX_GetActiveScene();
MT_assert(scene); MT_assert(scene);
scene->SetCameraOnTop(this); scene->SetCameraOnTop(this);
Py_Return; Py_Return;

@ -1027,7 +1027,7 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value) PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value)
{ {
KX_Scene *scene = PHY_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
char* meshname; char* meshname;
void* mesh_pt; void* mesh_pt;
@ -1050,7 +1050,7 @@ PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value)
PyObject* KX_GameObject::PyEndObject(PyObject* self) PyObject* KX_GameObject::PyEndObject(PyObject* self)
{ {
KX_Scene *scene = PHY_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
scene->DelayedRemoveObject(this); scene->DelayedRemoveObject(this);
Py_RETURN_NONE; Py_RETURN_NONE;
@ -1447,7 +1447,7 @@ PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
// The object we want to set as parent // The object we want to set as parent
CValue *m_ob = (CValue*)value; CValue *m_ob = (CValue*)value;
KX_GameObject *obj = ((KX_GameObject*)m_ob); KX_GameObject *obj = ((KX_GameObject*)m_ob);
KX_Scene *scene = PHY_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
this->SetParent(scene, obj); this->SetParent(scene, obj);
@ -1456,7 +1456,7 @@ PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
PyObject* KX_GameObject::PyRemoveParent(PyObject* self) PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
{ {
KX_Scene *scene = PHY_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
this->RemoveParent(scene); this->RemoveParent(scene);
Py_RETURN_NONE; Py_RETURN_NONE;
} }

@ -470,7 +470,7 @@ else
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
// set Python hooks for each scene // set Python hooks for each scene
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment()); PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
PHY_SetActiveScene(scene); KX_SetActiveScene(scene);
scene->GetPhysicsEnvironment()->endFrame(); scene->GetPhysicsEnvironment()->endFrame();
@ -568,7 +568,7 @@ else
// set Python hooks for each scene // set Python hooks for each scene
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment()); PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
PHY_SetActiveScene(scene); KX_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
scene->UpdateParents(m_clockTime); scene->UpdateParents(m_clockTime);
@ -1540,6 +1540,11 @@ double KX_KetsjiEngine::GetAnimFrameRate()
return m_anim_framerate; return m_anim_framerate;
} }
double KX_KetsjiEngine::GetClockTime(void) const
{
return m_clockTime;
}
void KX_KetsjiEngine::SetAnimFrameRate(double framerate) void KX_KetsjiEngine::SetAnimFrameRate(double framerate)
{ {
m_anim_framerate = framerate; m_anim_framerate = framerate;

@ -253,6 +253,11 @@ public:
*/ */
bool GetUseFixedTime(void) const; bool GetUseFixedTime(void) const;
/**
* Returns current render frame clock time
*/
double GetClockTime(void) const;
/** /**
* Returns the difference between the local time of the scene (when it * Returns the difference between the local time of the scene (when it
* was running and not suspended) and the "curtime" * was running and not suspended) and the "curtime"

@ -119,7 +119,7 @@ bool KX_ParentActuator::Update()
return false; // do nothing on negative events return false; // do nothing on negative events
KX_GameObject *obj = (KX_GameObject*) GetParent(); KX_GameObject *obj = (KX_GameObject*) GetParent();
KX_Scene *scene = PHY_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
switch (m_mode) { switch (m_mode) {
case KX_PARENT_SET: case KX_PARENT_SET:
if (m_ob) if (m_ob)

@ -1461,16 +1461,21 @@ PyObject* initMathutils()
return Mathutils_Init("Mathutils"); // Use as a top level module in BGE return Mathutils_Init("Mathutils"); // Use as a top level module in BGE
} }
void PHY_SetActiveScene(class KX_Scene* scene) void KX_SetActiveScene(class KX_Scene* scene)
{ {
gp_KetsjiScene = scene; gp_KetsjiScene = scene;
} }
class KX_Scene* PHY_GetActiveScene() class KX_Scene* KX_GetActiveScene()
{ {
return gp_KetsjiScene; return gp_KetsjiScene;
} }
class KX_KetsjiEngine* KX_GetActiveEngine()
{
return gp_KetsjiEngine;
}
// utility function for loading and saving the globalDict // utility function for loading and saving the globalDict
int saveGamePythonConfig( char **marshal_buffer) int saveGamePythonConfig( char **marshal_buffer)
{ {

@ -45,6 +45,7 @@ PyObject* initGameKeys();
PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas); PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level); PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level);
PyObject* initMathutils(); PyObject* initMathutils();
PyObject* initVideoTexture(void);
void exitGamePlayerPythonScripting(); void exitGamePlayerPythonScripting();
PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level); PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
void exitGamePythonScripting(); void exitGamePythonScripting();
@ -54,8 +55,12 @@ void pathGamePythonConfig( char *path );
int saveGamePythonConfig( char **marshal_buffer); int saveGamePythonConfig( char **marshal_buffer);
int loadGamePythonConfig(char *marshal_buffer, int marshal_length); int loadGamePythonConfig(char *marshal_buffer, int marshal_length);
void PHY_SetActiveScene(class KX_Scene* scene); class KX_KetsjiEngine;
class KX_Scene* PHY_GetActiveScene(); class KX_Scene;
void KX_SetActiveScene(class KX_Scene* scene);
class KX_Scene* KX_GetActiveScene();
class KX_KetsjiEngine* KX_GetActiveEngine();
#include "MT_Vector3.h" #include "MT_Vector3.h"
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color); void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color);

@ -78,6 +78,7 @@ numberoffilters(0)
m_gameObjects[passindex] = NULL; m_gameObjects[passindex] = NULL;
} }
texname[0] = texname[1] = texname[2] = -1; texname[0] = texname[1] = texname[2] = -1;
errorprinted= false;
} }
RAS_2DFilterManager::~RAS_2DFilterManager() RAS_2DFilterManager::~RAS_2DFilterManager()
@ -85,76 +86,107 @@ RAS_2DFilterManager::~RAS_2DFilterManager()
FreeTextures(); FreeTextures();
} }
void RAS_2DFilterManager::PrintShaderErrors(unsigned int shader, const char *task, const char *code)
{
GLcharARB log[5000];
GLsizei length = 0;
const char *c, *pos, *end;
int line = 1;
if(errorprinted)
return;
errorprinted= true;
glGetInfoLogARB(shader, sizeof(log), &length, log);
end = code + strlen(code);
printf("2D Filter GLSL Shader: %s error:\n", task);
c = code;
while ((c < end) && (pos = strchr(c, '\n'))) {
printf("%2d ", line);
fwrite(c, (pos+1)-c, 1, stdout);
c = pos+1;
line++;
}
printf("%s", c);
printf("%s\n", log);
}
unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource)
{ {
GLuint program = 0; GLuint program = 0;
GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
GLint success; GLint success;
glShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL); glShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL);
glCompileShaderARB(fShader); glCompileShaderARB(fShader);
glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success);
if(!success)
{
/*Shader Comile Error*/
std::cout << "2dFilters - Shader compile error" << std::endl;
return 0;
}
program = glCreateProgramObjectARB(); glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success);
glAttachObjectARB(program, fShader); if(!success)
{
/*Shader Comile Error*/
PrintShaderErrors(fShader, "compile", shadersource);
return 0;
}
glLinkProgramARB(program); program = glCreateProgramObjectARB();
glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); glAttachObjectARB(program, fShader);
if (!success)
{
/*Program Link Error*/
std::cout << "2dFilters - Shader program link error" << std::endl;
return 0;
}
glValidateProgramARB(program); glLinkProgramARB(program);
glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success); glGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
if (!success) if (!success)
{ {
/*Program Validation Error*/ /*Program Link Error*/
std::cout << "2dFilters - Shader program validation error" << std::endl; PrintShaderErrors(fShader, "link", shadersource);
return 0; return 0;
} }
return program; glValidateProgramARB(program);
glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success);
if (!success)
{
/*Program Validation Error*/
PrintShaderErrors(fShader, "validate", shadersource);
return 0;
}
return program;
} }
unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode) unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
{ {
switch(filtermode) switch(filtermode)
{ {
case RAS_2DFILTER_BLUR: case RAS_2DFILTER_BLUR:
return CreateShaderProgram(BlurFragmentShader); return CreateShaderProgram(BlurFragmentShader);
case RAS_2DFILTER_SHARPEN: case RAS_2DFILTER_SHARPEN:
return CreateShaderProgram(SharpenFragmentShader); return CreateShaderProgram(SharpenFragmentShader);
case RAS_2DFILTER_DILATION: case RAS_2DFILTER_DILATION:
return CreateShaderProgram(DilationFragmentShader); return CreateShaderProgram(DilationFragmentShader);
case RAS_2DFILTER_EROSION: case RAS_2DFILTER_EROSION:
return CreateShaderProgram(ErosionFragmentShader); return CreateShaderProgram(ErosionFragmentShader);
case RAS_2DFILTER_LAPLACIAN: case RAS_2DFILTER_LAPLACIAN:
return CreateShaderProgram(LaplacionFragmentShader); return CreateShaderProgram(LaplacionFragmentShader);
case RAS_2DFILTER_SOBEL: case RAS_2DFILTER_SOBEL:
return CreateShaderProgram(SobelFragmentShader); return CreateShaderProgram(SobelFragmentShader);
case RAS_2DFILTER_PREWITT: case RAS_2DFILTER_PREWITT:
return CreateShaderProgram(PrewittFragmentShader); return CreateShaderProgram(PrewittFragmentShader);
case RAS_2DFILTER_GRAYSCALE: case RAS_2DFILTER_GRAYSCALE:
return CreateShaderProgram(GrayScaleFragmentShader); return CreateShaderProgram(GrayScaleFragmentShader);
case RAS_2DFILTER_SEPIA: case RAS_2DFILTER_SEPIA:
return CreateShaderProgram(SepiaFragmentShader); return CreateShaderProgram(SepiaFragmentShader);
case RAS_2DFILTER_INVERT: case RAS_2DFILTER_INVERT:
return CreateShaderProgram(InvertFragmentShader); return CreateShaderProgram(InvertFragmentShader);
} }
return 0; return 0;
} }
void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
{ {
texflag[passindex] = 0; texflag[passindex] = 0;
if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1) if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
@ -249,11 +281,11 @@ void RAS_2DFilterManager::EndShaderProgram()
void RAS_2DFilterManager::FreeTextures() void RAS_2DFilterManager::FreeTextures()
{ {
if(texname[0]!=-1) if(texname[0]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[0]); glDeleteTextures(1, (GLuint*)&texname[0]);
if(texname[1]!=-1) if(texname[1]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[1]); glDeleteTextures(1, (GLuint*)&texname[1]);
if(texname[2]!=-1) if(texname[2]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[2]); glDeleteTextures(1, (GLuint*)&texname[2]);
} }
@ -300,8 +332,8 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
RAS_Rect canvas_rect = canvas->GetWindowArea(); RAS_Rect canvas_rect = canvas->GetWindowArea();
canvaswidth = canvas->GetWidth(); canvaswidth = canvas->GetWidth();
canvasheight = canvas->GetHeight(); canvasheight = canvas->GetHeight();
texturewidth = canvaswidth + canvas_rect.GetLeft(); texturewidth = canvaswidth;
textureheight = canvasheight + canvas_rect.GetBottom(); textureheight = canvasheight;
GLint i,j; GLint i,j;
i = 0; i = 0;
@ -365,17 +397,17 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if(need_depth){ if(need_depth){
glActiveTextureARB(GL_TEXTURE1); glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]); glBindTexture(GL_TEXTURE_2D, texname[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], texturewidth,textureheight, 0);
} }
if(need_luminance){ if(need_luminance){
glActiveTextureARB(GL_TEXTURE2); glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]); glBindTexture(GL_TEXTURE_2D, texname[2]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0 , texturewidth,textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1] , texturewidth,textureheight, 0);
} }
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0,0, texturewidth, textureheight); glViewport(viewport[0],viewport[1], texturewidth, textureheight);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
@ -393,15 +425,20 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glActiveTextureARB(GL_TEXTURE0); glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]); glBindTexture(GL_TEXTURE_2D, texname[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], texturewidth, textureheight, 0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
float canvascoordx, canvascoordy;
canvascoordx = (GLfloat) texturewidth / canvaswidth;
canvascoordy = (GLfloat) textureheight / canvasheight;
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glTexCoord2f(1.0, 1.0); glVertex2f(1,1); glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, canvascoordy); glVertex2f(1,1);
glTexCoord2f(0.0, 1.0); glVertex2f(-1,1); glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, canvascoordy); glVertex2f(-1,1);
glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1); glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex2f(-1,-1);
glTexCoord2f(1.0, 0.0); glVertex2f(1,-1); glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, 0.0); glVertex2f(1,-1);
glEnd(); glEnd();
} }
} }

@ -38,6 +38,7 @@ private:
void AnalyseShader(int passindex, vector<STR_String>& propNames); void AnalyseShader(int passindex, vector<STR_String>& propNames);
void StartShaderProgram(int passindex); void StartShaderProgram(int passindex);
void EndShaderProgram(); void EndShaderProgram();
void PrintShaderErrors(unsigned int shader, const char *task, const char *code);
void SetupTextures(bool depth, bool luminance); void SetupTextures(bool depth, bool luminance);
void FreeTextures(); void FreeTextures();
@ -58,6 +59,7 @@ private:
short texflag[MAX_RENDER_PASS]; short texflag[MAX_RENDER_PASS];
bool isshadersupported; bool isshadersupported;
bool errorprinted;
unsigned int m_filters[MAX_RENDER_PASS]; unsigned int m_filters[MAX_RENDER_PASS];
short m_enabled[MAX_RENDER_PASS]; short m_enabled[MAX_RENDER_PASS];

@ -15,7 +15,8 @@ SConscript(['BlenderRoutines/SConscript',
'Rasterizer/RAS_OpenGLRasterizer/SConscript', 'Rasterizer/RAS_OpenGLRasterizer/SConscript',
'SceneGraph/SConscript', 'SceneGraph/SConscript',
'Physics/Bullet/SConscript', 'Physics/Bullet/SConscript',
'Physics/Sumo/SConscript' 'Physics/Sumo/SConscript',
'VideoTexture/SConscript'
]) ])
if env['WITH_BF_PLAYER']: if env['WITH_BF_PLAYER']:

@ -0,0 +1,75 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined BLENDTYPE_H
#define BLENDTYPE_H
/// class allows check type of blender python object and access its contained object
template <class PyObj> class BlendType
{
public:
/// constructor
BlendType (char * name) : m_name(name) {}
/// check blender type and return pointer to contained object or NULL (if type is not valid)
PyObj * checkType (PyObject * obj)
{
// if pointer to type isn't set
if (m_objType == NULL)
{
// compare names of type
if (strcmp(obj->ob_type->tp_name, m_name) == 0)
// if name of type match, save pointer to type
m_objType = obj->ob_type;
else
// if names of type don't match, return NULL
return NULL;
}
// if pointer to type is set and don't match to type of provided object, return NULL
else if (obj->ob_type != m_objType)
return NULL;
// return pointer to object
return (PyObj*)obj;
}
/// parse arguments to get object
PyObj * parseArg (PyObject * args)
{
// parse arguments
PyObject * obj;
if (PyArg_ParseTuple(args, "O", &obj))
// if successfully parsed, return pointer to object
return checkType(obj);
// otherwise return NULL
return NULL;
}
protected:
/// name of Python type
char * m_name;
/// pointer to Python type
PyTypeObject * m_objType;
};
#endif

@ -0,0 +1,61 @@
# $Id$
# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jacques Beaurain.
#
# ***** END GPL LICENSE BLOCK *****
FILE(GLOB SRC *.cpp)
SET(INC
.
../../../source/gameengine/Ketsji
../../../source/gameengine/Expressions
../../../source/gameengine/GameLogic
../../../source/gameengine/SceneGraph
../../../source/gameengine/Rasterizer
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
../../../source/gameengine/BlenderRoutines
../../../source/blender/include
../../../source/blender/blenlib
../../../source/blender/blenkernel
../../../source/blender/makesdna
../../../source/blender/imbuf
../../../source/blender/python
../../../source/blender/gpu
../../../source/kernel/gen_system
../../../intern/string
../../../intern/moto/include
../../../intern/guardedalloc
../../../intern/SoundSystem
../../../extern/glew/include
${PYTHON_INC}
)
IF(WITH_FFMPEG)
SET(INC ${INC} ${FFMPEG_INC})
ADD_DEFINITIONS(-DWITH_FFMPEG)
ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS)
ENDIF(WITH_FFMPEG)
BLENDERLIB(bf_videotex "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_videotex', sources, Split(incs), [], libtype=['game','player'], priority=[25, 72], compileflags = cflags )

@ -0,0 +1,55 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if defined WIN32
#define WINDOWS_LEAN_AND_MEAN
#endif
#if !defined NULL
#define NULL 0
#endif
#if !defined HRESULT
#define HRESULT long
#endif
#if !defined DWORD
#define DWORD unsigned long
#endif
#if !defined S_OK
#define S_OK ((HRESULT)0L)
#endif
#if !defined BYTE
#define BYTE unsigned char
#endif
#if !defined WIN32
#define Sleep(time) sleep(time)
#endif
#if !defined FAILED
#define FAILED(Status) ((HRESULT)(Status)<0)
#endif
#include <iostream>

@ -0,0 +1,209 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include <strstream>
#include <fstream>
#include <Python.h>
#include "Exception.h"
// exception identificators
ExceptionID ErrGeneral, ErrNotFound;
// exception descriptions
ExpDesc errGenerDesc (ErrGeneral, "General Error");
ExpDesc errNFoundDesc (ErrNotFound, "Error description not found");
// implementation of ExpDesc
// constructor
ExpDesc::ExpDesc (ExceptionID & exp, char * desc, RESULT hres)
: m_expID(exp), m_hRslt(hres), m_description(desc)
{
}
// destructor
ExpDesc::~ExpDesc (void) {}
// list of descriptions
std::vector<ExpDesc*> ExpDesc::m_expDescs;
// class Exception
// last exception description
std::string Exception::m_lastError;
// log file name
char * Exception::m_logFile = NULL;
// basic constructor
Exception::Exception ()
{
// default values
m_expID = &ErrNotFound;
m_hRslt = S_OK;
m_line = 0;
}
// destructor
Exception::~Exception () throw() { }
// copy constructor
Exception::Exception (const Exception & xpt)
{ copy (xpt); }
// assignment operator
Exception & Exception::operator= (const Exception & xpt)
{ copy (xpt); return *this; }
// get exception description
const char * Exception::what()
{
// set exception description
setXptDesc();
// return c string
return m_desc.c_str();
}
// debug version - with file and line of exception
Exception::Exception (ExceptionID & expID, RESULT rslt, char * fil, int lin)
: m_expID (&expID), m_hRslt (rslt)
{
// set file and line
if (strlen(fil) > 0 || lin > 0)
setFileLine (fil, lin);
}
// set file and line
void Exception::setFileLine (char * fil, int lin)
{
if (fil != NULL) m_fileName = fil;
m_line = lin;
}
// report exception
void Exception::report(void)
{
// set exception description
setXptDesc();
// set python error
PyErr_SetString(PyExc_RuntimeError, what());
// if log file is set
if (m_logFile != NULL)
{
// write description to log
std::ofstream logf (m_logFile, std::ios_base::app);
logf << m_fileName << ':' << m_line << ':' << m_desc << std::endl;
logf.flush();
logf.close();
}
}
// set exception description
void Exception::setXptDesc (void)
{
// if description is not set
if (m_desc.size() == 0)
{
// start of search -1
// found description "NotFound" 0
// found description without matching result 1
// found description with matching result 2
int best = -1;
// find exception description
for (std::vector<ExpDesc*>::iterator it = ExpDesc::m_expDescs.begin(); it != ExpDesc::m_expDescs.end(); ++it)
{
// use "NotFound", if there is not better
if (best < 0 && (*it)->isExp(&ErrNotFound) > 0)
{
(*it)->loadDesc(m_desc);
best = 0;
}
// match exception
int nBest = (*it)->isExp(m_expID, m_hRslt);
// if exception is matching better
if (nBest > 0 && best < nBest)
{
// set description
(*it)->loadDesc(m_desc);
best = nBest;
// if matching exactly, finish search
if (best == 2) break;
}
}
// add result code
// length of result code
const size_t rsltSize = 10;
// delimit description
const char delimRslt[] = ": ";
// set text of description
char rsltTxt[rsltSize];
std::ostrstream os(rsltTxt, rsltSize);
os << std::hex << m_hRslt << delimRslt;
// copy result to description
m_desc.insert(0, rsltTxt, rsltSize);
// copy exception description to last exception string
m_lastError = m_desc;
}
}
// copy exception data
void Exception::copy (const Exception & xpt)
{
// standard data
m_expID = xpt.m_expID;
m_hRslt = xpt.m_hRslt;
m_desc = xpt.m_desc;
// debug data
m_fileName = xpt.m_fileName;
m_line = xpt.m_line;
}
void registerAllExceptions(void)
{
errGenerDesc.registerDesc();
errNFoundDesc.registerDesc();
MaterialNotAvailDesc.registerDesc();
ImageSizesNotMatchDesc.registerDesc();
SceneInvalidDesc.registerDesc();
CameraInvalidDesc.registerDesc();
SourceVideoEmptyDesc.registerDesc();
SourceVideoCreationDesc.registerDesc();
}

@ -0,0 +1,210 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined EXCEPTION_H
#define EXCEPTION_H
#include <exception>
#include <vector>
#include <string>
#include <algorithm>
#include "Common.h"
#define CHCKHRSLTV(fnc,val,err) \
{ \
HRESULT macroHRslt = (fnc); \
if (macroHRslt != val) \
throw Exception (err, macroHRslt, __FILE__, __LINE__); \
}
#define THRWEXCP(err,hRslt) throw Exception (err, hRslt, __FILE__, __LINE__);
#if defined WIN32
#define CHCKHRSLT(fnc,err) \
{ \
HRESULT macroHRslt = (fnc); \
if (FAILED(macroHRslt)) \
throw Exception (err, macroHRslt, __FILE__, __LINE__); \
}
#else
#define CHCKHRSLT(fnc,err) CHCKHRSLTV(fnc,S_OK,err)
#endif
// forward declarations
class ExceptionID;
class Exception;
// exception identificators
extern ExceptionID ErrGeneral, ErrNotFound;
// result type
typedef long RESULT;
// class ExceptionID for exception identification
class ExceptionID
{
public:
// constructor a destructor
ExceptionID (void) {}
~ExceptionID (void) {}
private:
// not allowed
ExceptionID (const ExceptionID & obj) throw() {}
ExceptionID & operator= (const ExceptionID & obj) throw() { return *this; }
};
// class ExpDesc for exception description
class ExpDesc
{
public:
// constructor a destructor
ExpDesc (ExceptionID & exp, char * desc, RESULT hres = S_OK);
~ExpDesc (void);
// comparision function
// returns 0, if exception identification don't match at all
// returns 1, if only exception identification is matching
// returns 2, if both exception identification and result are matching
int isExp (ExceptionID * exp, RESULT hres = S_OK) throw()
{
// check exception identification
if (&m_expID == exp)
{
// check result value
if (m_hRslt == hres) return 2;
// only identification match
if (m_hRslt == S_OK) return 1;
}
// no match
return 0;
}
// get exception description
void loadDesc (std::string & desc) throw()
{
desc = m_description;
}
void registerDesc(void)
{
if (std::find(m_expDescs.begin(), m_expDescs.end(), this) == m_expDescs.end())
m_expDescs.push_back(this);
}
// list of exception descriptions
static std::vector<ExpDesc*> m_expDescs;
private:
// exception ID
ExceptionID & m_expID;
// result
RESULT m_hRslt;
// description
char * m_description;
// not allowed
ExpDesc (const ExpDesc & obj) : m_expID (ErrNotFound) {}
ExpDesc & operator= (const ExpDesc & obj) { return *this; }
};
// class Exception
class Exception : public std::exception
{
public:
// constructor
Exception ();
// destructor
virtual ~Exception () throw();
// copy constructor
Exception (const Exception & xpt);
// assignment operator
Exception & operator= (const Exception & xpt);
// get exception description
virtual const char * what(void);
// debug version of constructor
Exception (ExceptionID & expID, RESULT rslt, char * fil, int lin);
// set source file and line of exception
void setFileLine (char * fil, int lin);
// get description in string
std::string & getDesc (void) throw() { return m_desc; }
// report exception
virtual void report (void);
// get exception id
ExceptionID * getID (void) throw() { return m_expID; }
/// last exception description
static std::string m_lastError;
/// log file name
static char * m_logFile;
protected:
// exception identification
ExceptionID * m_expID;
// RESULT code
RESULT m_hRslt;
// exception description
std::string m_desc;
// set exception description
virtual void setXptDesc (void);
// copy exception
void copy (const Exception & xpt);
// file name where exception was thrown
std::string m_fileName;
// line number in file
int m_line;
};
extern ExpDesc MaterialNotAvailDesc;
extern ExpDesc ImageSizesNotMatchDesc;
extern ExpDesc SceneInvalidDesc;
extern ExpDesc CameraInvalidDesc;
extern ExpDesc SourceVideoEmptyDesc;
extern ExpDesc SourceVideoCreationDesc;
void registerAllExceptions(void);
#endif

@ -0,0 +1,150 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include "FilterBase.h"
#include <Python.h>
#include <structmember.h>
// FilterBase class implementation
// constructor
FilterBase::FilterBase (void) : m_previous(NULL) {}
// destructor
FilterBase::~FilterBase (void)
{
// release Python objects, if not released yet
release();
}
// release python objects
void FilterBase::release (void)
{
// release previous filter object
setPrevious(NULL);
}
// set new previous filter
void FilterBase::setPrevious (PyFilter * filt, bool useRefCnt)
{
// if reference counting has to be used
if (useRefCnt)
{
// reference new filter
if (filt != NULL) Py_INCREF(filt);
// release old filter
Py_XDECREF(m_previous);
}
// set new previous filter
m_previous = filt;
}
// find first filter
FilterBase * FilterBase::findFirst (void)
{
// find first filter in chain
FilterBase * frst;
for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter);
// set first filter
return frst;
}
// list offilter types
PyTypeList pyFilterTypes;
// functions for python interface
// object allocation
PyObject * Filter_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds)
{
// allocate object
PyFilter * self = reinterpret_cast<PyFilter*>(type->tp_alloc(type, 0));
// initialize object structure
self->m_filter = NULL;
// return allocated object
return reinterpret_cast<PyObject*>(self);
}
// object deallocation
void Filter_dealloc (PyFilter * self)
{
// release object attributes
if (self->m_filter != NULL)
{
self->m_filter->release();
delete self->m_filter;
self->m_filter = NULL;
}
}
// get previous pixel filter object
PyObject * Filter_getPrevious (PyFilter * self, void * closure)
{
// if filter object is available
if (self->m_filter != NULL)
{
// pixel filter object
PyObject * filt = reinterpret_cast<PyObject*>(self->m_filter->getPrevious());
// if filter is present
if (filt != NULL)
{
// return it
Py_INCREF(filt);
return filt;
}
}
// otherwise return none
Py_RETURN_NONE;
}
// set previous pixel filter object
int Filter_setPrevious (PyFilter * self, PyObject * value, void * closure)
{
// if filter object is available
if (self->m_filter != NULL)
{
// check new value
if (value == NULL || !pyFilterTypes.in(value->ob_type))
{
// report value error
PyErr_SetString(PyExc_TypeError, "Invalid type of value");
return -1;
}
// set new value
self->m_filter->setPrevious(reinterpret_cast<PyFilter*>(value));
}
// return success
return 0;
}

@ -0,0 +1,132 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined FILTERBASE_H
#define FILTERBASE_H
#include "Common.h"
#include <Python.h>
#include "PyTypeList.h"
// forward declaration
class FilterBase;
// python structure for filter
struct PyFilter
{
PyObject_HEAD
// source object
FilterBase * m_filter;
};
/// base class for pixel filters
class FilterBase
{
public:
/// constructor
FilterBase (void);
/// destructor
virtual ~FilterBase (void);
// release python objects
virtual void release (void);
/// convert pixel
template <class SRC> unsigned int convert (SRC src, short x, short y,
short * size, unsigned int pixSize)
{
return filter(src, x, y, size, pixSize,
convertPrevious(src, x, y, size, pixSize));
}
/// get previous filter
PyFilter * getPrevious (void) { return m_previous; }
/// set previous filter
void setPrevious (PyFilter * filt, bool useRefCnt = true);
/// find first filter in chain
FilterBase * findFirst (void);
/// get first filter's source pixel size
unsigned int firstPixelSize (void) { return findFirst()->getPixelSize(); }
protected:
/// previous pixel filter
PyFilter * m_previous;
/// filter pixel, source byte buffer
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return val; }
/// filter pixel, source int buffer
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return val; }
/// get source pixel size
virtual unsigned int getPixelSize (void) { return 1; }
/// get converted pixel from previous filters
template <class SRC> unsigned int convertPrevious (SRC src, short x, short y,
short * size, unsigned int pixSize)
{
// if previous filter doesn't exists, return source pixel
if (m_previous == NULL) return *src;
// otherwise return converted pixel
return m_previous->m_filter->convert(src, x, y, size, pixSize);
}
};
// list of python filter types
extern PyTypeList pyFilterTypes;
// functions for python interface
// object initialization
template <class T> static int Filter_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
{
PyFilter * self = reinterpret_cast<PyFilter*>(pySelf);
// create filter object
if (self->m_filter != NULL) delete self->m_filter;
self->m_filter = new T();
// initialization succeded
return 0;
}
// object allocation
PyObject * Filter_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds);
// object deallocation
void Filter_dealloc (PyFilter * self);
// get previous pixel filter object
PyObject * Filter_getPrevious (PyFilter * self, void * closure);
// set previous pixel filter object
int Filter_setPrevious (PyFilter * self, PyObject * value, void * closure);
#endif

@ -0,0 +1,178 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include <Python.h>
#include <structmember.h>
#include "FilterBlueScreen.h"
#include "FilterBase.h"
#include "PyTypeList.h"
// implementation FilterBlueScreen
// constructor
FilterBlueScreen::FilterBlueScreen (void)
{
// set color to blue
setColor(0, 0, 255);
// set limits
setLimits(64, 64);
}
// set color
void FilterBlueScreen::setColor (unsigned char red, unsigned char green, unsigned char blue)
{
m_color[0] = red;
m_color[1] = green;
m_color[2] = blue;
}
// set limits for color variation
void FilterBlueScreen::setLimits (unsigned short minLimit, unsigned short maxLimit)
{
m_limits[0] = minLimit;
m_limits[1] = maxLimit > minLimit ? maxLimit : minLimit;
// calculate square values
for (short idx = 0; idx < 2; ++idx)
m_squareLimits[idx] = m_limits[idx] * m_limits[idx];
// limits distance
m_limitDist = m_squareLimits[1] - m_squareLimits[0];
}
// cast Filter pointer to FilterBlueScreen
inline FilterBlueScreen * getFilter (PyFilter * self)
{ return static_cast<FilterBlueScreen*>(self->m_filter); }
// python methods and get/sets
// get color
static PyObject * getColor (PyFilter * self, void * closure)
{
return Py_BuildValue("[BBB]", getFilter(self)->getColor()[0],
getFilter(self)->getColor()[1], getFilter(self)->getColor()[2]);
}
// set color
static int setColor (PyFilter * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints");
return -1;
}
// set color
getFilter(self)->setColor((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
(unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
(unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))));
// success
return 0;
}
// get limits
static PyObject * getLimits (PyFilter * self, void * closure)
{
return Py_BuildValue("[II]", getFilter(self)->getLimits()[0],
getFilter(self)->getLimits()[1]);
}
// set limit
static int setLimits (PyFilter * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints");
return -1;
}
// set limits
getFilter(self)->setLimits((unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
(unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))));
// success
return 0;
}
// attributes structure
static PyGetSetDef filterBSGetSets[] =
{
{"color", (getter)getColor, (setter)setColor, "blue screen color", NULL},
{"limits", (getter)getLimits, (setter)setLimits, "blue screen color limits", NULL},
// attributes from FilterBase class
{"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject FilterBlueScreenType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterBlueScreen", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Filter for Blue Screen objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
filterBSGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterBlueScreen>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};

@ -0,0 +1,98 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined FILTERBLUESCREEN_H
#define FILTERBLUESCREEN_H
#include "Common.h"
#include "FilterBase.h"
/// pixel filter for blue screen
class FilterBlueScreen : public FilterBase
{
public:
/// constructor
FilterBlueScreen (void);
/// destructor
virtual ~FilterBlueScreen (void) {}
/// get color
unsigned char * getColor (void) { return m_color; }
/// set color
void setColor (unsigned char red, unsigned char green, unsigned char blue);
/// get limits for color variation
unsigned short * getLimits (void) { return m_limits; }
/// set limits for color variation
void setLimits (unsigned short minLimit, unsigned short maxLimit);
protected:
/// blue screen color (red component first)
unsigned char m_color[3];
/// limits for color variation - first defines, where ends fully transparent
/// color, second defines, where begins fully opaque color
unsigned short m_limits[2];
/// squared limits for color variation
unsigned int m_squareLimits[2];
/// distance between squared limits
unsigned int m_limitDist;
/// filter pixel template, source int buffer
template <class SRC> unsigned int tFilter (SRC src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{
// calculate differences
int difRed = int((val >> 16) & 0xFF) - int(m_color[0]);
int difGreen = int((val >> 8) & 0xFF) - int(m_color[1]);
int difBlue = int(val & 0xFF) - int(m_color[2]);
// calc distance from "blue screen" color
unsigned int dist = (unsigned int)(difRed * difRed + difGreen * difGreen
+ difBlue * difBlue);
// condition for fully transparent color
if (m_squareLimits[0] >= dist)
// return color with zero alpha
//return 0xFF000000;
return val & 0x00FFFFFF;
// condition for fully opaque color
else if (m_squareLimits[1] <= dist)
// return normal colour
return val | 0xFF000000;
// otherwise calc alpha
else
return (val & 0x00FFFFFF) | ((((dist - m_squareLimits[0]) << 8)
/ m_limitDist) << 24);
}
/// virtual filtering function for byte source
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
/// virtual filtering function for unsigned int source
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
};
#endif

@ -0,0 +1,350 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include <Python.h>
#include <structmember.h>
#include "FilterColor.h"
#include "FilterBase.h"
#include "PyTypeList.h"
// implementation FilterGray
// attributes structure
static PyGetSetDef filterGrayGetSets[] =
{ // attributes from FilterBase class
{"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject FilterGrayType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterGray", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Filter for gray scale effect", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
filterGrayGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterGray>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};
// implementation FilterColor
// constructor
FilterColor::FilterColor (void)
{
// reset color matrix to identity
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 5; ++c)
m_matrix[r][c] = (r == c) ? 256 : 0;
}
// set color matrix
void FilterColor::setMatrix (ColorMatrix & mat)
{
// copy matrix
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 5; ++c)
m_matrix[r][c] = mat[r][c];
}
// cast Filter pointer to FilterColor
inline FilterColor * getFilterColor (PyFilter * self)
{ return static_cast<FilterColor*>(self->m_filter); }
// python methods and get/sets
// get color matrix
static PyObject * getMatrix (PyFilter * self, void * closure)
{
ColorMatrix & mat = getFilterColor(self)->getMatrix();
return Py_BuildValue("((hhhhh)(hhhhh)(hhhhh)(hhhhh))",
mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat[0][4],
mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat[1][4],
mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat[2][4],
mat[3][0], mat[3][1], mat[3][2], mat[3][3], mat[3][4]);
}
// set color matrix
static int setMatrix (PyFilter * self, PyObject * value, void * closure)
{
// matrix to store items
ColorMatrix mat;
// check validity of parameter
bool valid = value != NULL && PySequence_Check(value)
&& PySequence_Length(value) == 4;
// check rows
for (int r = 0; valid && r < 4; ++r)
{
// get row object
PyObject * row = PySequence_Fast_GET_ITEM(value, r);
// check sequence
valid = PySequence_Check(row) && PySequence_Length(row) == 5;
// check items
for (int c = 0; valid && c < 5; ++c)
{
// item must be int
valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c));
// if it is valid, save it in matrix
if (valid)
mat[r][c] = short(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c)));
}
}
// if parameter is not valid, report error
if (!valid)
{
PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][5] of ints");
return -1;
}
// set color matrix
getFilterColor(self)->setMatrix(mat);
// success
return 0;
}
// attributes structure
static PyGetSetDef filterColorGetSets[] =
{
{"matrix", (getter)getMatrix, (setter)setMatrix, "matrix [4][5] for color calculation", NULL},
// attributes from FilterBase class
{"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject FilterColorType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterColor", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Filter for color calculations", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
filterColorGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterColor>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};
// implementation FilterLevel
// constructor
FilterLevel::FilterLevel (void)
{
// reset color levels
for (int r = 0; r < 4; ++r)
{
levels[r][0] = 0;
levels[r][1] = 0xFF << (r << 3);
levels[r][2] = 0xFF;
}
}
// set color levels
void FilterLevel::setLevels (ColorLevel & lev)
{
// copy levels
for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 2; ++c)
levels[r][c] = lev[r][c] << (r << 3);
levels[r][2] = lev[r][0] < lev[r][1] ? lev[r][1] - lev[r][0] : 1;
}
}
// cast Filter pointer to FilterLevel
inline FilterLevel * getFilterLevel (PyFilter * self)
{ return static_cast<FilterLevel*>(self->m_filter); }
// python methods and get/sets
// get color levels
static PyObject * getLevels (PyFilter * self, void * closure)
{
ColorLevel & lev = getFilterLevel(self)->getLevels();
return Py_BuildValue("((kk)(kk)(kk)(kk))",
lev[0][0], lev[0][1], lev[1][0] >> 8, lev[1][1] >> 8,
lev[2][0] >> 16, lev[2][1] >> 16, lev[3][0] >> 24, lev[3][1] >> 24);
}
// set color levels
static int setLevels (PyFilter * self, PyObject * value, void * closure)
{
// matrix to store items
ColorLevel lev;
// check validity of parameter
bool valid = value != NULL && PySequence_Check(value)
&& PySequence_Length(value) == 4;
// check rows
for (int r = 0; valid && r < 4; ++r)
{
// get row object
PyObject * row = PySequence_Fast_GET_ITEM(value, r);
// check sequence
valid = PySequence_Check(row) && PySequence_Length(row) == 2;
// check items
for (int c = 0; valid && c < 2; ++c)
{
// item must be int
valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c));
// if it is valid, save it in matrix
if (valid)
lev[r][c] = (unsigned long)(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c)));
}
}
// if parameter is not valid, report error
if (!valid)
{
PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][2] of ints");
return -1;
}
// set color matrix
getFilterLevel(self)->setLevels(lev);
// success
return 0;
}
// attributes structure
static PyGetSetDef filterLevelGetSets[] =
{
{"levels", (getter)getLevels, (setter)setLevels, "levels matrix [4] (min, max)", NULL},
// attributes from FilterBase class
{"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject FilterLevelType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterLevel", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Filter for levels calculations", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
filterLevelGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterLevel>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};

@ -0,0 +1,164 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined FILTERCOLOR_H
#define FILTERCOLOR_H
#include "Common.h"
#include "FilterBase.h"
/// pixel filter for gray scale
class FilterGray : public FilterBase
{
public:
/// constructor
FilterGray (void) {}
/// destructor
virtual ~FilterGray (void) {}
protected:
/// filter pixel template, source int buffer
template <class SRC> unsigned int tFilter (SRC src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{
// calculate gray value
unsigned int gray = (28 * ((val >> 16) & 0xFF) + 151 * ((val >> 8) & 0xFF)
+ 77 * (val & 0xFF)) & 0xFF00;
// return gray scale value
return (val & 0xFF000000) | gray << 8 | gray | gray >> 8;
}
/// virtual filtering function for byte source
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
/// virtual filtering function for unsigned int source
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
};
/// type for color matrix
typedef short ColorMatrix[4][5];
/// pixel filter for color calculation
class FilterColor : public FilterBase
{
public:
/// constructor
FilterColor (void);
/// destructor
virtual ~FilterColor (void) {}
/// get color matrix
ColorMatrix & getMatrix (void) { return m_matrix; }
/// set color matrix
void setMatrix (ColorMatrix & mat);
protected:
/// color calculation matrix
ColorMatrix m_matrix;
/// calculate one color component
unsigned int calcColor (unsigned int val, short idx)
{
return (((m_matrix[idx][0] * (val & 0xFF) + m_matrix[idx][1] * ((val >> 8) & 0xFF)
+ m_matrix[idx][2] * ((val >> 16) & 0xFF) + m_matrix[idx][3] * ((val >> 24) & 0xFF)
+ m_matrix[idx][4]) >> 8) & 0xFF) << (idx << 3);
}
/// filter pixel template, source int buffer
template <class SRC> unsigned int tFilter (SRC src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{
// return calculated color
return calcColor(val, 0) | calcColor(val, 1) | calcColor(val, 2)
| calcColor(val, 3);
}
/// virtual filtering function for byte source
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
/// virtual filtering function for unsigned int source
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
};
/// type for color levels
typedef unsigned long ColorLevel[4][3];
/// pixel filter for color calculation
class FilterLevel : public FilterBase
{
public:
/// constructor
FilterLevel (void);
/// destructor
virtual ~FilterLevel (void) {}
/// get color matrix
ColorLevel & getLevels (void) { return levels; }
/// set color matrix
void setLevels (ColorLevel & lev);
protected:
/// color calculation matrix
ColorLevel levels;
/// calculate one color component
unsigned int calcColor (unsigned int val, short idx)
{
unsigned int col = val & (0xFF << (idx << 3));
if (col <= levels[idx][0]) col = 0;
else if (col >= levels[idx][1]) col = 0xFF << (idx << 3);
else if (idx < 3) col = (((col - levels[idx][0]) << 8) / levels[idx][2]) & (0xFF << (idx << 3));
else col = (((col - levels[idx][0]) / levels[idx][2]) << 8) & (0xFF << (idx << 3));
return col;
}
/// filter pixel template, source int buffer
template <class SRC> unsigned int tFilter (SRC src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{
// return calculated color
return calcColor(val, 0) | calcColor(val, 1) | calcColor(val, 2)
| calcColor(val, 3);
}
/// virtual filtering function for byte source
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
/// virtual filtering function for unsigned int source
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
};
#endif

@ -0,0 +1,162 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include <Python.h>
#include <structmember.h>
#include "FilterNormal.h"
#include "FilterBase.h"
#include "PyTypeList.h"
// implementation FilterNormal
// constructor
FilterNormal::FilterNormal (void) : m_colShift(0)
{
// set default depth
setDepth(4);
}
// set color shift
void FilterNormal::setColor (unsigned short colIdx)
{
// check validity of index
if (colIdx < 3)
// set color shift
m_colShift = colIdx << 3;
}
// set depth
void FilterNormal::setDepth (float depth)
{
m_depth = depth;
m_depthScale = depth / depthScaleKoef;
}
// cast Filter pointer to FilterNormal
inline FilterNormal * getFilter (PyFilter * self)
{ return static_cast<FilterNormal*>(self->m_filter); }
// python methods and get/sets
// get index of color used to calculate normal
static PyObject * getColor (PyFilter * self, void * closure)
{
return Py_BuildValue("H", getFilter(self)->getColor());
}
// set index of color used to calculate normal
static int setColor (PyFilter * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PyInt_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a int");
return -1;
}
// set color index
getFilter(self)->setColor((unsigned short)(PyInt_AsLong(value)));
// success
return 0;
}
// get depth
static PyObject * getDepth (PyFilter * self, void * closure)
{
return Py_BuildValue("f", getFilter(self)->getDepth());
}
// set depth
static int setDepth (PyFilter * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PyFloat_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a float");
return -1;
}
// set depth
getFilter(self)->setDepth(float(PyFloat_AsDouble(value)));
// success
return 0;
}
// attributes structure
static PyGetSetDef filterNormalGetSets[] =
{
{"colorIdx", (getter)getColor, (setter)setColor, "index of color used to calculate normal (0 - red, 1 - green, 2 - blue)", NULL},
{"depth", (getter)getDepth, (setter)setDepth, "depth of relief", NULL},
// attributes from FilterBase class
{"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject FilterNormalType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterNormal", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Filter for Blue Screen objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
filterNormalGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterNormal>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};

@ -0,0 +1,98 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined FILTERNORMAL_H
#define FILTERNORMAL_H
#include "Common.h"
#include "FilterBase.h"
// scale constants for normals
const float depthScaleKoef = 255.0;
const float normScaleKoef = float(depthScaleKoef / 2.0);
/// pixel filter for normal mapping
class FilterNormal : public FilterBase
{
public:
/// constructor
FilterNormal (void);
/// destructor
virtual ~FilterNormal (void) {}
/// get index of color used to calculate normals
unsigned short getColor (void) { return m_colShift >> 3; }
/// set index of color used to calculate normals
void setColor (unsigned short colIdx);
/// get depth
float getDepth (void) { return m_depth; }
/// set depth
void setDepth (float depth);
protected:
/// depth of normal relief
float m_depth;
/// scale to calculate normals
float m_depthScale;
/// shift to used color component
unsigned short m_colShift;
/// filter pixel, source int buffer
template <class SRC> unsigned int tFilter (SRC * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{
// get value of required color
int actPix = int((val >> m_colShift) & 0xFF);
// get upper and left pixel from actual pixel
int upPix = y > 0 ? int((convertPrevious(src - pixSize * size[0], x, y - 1,
size, pixSize) >> m_colShift) & 0xFF) : actPix;
int leftPix = x > 0 ? int((convertPrevious(src - pixSize, x - 1, y, size, pixSize)
>> m_colShift) & 0xFF) : actPix;
// height differences (from blue color)
float dx = (actPix - leftPix) * m_depthScale;
float dy = (actPix - upPix) * m_depthScale;
// normalize vector
float dz = float(normScaleKoef / sqrt(dx * dx + dy * dy + 1.0));
dx = dx * dz + normScaleKoef;
dy = dy * dz + normScaleKoef;
dz += normScaleKoef;
// return normal vector converted to color
return 0xFF000000 | int(dz) << 16 | int(dy) << 8 | int(dx);
}
/// filter pixel, source byte buffer
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
/// filter pixel, source int buffer
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{ return tFilter(src, x, y, size, pixSize, val); }
};
#endif

@ -0,0 +1,125 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include "FilterSource.h"
#include "FilterBase.h"
#include "PyTypeList.h"
// FilterRGB24
// define python type
PyTypeObject FilterRGB24Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterRGB24", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Source filter RGB24 objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
NULL, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterRGB24>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};
// FilterBGR24
// define python type
PyTypeObject FilterBGR24Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.FilterBGR24", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Filter_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Source filter BGR24 objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
NULL, /* tp_methods */
0, /* tp_members */
NULL, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Filter_init<FilterBGR24>, /* tp_init */
0, /* tp_alloc */
Filter_allocNew, /* tp_new */
};

@ -0,0 +1,233 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined FILTERSOURCE_H
#define FILTERSOURCE_H
#include "Common.h"
#include "FilterBase.h"
/// class for RGB24 conversion
class FilterRGB24 : public FilterBase
{
public:
/// constructor
FilterRGB24 (void) {}
/// destructor
virtual ~FilterRGB24 (void) {}
/// get source pixel size
virtual unsigned int getPixelSize (void) { return 3; }
protected:
/// filter pixel, source byte buffer
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{ return 0xFF000000 | src[0] << 16 | src[1] << 8 | src[2]; }
};
/// class for BGR24 conversion
class FilterBGR24 : public FilterBase
{
public:
/// constructor
FilterBGR24 (void) {}
/// destructor
virtual ~FilterBGR24 (void) {}
/// get source pixel size
virtual unsigned int getPixelSize (void) { return 3; }
protected:
/// filter pixel, source byte buffer
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{ return 0xFF000000 | src[2] << 16 | src[1] << 8 | src[0]; }
};
/// class for YV12 conversion
class FilterYV12 : public FilterBase
{
public:
/// constructor
FilterYV12 (void) {}
/// destructor
virtual ~FilterYV12 (void) {}
/// get source pixel size
virtual unsigned int getPixelSize (void) { return 1; }
/// set pointers to color buffers
void setBuffs (unsigned char * buff, short * size)
{
unsigned int buffSize = size[0] * size[1];
m_buffV = buff + buffSize;
m_buffU = m_buffV + (buffSize >> 2);
m_pitchUV = size[0] >> 1;
}
protected:
/// begin of V buffer
unsigned char * m_buffV;
/// begin of U buffer
unsigned char * m_buffU;
/// pitch for V & U buffers
short m_pitchUV;
/// interpolation function
int interpol (int a, int b, int c, int d)
{ return (9 * (b + c) - a - d + 8) >> 4; }
/// common horizontal interpolation
int interpolH (unsigned char * src)
{ return interpol(*(src-1), *src, *(src+1), *(src+2)); }
/// common vertical interpolation
int interpolV (unsigned char * src)
{ return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); }
/// common joined vertical and horizontal interpolation
int interpolVH (unsigned char * src)
{
return interpol(interpolV(src-1), interpolV(src), interpolV(src+1),
interpolV(src+2));
}
/// is pixel on edge
bool isEdge (short x, short y, short * size)
{ return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; }
/// get the first parameter on the low edge
unsigned char * interParA (unsigned char * src, short x, short size, short shift)
{ return x > 1 ? src - shift : src; }
/// get the third parameter on the high edge
unsigned char * interParC (unsigned char * src, short x, short size, short shift)
{ return x < size - 2 ? src + shift : src; }
/// get the fourth parameter on the high edge
unsigned char * interParD (unsigned char * src, short x, short size, short shift)
{ return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; }
/// horizontal interpolation on edges
int interpolEH (unsigned char * src, short x, short size)
{
return interpol(*interParA(src, x, size, 1), *src,
*interParC(src, x, size, 1), *interParD(src, x, size, 1));
}
/// vertical interpolation on edges
int interpolEV (unsigned char * src, short y, short size)
{
return interpol(*interParA(src, y, size, m_pitchUV), *src,
*interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV));
}
/// joined vertical and horizontal interpolation on edges
int interpolEVH (unsigned char * src, short x, short y, short * size)
{
return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]),
interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]),
interpolEV(interParD(src, x, size[0], 1), y, size[1]));
}
/// filter pixel, source byte buffer
virtual unsigned int filter (unsigned char * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val)
{
// V & U offset
long offset = (x >> 1) + m_pitchUV * (y >> 1);
// get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128
int c = *src - 16;
int d = m_buffU[offset] - 128;
int e = m_buffV[offset] - 128;
// if horizontal interpolation is needed
if ((x & 1) == 1)
// if vertical interpolation is needed too
if ((y & 1) == 1)
// if this pixel is on the edge
if (isEdge(x, y, size))
{
// get U & V from edge
d = interpolEVH(m_buffU + offset, x, y, size) - 128;
e = interpolEVH(m_buffV + offset, x, y, size) - 128;
}
// otherwise get U & V from inner range
else
{
d = interpolVH(m_buffU + offset) - 128;
e = interpolVH(m_buffV + offset) - 128;
}
// otherwise use horizontal interpolation only
else
// if this pixel is on the edge
if (isEdge(x, y, size))
{
// get U & V from edge
d = interpolEH(m_buffU + offset, x, size[0]) - 128;
e = interpolEH(m_buffV + offset, x, size[0]) - 128;
}
// otherwise get U & V from inner range
else
{
d = interpolH(m_buffU + offset) - 128;
e = interpolH(m_buffV + offset) - 128;
}
// otherwise if only vertical interpolation is needed
else if ((y & 1) == 1)
// if this pixel is on the edge
if (isEdge(x, y, size))
{
// get U & V from edge
d = interpolEV(m_buffU + offset, y, size[1]) - 128;
e = interpolEV(m_buffV + offset, y, size[1]) - 128;
}
// otherwise get U & V from inner range
else
{
d = interpolV(m_buffU + offset) - 128;
e = interpolV(m_buffV + offset) - 128;
}
// convert to RGB
// R = clip(( 298 * C + 409 * E + 128) >> 8)
// G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
// B = clip(( 298 * C + 516 * D + 128) >> 8)
int red = (298 * c + 409 * e + 128) >> 8;
if (red >= 0x100) red = 0xFF;
else if (red < 0) red = 0;
int green = 298 * c - 100 * d - 208 * e;
if (green > 0x10000) green = 0xFF00;
else if (green < 0) green = 0;
int blue = (298 * c + 516 * d + 128) << 8;
if (blue > 0x1000000) blue = 0xFF0000;
else if (blue < 0) blue = 0;
// return result
return 0xFF000000 | blue & 0xFF0000 | green & 0xFF00
| red & 0xFF;
}
};
#endif

@ -0,0 +1,529 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include "ImageBase.h"
#include <vector>
#include <string.h>
#include <Python.h>
#include <structmember.h>
#include "FilterBase.h"
#include "Exception.h"
// ImageBase class implementation
// constructor
ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0),
m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
m_staticSources(staticSrc), m_pyfilter(NULL)
{
m_size[0] = m_size[1] = 0;
}
// destructor
ImageBase::~ImageBase (void)
{
// release image
delete [] m_image;
}
// release python objects
bool ImageBase::release (void)
{
// iterate sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
{
// release source object
delete *it;
*it = NULL;
}
// release filter object
Py_XDECREF(m_pyfilter);
m_pyfilter = NULL;
return true;
}
// get image
unsigned int * ImageBase::getImage (unsigned int texId)
{
// if image is not available
if (!m_avail)
{
// if there are any sources
if (!m_sources.empty())
{
// get images from sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
// get source image
(*it)->getImage();
// init image
init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
}
// calculate new image
calcImage(texId);
}
// if image is available, return it, otherwise NULL
return m_avail ? m_image : NULL;
}
// refresh image source
void ImageBase::refresh (void)
{
// invalidate this image
m_avail = false;
// refresh all sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
(*it)->refresh();
}
// get source object
PyImage * ImageBase::getSource (const char * id)
{
// find source
ImageSourceList::iterator src = findSource(id);
// return it, if found
return src != m_sources.end() ? (*src)->getSource() : NULL;
}
// set source object
bool ImageBase::setSource (const char * id, PyImage * source)
{
// find source
ImageSourceList::iterator src = findSource(id);
// check source loop
if (source != NULL && source->m_image->loopDetect(this))
return false;
// if found, set new object
if (src != m_sources.end())
// if new object is not empty or sources are static
if (source != NULL || m_staticSources)
// replace previous source
(*src)->setSource(source);
// otherwise delete source
else
m_sources.erase(src);
// if source is not found and adding is allowed
else
if (!m_staticSources)
{
// create new source
ImageSource * newSrc = newSource(id);
newSrc->setSource(source);
// if source was created, add it to source list
if (newSrc != NULL) m_sources.push_back(newSrc);
}
// otherwise source wasn't set
else
return false;
// source was set
return true;
}
// set pixel filter
void ImageBase::setFilter (PyFilter * filt)
{
// reference new filter
if (filt != NULL) Py_INCREF(filt);
// release previous filter
Py_XDECREF(m_pyfilter);
// set new filter
m_pyfilter = filt;
}
// initialize image data
void ImageBase::init (short width, short height)
{
// if image has to be scaled
if (m_scale)
{
// recalc sizes of image
width = calcSize(width);
height = calcSize(height);
}
// if sizes differ
if (width != m_size[0] || height != m_size[1])
{
// new buffer size
unsigned int newSize = width * height;
// if new buffer is larger than previous
if (newSize > m_imgSize)
{
// set new buffer size
m_imgSize = newSize;
// release previous and create new buffer
delete [] m_image;
m_image = new unsigned int[m_imgSize];
}
// new image size
m_size[0] = width;
m_size[1] = height;
// scale was processed
m_scaleChange = false;
}
}
// find source
ImageSourceList::iterator ImageBase::findSource (const char * id)
{
// iterate sources
ImageSourceList::iterator it;
for (it = m_sources.begin(); it != m_sources.end(); ++it)
// if id matches, return iterator
if ((*it)->is(id)) return it;
// source not found
return it;
}
// check sources sizes
bool ImageBase::checkSourceSizes (void)
{
// reference size
short * refSize = NULL;
// iterate sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
{
// get size of current source
short * curSize = (*it)->getSize();
// if size is available and is not empty
if (curSize[0] != 0 && curSize[1] != 0)
// if reference size is not set
if (refSize == NULL)
// set current size as reference
refSize = curSize;
// otherwise check with current size
else if (curSize[0] != refSize[0] || curSize[1] != refSize[1])
// if they don't match, report it
return false;
}
// all sizes match
return true;
}
// compute nearest power of 2 value
short ImageBase::calcSize (short size)
{
// while there is more than 1 bit in size value
while ((size & (size - 1)) != 0)
// clear last bit
size = size & (size - 1);
// return result
return size;
}
// perform loop detection
bool ImageBase::loopDetect (ImageBase * img)
{
// if this object is the same as parameter, loop is detected
if (this == img) return true;
// check all sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
// if source detected loop, return this result
if ((*it)->getSource() != NULL && (*it)->getSource()->m_image->loopDetect(img))
return true;
// no loop detected
return false;
}
// ImageSource class implementation
// constructor
ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL)
{
// copy id
int idx;
for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx)
m_id[idx] = id[idx];
m_id[idx] = '\0';
}
// destructor
ImageSource::~ImageSource (void)
{
// release source
setSource(NULL);
}
// compare id
bool ImageSource::is (const char * id)
{
for (char * myId = m_id; *myId != '\0'; ++myId, ++id)
if (*myId != *id) return false;
return *id == '\0';
}
// set source object
void ImageSource::setSource (PyImage * source)
{
// reference new source
if (source != NULL) Py_INCREF(source);
// release previous source
Py_XDECREF(m_source);
// set new source
m_source = source;
}
// get image from source
unsigned int * ImageSource::getImage (void)
{
// if source is available
if (m_source != NULL)
// get image from source
m_image = m_source->m_image->getImage();
// otherwise reset buffer
else
m_image = NULL;
// return image
return m_image;
}
// refresh source
void ImageSource::refresh (void)
{
// if source is available, refresh it
if (m_source != NULL) m_source->m_image->refresh();
}
// list of image types
PyTypeList pyImageTypes;
// functions for python interface
// object allocation
PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds)
{
// allocate object
PyImage * self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0));
// initialize object structure
self->m_image = NULL;
// return allocated object
return reinterpret_cast<PyObject*>(self);
}
// object deallocation
void Image_dealloc (PyImage * self)
{
// release object attributes
if (self->m_image != NULL)
{
// if release requires deleting of object, do it
if (self->m_image->release())
delete self->m_image;
self->m_image = NULL;
}
}
// get image data
PyObject * Image_getImage (PyImage * self, void * closure)
{
try
{
// get image
unsigned int * image = self->m_image->getImage();
return Py_BuildValue("s#", image, self->m_image->getBuffSize());
}
catch (Exception & exp)
{
exp.report();
}
Py_RETURN_NONE;
}
// get image size
PyObject * Image_getSize (PyImage * self, void * closure)
{
return Py_BuildValue("(hh)", self->m_image->getSize()[0],
self->m_image->getSize()[1]);
}
// refresh image
PyObject * Image_refresh (PyImage * self)
{
self->m_image->refresh();
Py_RETURN_NONE;
}
// get scale
PyObject * Image_getScale (PyImage * self, void * closure)
{
if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
// set scale
int Image_setScale (PyImage * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
// set scale
if (self->m_image != NULL) self->m_image->setScale(value == Py_True);
// success
return 0;
}
// get flip
PyObject * Image_getFlip (PyImage * self, void * closure)
{
if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
// set flip
int Image_setFlip (PyImage * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
// set scale
if (self->m_image != NULL) self->m_image->setFlip(value == Py_True);
// success
return 0;
}
// get filter source object
PyObject * Image_getSource (PyImage * self, PyObject * args)
{
// get arguments
char * id;
if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id))
{
// get source object
PyObject * src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
// if source is available
if (src != NULL)
{
// return source
Py_INCREF(src);
return src;
}
}
// source was not found
Py_RETURN_NONE;
}
// set filter source object
PyObject * Image_setSource (PyImage * self, PyObject * args)
{
// get arguments
char * id;
PyObject * obj;
if (self->m_image != NULL && PyArg_ParseTuple(args, "sO", &id, &obj))
{
// check type of object
if (pyImageTypes.in(obj->ob_type))
{
// convert to image struct
PyImage * img = reinterpret_cast<PyImage*>(obj);
// set source
if (!self->m_image->setSource(id, img))
{
// if not set, retport error
PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
return NULL;
}
}
// else report error
else
{
PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
return NULL;
}
}
// return none
Py_RETURN_NONE;
}
// get pixel filter object
PyObject * Image_getFilter (PyImage * self, void * closure)
{
// if image object is available
if (self->m_image != NULL)
{
// pixel filter object
PyObject * filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
// if filter is present
if (filt != NULL)
{
// return it
Py_INCREF(filt);
return filt;
}
}
// otherwise return none
Py_RETURN_NONE;
}
// set pixel filter object
int Image_setFilter (PyImage * self, PyObject * value, void * closure)
{
// if image object is available
if (self->m_image != NULL)
{
// check new value
if (value == NULL || !pyFilterTypes.in(value->ob_type))
{
// report value error
PyErr_SetString(PyExc_TypeError, "Invalid type of value");
return -1;
}
// set new value
self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));
}
// return success
return 0;
}

@ -0,0 +1,349 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined IMAGEBASE_H
#define IMAGEBASE_H
#include "Common.h"
#include <vector>
#include <Python.h>
#include "PyTypeList.h"
#include "FilterBase.h"
// forward declarations
struct PyImage;
class ImageSource;
/// type for list of image sources
typedef std::vector<ImageSource*> ImageSourceList;
/// base class for image filters
class ImageBase
{
public:
/// constructor
ImageBase (bool staticSrc = false);
/// destructor
virtual ~ImageBase (void);
/// release contained objects, if returns true, object should be deleted
virtual bool release (void);
/// get image
unsigned int * getImage (unsigned int texId = 0);
/// get image size
short * getSize (void) { return m_size; }
/// get image buffer size
unsigned long getBuffSize (void)
{ return m_size[0] * m_size[1] * sizeof(unsigned int); }
/// refresh image - invalidate its current content
virtual void refresh (void);
/// get scale
bool getScale (void) { return m_scale; }
/// set scale
void setScale (bool scale) { m_scale = scale; m_scaleChange = true; }
/// get vertical flip
bool getFlip (void) { return m_flip; }
/// set vertical flip
void setFlip (bool flip) { m_flip = flip; }
/// get source object
PyImage * getSource (const char * id);
/// set source object, return true, if source was set
bool setSource (const char * id, PyImage * source);
/// get pixel filter
PyFilter * getFilter (void) { return m_pyfilter; }
/// set pixel filter
void setFilter (PyFilter * filt);
/// calculate size (nearest power of 2)
static short calcSize (short size);
protected:
/// image buffer
unsigned int * m_image;
/// image buffer size
unsigned int m_imgSize;
/// image size
short m_size[2];
/// image is available
bool m_avail;
/// scale image to power 2 sizes
bool m_scale;
/// scale was changed
bool m_scaleChange;
/// flip image vertically
bool m_flip;
/// source image list
ImageSourceList m_sources;
/// flag for disabling addition and deletion of sources
bool m_staticSources;
/// pixel filter
PyFilter * m_pyfilter;
/// initialize image data
void init (short width, short height);
/// find source
ImageSourceList::iterator findSource (const char * id);
/// create new source
virtual ImageSource * newSource (const char * id) { return NULL; }
/// check source sizes
bool checkSourceSizes (void);
/// calculate image from sources and set its availability
virtual void calcImage (unsigned int texId) {}
/// perform loop detection
bool loopDetect (ImageBase * img);
/// template for image conversion
template<class FLT, class SRC> void convImage (FLT & filter, SRC srcBuff,
short * srcSize)
{
// destination buffer
unsigned int * dstBuff = m_image;
// pixel size from filter
unsigned int pixSize = filter.firstPixelSize();
// if no scaling is needed
if (srcSize[0] == m_size[0] && srcSize[1] == m_size[1])
// if flipping isn't required
if (!m_flip)
// copy bitmap
for (short y = 0; y < m_size[1]; ++y)
for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
// copy pixel
*dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
// otherwise flip image top to bottom
else
{
// go to last row of image
srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
// copy bitmap
for (short y = m_size[1] - 1; y >= 0; --y, srcBuff -= 2 * srcSize[0] * pixSize)
for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
// copy pixel
*dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
}
// else scale picture (nearest neighbour)
else
{
// interpolation accumulator
int accHeight = srcSize[1] >> 1;
// if flipping is required
if (m_flip)
// go to last row of image
srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
// process image rows
for (int y = 0; y < srcSize[1]; ++y)
{
// increase height accum
accHeight += m_size[1];
// if pixel row has to be drawn
if (accHeight >= srcSize[1])
{
// decrease accum
accHeight -= srcSize[1];
// width accum
int accWidth = srcSize[0] >> 1;
// process row
for (int x = 0; x < srcSize[0]; ++x)
{
// increase width accum
accWidth += m_size[0];
// if pixel has to be drawn
if (accWidth >= srcSize[0])
{
// decrease accum
accWidth -= srcSize[0];
// convert pixel
*dstBuff = filter.convert(srcBuff, x, m_flip ? srcSize[1] - y - 1 : y,
srcSize, pixSize);
// next pixel
++dstBuff;
}
// shift source pointer
srcBuff += pixSize;
}
}
// if pixel row will not be drawn
else
// move source pointer to next row
srcBuff += pixSize * srcSize[0];
// if y flipping is required
if (m_flip)
// go to previous row of image
srcBuff -= 2 * pixSize * srcSize[0];
}
}
}
// template for specific filter preprocessing
template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short * srcSize)
{
// find first filter in chain
FilterBase * firstFilter = NULL;
if (m_pyfilter != NULL) firstFilter = m_pyfilter->m_filter->findFirst();
// if first filter is available
if (firstFilter != NULL)
{
// python wrapper for filter
PyFilter pyFilt;
pyFilt.m_filter = &filt;
// set specified filter as first in chain
firstFilter->setPrevious(&pyFilt, false);
// convert video image
convImage(*(m_pyfilter->m_filter), srcBuff, srcSize);
// delete added filter
firstFilter->setPrevious(NULL, false);
}
// otherwise use given filter for conversion
else convImage(filt, srcBuff, srcSize);
// source was processed
m_avail = true;
}
};
// python structure for image filter
struct PyImage
{
PyObject_HEAD
// source object
ImageBase * m_image;
};
// size of id
const int SourceIdSize = 32;
/// class for source of image
class ImageSource
{
public:
/// constructor
ImageSource (const char * id);
/// destructor
virtual ~ImageSource (void);
/// get id
const char * getId (void) { return m_id; }
/// compare id to argument
bool is (const char * id);
/// get source object
PyImage * getSource (void) { return m_source; }
/// set source object
void setSource (PyImage * source);
/// get image from source
unsigned int * getImage (void);
/// get buffered image
unsigned int * getImageBuf (void) { return m_image; }
/// refresh source
void refresh (void);
/// get image size
short * getSize (void)
{
static short defSize [] = {0, 0};
return m_source != NULL ? m_source->m_image->getSize() : defSize;
}
protected:
/// id of source
char m_id [SourceIdSize];
/// pointer to source structure
PyImage * m_source;
/// buffered image from source
unsigned int * m_image;
private:
/// default constructor is forbidden
ImageSource (void) {}
};
// list of python image types
extern PyTypeList pyImageTypes;
// functions for python interface
// object initialization
template <class T> static int Image_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
{
PyImage * self = reinterpret_cast<PyImage*>(pySelf);
// create source object
if (self->m_image != NULL) delete self->m_image;
self->m_image = new T();
// initialization succeded
return 0;
}
// object allocation
PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds);
// object deallocation
void Image_dealloc (PyImage * self);
// get image data
PyObject * Image_getImage (PyImage * self, void * closure);
// get image size
PyObject * Image_getSize (PyImage * self, void * closure);
// refresh image - invalidate current content
PyObject * Image_refresh (PyImage * self);
// get scale
PyObject * Image_getScale (PyImage * self, void * closure);
// set scale
int Image_setScale (PyImage * self, PyObject * value, void * closure);
// get flip
PyObject * Image_getFlip (PyImage * self, void * closure);
// set flip
int Image_setFlip (PyImage * self, PyObject * value, void * closure);
// get filter source object
PyObject * Image_getSource (PyImage * self, PyObject * args);
// set filter source object
PyObject * Image_setSource (PyImage * self, PyObject * args);
// get pixel filter object
PyObject * Image_getFilter (PyImage * self, void * closure);
// set pixel filter object
int Image_setFilter (PyImage * self, PyObject * value, void * closure);
#endif

@ -0,0 +1,166 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include "ImageBuff.h"
#include "ImageBase.h"
#include "FilterSource.h"
// default filter
FilterBGR24 defFilter;
// load image from buffer
void ImageBuff::load (unsigned char * img, short width, short height)
{
// initialize image buffer
init(width, height);
// original size
short orgSize[2] = {width, height};
// is filter available
if (m_pyfilter != NULL)
// use it to process image
convImage(*(m_pyfilter->m_filter), img, orgSize);
else
// otherwise use default filter
convImage(defFilter, img, orgSize);
// image is available
m_avail = true;
}
// cast Image pointer to ImageBuff
inline ImageBuff * getImageBuff (PyImage * self)
{ return static_cast<ImageBuff*>(self->m_image); }
// python methods
// load image
static PyObject * load (PyImage * self, PyObject * args)
{
// parameters: string image buffer, its size, width, height
unsigned char * buff;
unsigned int buffSize;
short width;
short height;
// parse parameters
if (!PyArg_ParseTuple(args, "s#hh", &buff, &buffSize, &width, &height))
{
// report error
PyErr_SetString(PyExc_TypeError, "Parameters are not correct");
return NULL;
}
// else check buffer size
else
{
// calc proper buffer size
unsigned int propSize = width * height;
// use pixel size from filter
if (self->m_image->getFilter() != NULL)
propSize *= self->m_image->getFilter()->m_filter->firstPixelSize();
else
propSize *= defFilter.firstPixelSize();
// check if buffer size is correct
if (propSize != buffSize)
{
// if not, report error
PyErr_SetString(PyExc_TypeError, "Buffer hasn't correct size");
return NULL;
}
else
// if correct, load image
getImageBuff(self)->load(buff, width, height);
}
Py_RETURN_NONE;
}
// methods structure
static PyMethodDef imageBuffMethods[] =
{
{"load", (PyCFunction)load, METH_VARARGS, "Load image from buffer"},
{NULL}
};
// attributes structure
static PyGetSetDef imageBuffGetSets[] =
{ // attributes from ImageBase class
{"image", (getter)Image_getImage, NULL, "image data", NULL},
{"size", (getter)Image_getSize, NULL, "image size", NULL},
{"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL},
{"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
{"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject ImageBuffType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.ImageBuff", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Image_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from image buffer", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
imageBuffMethods, /* tp_methods */
0, /* tp_members */
imageBuffGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Image_init<ImageBuff>, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};

@ -0,0 +1,51 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined IMAGEBUFF_H
#define IMAGEBUFF_H
#include "Common.h"
#include "ImageBase.h"
/// class for image buffer
class ImageBuff : public ImageBase
{
public:
/// constructor
ImageBuff (void) : ImageBase(true) {}
/// destructor
virtual ~ImageBuff (void) {}
/// load image from buffer
void load (unsigned char * img, short width, short height);
/// refresh image - do nothing
virtual void refresh (void) {}
};
#endif

@ -0,0 +1,205 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include "ImageMix.h"
#include "ImageBase.h"
#include "Exception.h"
// cast ImageSource pointer to ImageSourceMix
inline ImageSourceMix * getImageSourceMix (ImageSource * src)
{ return static_cast<ImageSourceMix*>(src); }
// get weight
short ImageMix::getWeight (const char * id)
{
// find source
ImageSourceList::iterator src = findSource(id);
// if found, return its weight
return src != m_sources.end() ? getImageSourceMix(*src)->getWeight() : 0;
}
// set weight
bool ImageMix::setWeight (const char * id, short weight)
{
// find source
ImageSourceList::iterator src = findSource(id);
// if source isn't found, report it
if (src == m_sources.end()) return false;
// set its weight
getImageSourceMix(*src)->setWeight(weight);
return true;
}
ExceptionID ImageSizesNotMatch;
ExpDesc ImageSizesNotMatchDesc (ImageSizesNotMatch, "Image sizes of sources are different");
// calculate image from sources and set its availability
void ImageMix::calcImage (unsigned int texId)
{
// check source sizes
if (!checkSourceSizes()) THRWEXCP(ImageSizesNotMatch, S_OK);
// set offsets to image buffers
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
// if image buffer is available
if ((*it)->getImageBuf() != NULL)
// set its offset
getImageSourceMix(*it)->setOffset(m_sources[0]->getImageBuf());
// otherwise don't calculate image
else
return;
// if there is only single source
if (m_sources.size() == 1)
{
// use single filter
FilterBase mixFilt;
// fiter and convert image
filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
}
// otherwise use mix filter to merge source images
else
{
FilterImageMix mixFilt (m_sources);
// fiter and convert image
filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
}
}
// cast Image pointer to ImageMix
inline ImageMix * getImageMix (PyImage * self)
{ return static_cast<ImageMix*>(self->m_image); }
// python methods
// get source weight
PyObject * getWeight (PyImage * self, PyObject * args)
{
// weight
short weight = 0;
// get arguments
char * id;
if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id))
// get weight
weight = getImageMix(self)->getWeight(id);
// return weight
return Py_BuildValue("h", weight);
}
// set source weight
PyObject * setWeight (PyImage * self, PyObject * args)
{
// get arguments
char * id;
short weight = 0;
if (self->m_image != NULL && PyArg_ParseTuple(args, "sh", &id, &weight))
// set weight
if (!getImageMix(self)->setWeight(id, weight))
{
// if not set, report error
PyErr_SetString(PyExc_RuntimeError, "Invalid id of source");;
return NULL;
}
// return none
Py_RETURN_NONE;
}
// methods structure
static PyMethodDef imageMixMethods[] =
{
{"getSource", (PyCFunction)Image_getSource, METH_VARARGS, "get image source"},
{"setSource", (PyCFunction)Image_setSource, METH_VARARGS, "set image source"},
{"getWeight", (PyCFunction)getWeight, METH_VARARGS, "get image source weight"},
{"setWeight", (PyCFunction)setWeight, METH_VARARGS, "set image source weight"},
// methods from ImageBase class
{"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"},
{NULL}
};
// attributes structure
static PyGetSetDef imageMixGetSets[] =
{ // attributes from ImageBase class
{"image", (getter)Image_getImage, NULL, "image data", NULL},
{"size", (getter)Image_getSize, NULL, "image size", NULL},
{"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL},
{"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
{"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject ImageMixType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.ImageMix", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Image_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image mixer", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
imageMixMethods, /* tp_methods */
0, /* tp_members */
imageMixGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Image_init<ImageMix>, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};

@ -0,0 +1,123 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined IMAGEMIX_H
#define IMAGEMIX_H
#include "Common.h"
#include "ImageBase.h"
#include "FilterBase.h"
/// class for source mixing
class ImageSourceMix : public ImageSource
{
public:
/// constructor
ImageSourceMix (const char * id) : ImageSource(id), m_weight(0x100) {}
/// destructor
virtual ~ImageSourceMix (void) {}
/// get offset
long long getOffset (void) { return m_offset; }
/// set offset
void setOffset (unsigned int * firstImg) { m_offset = m_image - firstImg; }
/// get weight
short getWeight (void) { return m_weight; }
/// set weight
void setWeight (short weight) { m_weight = weight; }
protected:
/// buffer offset to the first source buffer
long long m_offset;
/// source weight
short m_weight;
};
/// class for image mixer
class ImageMix : public ImageBase
{
public:
/// constructor
ImageMix (void) : ImageBase(false) {}
/// destructor
virtual ~ImageMix (void) {}
/// get weight
short getWeight (const char * id);
/// set weight
bool setWeight (const char * id, short weight);
protected:
/// create new source
virtual ImageSource * newSource (const char * id) { return new ImageSourceMix(id); }
/// calculate image from sources and set its availability
virtual void calcImage (unsigned int texId);
};
/// pixel filter for image mixer
class FilterImageMix : public FilterBase
{
public:
/// constructor
FilterImageMix (ImageSourceList & sources) : m_sources(sources) {}
/// destructor
virtual ~FilterImageMix (void) {}
protected:
/// source list
ImageSourceList & m_sources;
/// filter pixel, source int buffer
virtual unsigned int filter (unsigned int * src, short x, short y,
short * size, unsigned int pixSize, unsigned int val = 0)
{
// resulting pixel color
int color[] = {0, 0, 0, 0};
// iterate sources
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
{
// get pointer to mixer source
ImageSourceMix * mixSrc = static_cast<ImageSourceMix*>(*it);
// add weighted source pixel to result
color[0] += mixSrc->getWeight() * (src[mixSrc->getOffset()] & 0xFF);
color[1] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 8) & 0xFF);
color[2] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 16) & 0xFF);
color[3] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 24) & 0xFF);
}
// return resulting color
return ((color[0] >> 8) & 0xFF) | (color[1] & 0xFF00)
| ((color[2] << 8) & 0xFF0000) | ((color[3] << 16) & 0xFF000000);
}
};
#endif

@ -0,0 +1,265 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include <KX_BlenderCanvas.h>
#include <KX_BlenderRenderTools.h>
#include <RAS_IRasterizer.h>
#include <RAS_OpenGLRasterizer.h>
#include <KX_WorldInfo.h>
#include <KX_Light.h>
#include "ImageRender.h"
#include "ImageBase.h"
#include "BlendType.h"
#include "Exception.h"
// constructor
ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : m_scene(scene),
m_camera(camera)
{
// create screen area
m_area.winrct.xmin = m_upLeft[0];
m_area.winrct.ymin = m_upLeft[1];
m_area.winx = m_size[0];
m_area.winy = m_size[1];
// create canvas
m_canvas = new KX_BlenderCanvas(&m_area);
// create render tools
m_rendertools = new KX_BlenderRenderTools();
// create rasterizer
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
m_rasterizer->Init();
// initialize background colour
setBackground(0, 0, 255);
// refresh lights
refreshLights();
}
// destructor
ImageRender::~ImageRender (void)
{
// release allocated objects
delete m_rasterizer;
delete m_rendertools;
delete m_canvas;
}
// set background color
void ImageRender::setBackground (unsigned char red, unsigned char green, unsigned char blue)
{
m_background[0] = red;
m_background[1] = green;
m_background[2] = blue;
m_rasterizer->SetBackColor(m_background[0], m_background[1], m_background[2], 1.0);
}
// capture image from viewport
void ImageRender::calcImage (unsigned int texId)
{
// setup camera
bool cameraPasive = !m_camera->GetViewport();
// render scene
Render();
// reset camera
if (cameraPasive) m_camera->EnableViewport(false);
// get image from viewport
ImageViewport::calcImage(texId);
}
void ImageRender::Render()
{
//
}
// refresh lights
void ImageRender::refreshLights (void)
{
// clear lights list
//m_rendertools->RemoveAllLights();
// set lights
//for (int idx = 0; idx < scene->GetLightList()->GetCount(); ++idx)
// m_rendertools->AddLight(((KX_LightObject*)(scene->GetLightList()->GetValue(idx)))->GetLightData());
}
// cast Image pointer to ImageRender
inline ImageRender * getImageRender (PyImage * self)
{ return static_cast<ImageRender*>(self->m_image); }
// python methods
// Blender Scene type
BlendType<KX_Scene> sceneType ("KX_Scene");
// Blender Camera type
BlendType<KX_Camera> cameraType ("KX_Camera");
ExceptionID SceneInvalid, CameraInvalid;
ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid");
ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid");
// object initialization
static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
{
// parameters - scene object
PyObject * scene;
// camera object
PyObject * camera;
// parameter keywords
static char *kwlist[] = {"sceneObj", "cameraObj", NULL};
// get parameters
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &scene, &camera))
return -1;
try
{
// get scene pointer
KX_Scene * scenePtr (NULL);
if (scene != NULL) scenePtr = sceneType.checkType(scene);
// throw exception if scene is not available
if (scenePtr == NULL) THRWEXCP(SceneInvalid, S_OK);
// get camera pointer
KX_Camera * cameraPtr (NULL);
if (camera != NULL) cameraPtr = cameraType.checkType(camera);
// throw exception if camera is not available
if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK);
// get pointer to image structure
PyImage * self = reinterpret_cast<PyImage*>(pySelf);
// create source object
if (self->m_image != NULL) delete self->m_image;
self->m_image = new ImageRender(scenePtr, cameraPtr);
}
catch (Exception & exp)
{
exp.report();
return -1;
}
// initialization succeded
return 0;
}
// get background color
PyObject * getBackground (PyImage * self, void * closure)
{
return Py_BuildValue("[BBB]", getImageRender(self)->getBackground()[0],
getImageRender(self)->getBackground()[1], getImageRender(self)->getBackground()[2]);
}
// set color
static int setBackground (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints");
return -1;
}
// set background color
getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
(unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
(unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))));
// success
return 0;
}
// methods structure
static PyMethodDef imageRenderMethods[] =
{ // methods from ImageBase class
{"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"},
{NULL}
};
// attributes structure
static PyGetSetDef imageRenderGetSets[] =
{
{"background", (getter)getBackground, (setter)setBackground, "background color", NULL},
// attributes from ImageBase class
{"image", (getter)Image_getImage, NULL, "image data", NULL},
{"size", (getter)Image_getSize, NULL, "image size", NULL},
{"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL},
{"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
{"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject ImageRenderType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.ImageRender", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Image_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from render", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
imageRenderMethods, /* tp_methods */
0, /* tp_members */
imageRenderGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)ImageRender_init, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};

@ -0,0 +1,90 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined IMAGERENDER_H
#define IMAGERENDER_H
#include "Common.h"
#include <KX_Scene.h>
#include <KX_Camera.h>
#include <DNA_screen_types.h>
#include <RAS_ICanvas.h>
#include <RAS_IRasterizer.h>
#include <RAS_IRenderTools.h>
#include "ImageViewport.h"
/// class for render 3d scene
class ImageRender : public ImageViewport
{
public:
/// constructor
ImageRender (KX_Scene * scene, KX_Camera * camera);
/// destructor
virtual ~ImageRender (void);
/// get background color
unsigned char * getBackground (void) { return m_background; }
/// set background color
void setBackground (unsigned char red, unsigned char green, unsigned char blue);
protected:
/// rendered scene
KX_Scene * m_scene;
/// camera for render
KX_Camera * m_camera;
/// screen area for rendering
ScrArea m_area;
/// rendering device
RAS_ICanvas * m_canvas;
/// rasterizer
RAS_IRasterizer * m_rasterizer;
/// render tools
RAS_IRenderTools * m_rendertools;
/// background colour
unsigned char m_background[3];
/// render 3d scene to image
virtual void calcImage (unsigned int texId);
/// refresh lights
void refreshLights (void);
/// methods from KX_KetsjiEngine
bool BeginFrame();
void EndFrame();
void Render();
void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
void SetBackGround(KX_WorldInfo* wi);
void SetWorldSettings(KX_WorldInfo* wi);
};
#endif

@ -0,0 +1,298 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include "ImageViewport.h"
#include <BIF_gl.h>
#include "Texture.h"
#include "ImageBase.h"
#include "FilterSource.h"
// constructor
ImageViewport::ImageViewport (void) : m_texInit(false)
{
// get viewport rectangle
glGetIntegerv(GL_VIEWPORT, m_viewport);
// create buffer for viewport image
m_viewportImage = new BYTE [3 * getViewportSize()[0] * getViewportSize()[1]];
// set attributes
setWhole(false);
}
// destructor
ImageViewport::~ImageViewport (void)
{ delete m_viewportImage; }
// use whole viewport to capture image
void ImageViewport::setWhole (bool whole)
{
// set whole
m_whole = whole;
// set capture size to viewport size, if whole,
// otherwise place area in the middle of viewport
for (int idx = 0; idx < 2; ++idx)
{
// capture size
m_capSize[idx] = whole ? short(getViewportSize()[idx])
: calcSize(short(getViewportSize()[idx]));
// position
m_position[idx] = whole ? 0 : (getViewportSize()[idx] - m_capSize[idx]) >> 1;
}
// init image
init(m_capSize[0], m_capSize[1]);
// set capture position
setPosition();
}
void ImageViewport::setCaptureSize (short * size)
{
m_whole = false;
if (size == NULL)
size = m_capSize;
for (int idx = 0; idx < 2; ++idx)
{
if (size[idx] < 1)
m_capSize[idx] = 1;
else if (size[idx] > getViewportSize()[idx])
m_capSize[idx] = getViewportSize()[idx];
else
m_capSize[idx] = size[idx];
}
init(m_capSize[0], m_capSize[1]);
// set capture position
setPosition();
}
// set position of capture rectangle
void ImageViewport::setPosition (int * pos)
{
// if new position is not provided, use existing position
if (pos == NULL) pos = m_position;
// save position
for (int idx = 0; idx < 2; ++idx)
m_position[idx] = pos[idx] < 0 ? 0 : pos[idx] >= getViewportSize()[idx]
- m_capSize[idx] ? getViewportSize()[idx] - m_capSize[idx] : pos[idx];
// recalc up left corner
for (int idx = 0; idx < 2; ++idx)
m_upLeft[idx] = m_position[idx] + m_viewport[idx];
}
// capture image from viewport
void ImageViewport::calcImage (unsigned int texId)
{
// if scale was changed
if (m_scaleChange)
// reset image
init(m_capSize[0], m_capSize[1]);
// if texture wasn't initialized
if (!m_texInit)
{
// initialize it
loadTexture(texId, m_image, m_size);
m_texInit = true;
}
// if texture can be directly created
if (texId != 0 && m_pyfilter == NULL && m_capSize[0] == calcSize(m_capSize[0])
&& m_capSize[1] == calcSize(m_capSize[1]) && !m_flip)
{
// just copy current viewport to texture
glBindTexture(GL_TEXTURE_2D, texId);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1]);
// image is not available
m_avail = false;
}
// otherwise copy viewport to buffer, if image is not available
else if (!m_avail)
{
// get frame buffer data
glReadPixels(m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1], GL_RGB,
GL_UNSIGNED_BYTE, m_viewportImage);
// filter loaded data
FilterBGR24 filt;
filterImage(filt, m_viewportImage, m_capSize);
}
}
// cast Image pointer to ImageViewport
inline ImageViewport * getImageViewport (PyImage * self)
{ return static_cast<ImageViewport*>(self->m_image); }
// python methods
// get whole
static PyObject * ImageViewport_getWhole (PyImage * self, void * closure)
{
if (self->m_image != NULL && getImageViewport(self)->getWhole()) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
// set whole
static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
// set whole
if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
// success
return 0;
}
// get position
static PyObject * ImageViewport_getPosition (PyImage * self, void * closure)
{
return Py_BuildValue("(ii)", getImageViewport(self)->getPosition()[0],
getImageViewport(self)->getPosition()[1]);
}
// set position
static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints");
return -1;
}
// set position
int pos [] = {
int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1)))
};
getImageViewport(self)->setPosition(pos);
// success
return 0;
}
// get capture size
static PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure)
{
return Py_BuildValue("(ii)", getImageViewport(self)->getCaptureSize()[0],
getImageViewport(self)->getCaptureSize()[1]);
}
// set capture size
static int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints");
return -1;
}
// set capture size
short size [] = {
short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1)))
};
getImageViewport(self)->setCaptureSize(size);
// success
return 0;
}
// methods structure
static PyMethodDef imageViewportMethods[] =
{ // methods from ImageBase class
{"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"},
{NULL}
};
// attributes structure
static PyGetSetDef imageViewportGetSets[] =
{
{"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, "use whole viewport to capture", NULL},
{"position", (getter)ImageViewport_getPosition, (setter)ImageViewport_setPosition, "upper left corner of captured area", NULL},
{"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, "size of viewport area being captured", NULL},
// attributes from ImageBase class
{"image", (getter)Image_getImage, NULL, "image data", NULL},
{"size", (getter)Image_getSize, NULL, "image size", NULL},
{"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL},
{"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
{"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
{NULL}
};
// define python type
PyTypeObject ImageViewportType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.ImageViewport", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Image_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from viewport", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
imageViewportMethods, /* tp_methods */
0, /* tp_members */
imageViewportGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Image_init<ImageViewport>, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};

@ -0,0 +1,84 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined IMAGEVIEWPORT_H
#define IMAGEVIEWPORT_H
#include "Common.h"
#include "ImageBase.h"
/// class for viewport access
class ImageViewport : public ImageBase
{
public:
/// constructor
ImageViewport (void);
/// destructor
virtual ~ImageViewport (void);
/// is whole buffer used
bool getWhole (void) { return m_whole; }
/// set whole buffer use
void setWhole (bool whole);
/// get capture size in viewport
short * getCaptureSize (void) { return m_capSize; }
/// set capture size in viewport
void setCaptureSize (short * size = NULL);
/// get position in viewport
int * getPosition (void) { return m_position; }
/// set position in viewport
void setPosition (int * pos = NULL);
protected:
/// frame buffer rectangle
int m_viewport[4];
/// size of captured area
short m_capSize[2];
/// use whole viewport
bool m_whole;
/// position of capture rectangle in viewport
int m_position[2];
/// upper left point for capturing
int m_upLeft[2];
/// buffer to copy viewport
BYTE * m_viewportImage;
/// texture is initialized
bool m_texInit;
/// capture image from viewport
virtual void calcImage (unsigned int texId);
/// get viewport size
int * getViewportSize (void) { return m_viewport + 2; }
};
#endif

@ -0,0 +1,65 @@
#
# $Id$
#
# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): none yet.
#
# ***** END GPL LICENSE BLOCK *****
#
#
LIBNAME = videotex
DIR = $(OCGDIR)/gameengine/$(LIBNAME)
SOURCEDIR = source/gameengine/VideoTexture
include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += $(OGL_CPPFLAGS)
CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += -I../../blender/python
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
CPPFLAGS += -I../Rasterizer -I../GameLogic -I../SceneGraph
CPPFLAGS += -I../BlenderRoutines -I../Expressions -I../Ketsji
CPPFLAGS += -I../../kernel/gen_system
CPPFLAGS += -I.
CPPFLAGS += -I../../blender/blenkernel
CPPFLAGS += -I../../blender/blenlib
CPPFLAGS += -I../../blender/include
CPPFLAGS += -I../../blender/makesdna
CPPFLAGS += -I../../blender/imbuf
CPPFLAGS += -I../../blender/gpu
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
ifeq ($(WITH_FFMPEG),true)
CPPFLAGS += -DWITH_FFMPEG
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
endif

@ -0,0 +1,83 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include "PyTypeList.h"
#include <memory>
#include <vector>
#include <Python.h>
/// check, if type is in list
bool PyTypeList::in (PyTypeObject * type)
{
// if list exists
if (m_list.get() != NULL)
// iterate items in list
for (PyTypeListType::iterator it = m_list->begin(); it != m_list->end(); ++it)
// if item is found, return with success
if ((*it)->getType() == type) return true;
// otherwise return not found
return false;
}
/// add type to list
void PyTypeList::add (PyTypeObject * type, const char * name)
{
PyTypeListItem * typeItem;
// if list doesn't exist, create it
if (m_list.get() == NULL)
m_list.reset(new PyTypeListType());
if (!in(type))
// add new item to list
m_list->push_back(new PyTypeListItem(type, name));
}
/// prepare types
bool PyTypeList::ready (void)
{
// if list exists
if (m_list.get() != NULL)
// iterate items in list
for (PyTypeListType::iterator it = m_list->begin(); it != m_list->end(); ++it)
// if preparation failed, report it
if (PyType_Ready((*it)->getType()) < 0) return false;
// success
return true;
}
/// register types to module
void PyTypeList::reg (PyObject * module)
{
// if list exists
if (m_list.get() != NULL)
// iterate items in list
for (PyTypeListType::iterator it = m_list->begin(); it != m_list->end(); ++it)
{
// increase ref count
Py_INCREF((*it)->getType());
// add type to module
PyModule_AddObject(module, (*it)->getName(), (PyObject*)(*it)->getType());
}
}

@ -0,0 +1,85 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of blendTex library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined PYTYPELIST_H
#define PYTYPELIST_H
#include "Common.h"
#include <memory>
#include <vector>
#include <Python.h>
// forward declaration
class PyTypeListItem;
// type for list of types
typedef std::vector<PyTypeListItem*> PyTypeListType;
/// class to store list of python types
class PyTypeList
{
public:
/// check, if type is in list
bool in (PyTypeObject * type);
/// add type to list
void add (PyTypeObject * type, const char * name);
/// prepare types
bool ready (void);
/// register types to module
void reg (PyObject * module);
protected:
/// pointer to list of types
std::auto_ptr<PyTypeListType> m_list;
};
/// class for item of python type list
class PyTypeListItem
{
public:
/// constructor adds type into list
PyTypeListItem (PyTypeObject * type, const char * name)
: m_type(type), m_name(name)
{ }
/// does type match
PyTypeObject * getType (void) { return m_type; }
/// get name of type
const char * getName (void) { return m_name; }
protected:
/// pointer to type object
PyTypeObject * m_type;
/// name of type
const char * m_name;
};
#endif

@ -0,0 +1,33 @@
#!/usr/bin/python
import sys
Import ('env')
sources = env.Glob('*.cpp')
incs = '. #source/gameengine/Ketsji #source/gameengine/Expressions'
incs += ' #source/gameengine/GameLogic #source/gameengine/SceneGraph #source/gameengine/Rasterizer'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
incs += ' #source/gameengine/BlenderRoutines'
incs += ' #source/blender/include #source/blender/blenlib #source/blender/blenkernel'
incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python'
incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/moto/include'
incs += ' #intern/guardedalloc #intern/SoundSystem'
incs += ' #extern/glew/include'
cflags = []
defs = ''
if env['OURPLATFORM'] == 'win32-vc':
cflags.append('/GR')
cflags.append('/Ox')
incs += ' ' + env['BF_PYTHON'] + '/lib/python' + env['BF_PYTHON_VERSION'] + "/site-packages/numpy/core/include"
incs += ' ' + env['BF_PYTHON_INC']
#incs += ' ' + env['BF_OPENGL_INC']
if env['WITH_BF_FFMPEG']:
defs += ' WITH_FFMPEG'
incs += ' ' + env['BF_FFMPEG_INC']
defs += ' __STDC_CONSTANT_MACROS'
env.BlenderLib ( 'bf_videotex', sources, Split(incs), Split(defs), libtype=['game','player'], priority=[25, 72], compileflags = cflags )

@ -0,0 +1,463 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
// implementation
#include <Python.h>
#include <structmember.h>
#include <KX_GameObject.h>
#include <RAS_MeshObject.h>
#include <DNA_mesh_types.h>
#include <DNA_meshdata_types.h>
#include <DNA_image_types.h>
#include <IMB_imbuf_types.h>
#include <BDR_drawmesh.h>
#include <KX_PolygonMaterial.h>
#include <MEM_guardedalloc.h>
#include <KX_BlenderMaterial.h>
#include <BL_Texture.h>
#include "KX_KetsjiEngine.h"
#include "KX_PythonInit.h"
#include "Texture.h"
#include "ImageBase.h"
#include "Exception.h"
#include <memory.h>
#include <BIF_gl.h>
// macro for exception handling and logging
#define CATCH_EXCP catch (Exception & exp) \
{ exp.report(); }
// are Blender materials used
bool blendMats = false;
// Blender GameObject type
BlendType<KX_GameObject> gameObjectType ("KX_GameObject");
// load texture
void loadTexture (unsigned int texId, unsigned int * texture, short * size,
bool mipmap)
{
// load texture for rendering
glBindTexture(GL_TEXTURE_2D, texId);
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, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, texture);
}
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, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
// get pointer to material
RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID)
{
// if object is available
if (obj != NULL)
{
// get pointer to texture image
KX_GameObject * gameObj = gameObjectType.checkType(obj);
if (gameObj != NULL && gameObj->GetMeshCount() > 0)
{
// get material from mesh
RAS_MeshObject * mesh = gameObj->GetMesh(0);
RAS_MeshMaterial *meshMat = mesh->GetMeshMaterial(matID);
if (meshMat != NULL && meshMat->m_bucket != NULL)
// return pointer to polygon or blender material
return meshMat->m_bucket->GetPolyMaterial();
}
}
// otherwise material was not found
return NULL;
}
// get material ID
short getMaterialID (PyObject * obj, char * name)
{
// search for material
for (short matID = 0;; ++matID)
{
// get material
RAS_IPolyMaterial * mat = getMaterial(obj, matID);
// if material is not available, report that no material was found
if (mat == NULL) break;
// if material name matches
if (strcmp(mat->GetMaterialName().ReadPtr(), name) == 0)
// matID is found
return matID;
}
// material was not found
return -1;
}
// Texture object allocation
PyObject * Texture_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
{
// allocate object
Texture * self = reinterpret_cast<Texture*>(type->tp_alloc(type, 0));
// initialize object structure
self->m_actTex = 0;
self->m_orgSaved = false;
self->m_imgTexture = NULL;
self->m_matTexture = NULL;
self->m_mipmap = false;
self->m_scaledImg = NULL;
self->m_scaledImgSize = 0;
self->m_source = NULL;
self->m_lastClock = 0.0;
// return allocated object
return reinterpret_cast<PyObject*>(self);
}
// forward declaration
PyObject * Texture_close(Texture * self);
int Texture_setSource (Texture * self, PyObject * value, void * closure);
// Texture object deallocation
void Texture_dealloc (Texture * self)
{
// release renderer
Py_XDECREF(self->m_source);
// close texture
Texture_close(self);
// release scaled image buffer
delete [] self->m_scaledImg;
// release object
self->ob_type->tp_free((PyObject*)self);
}
ExceptionID MaterialNotAvail;
ExpDesc MaterialNotAvailDesc (MaterialNotAvail, "Texture material is not available");
// Texture object initialization
int Texture_init (Texture *self, PyObject *args, PyObject *kwds)
{
// parameters - game object with video texture
PyObject * obj = NULL;
// material ID
short matID = 0;
// texture ID
short texID = 0;
// texture object with shared texture ID
Texture * texObj = NULL;
static char *kwlist[] = {"gameObj", "materialID", "textureID", "textureObj", NULL};
// get parameters
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhO!", kwlist, &obj, &matID,
&texID, &TextureType, &texObj))
return -1;
// if parameters are available
if (obj != NULL)
{
// process polygon material or blender material
try
{
// get pointer to texture image
RAS_IPolyMaterial * mat = getMaterial(obj, matID);
if (mat != NULL)
{
// is it blender material or polygon material
blendMats = (mat->GetFlag() & RAS_BLENDERMAT) != 0;
if (blendMats)
// get blender material texture
self->m_matTexture = static_cast<KX_BlenderMaterial*>(mat)->getTex(texID);
else
{
// get texture pointer from polygon material
MTFace * tface = static_cast<KX_PolygonMaterial*>(mat)->GetMTFace();
self->m_imgTexture = (Image*)tface->tpage;
}
}
// check if texture is available, if not, initialization failed
if (self->m_imgTexture == NULL && self->m_matTexture == NULL)
// throw exception if initialization failed
THRWEXCP(MaterialNotAvail, S_OK);
// if texture object is provided
if (texObj != NULL)
{
// copy texture code
self->m_actTex = texObj->m_actTex;
self->m_mipmap = texObj->m_mipmap;
if (texObj->m_source != NULL)
Texture_setSource(self, reinterpret_cast<PyObject*>(texObj->m_source), NULL);
}
else
// otherwise generate texture code
glGenTextures(1, (GLuint*)&self->m_actTex);
}
catch (Exception & exp)
{
exp.report();
return -1;
}
}
// initialization succeded
return 0;
}
// close added texture
PyObject * Texture_close(Texture * self)
{
// restore texture
if (self->m_orgSaved)
{
self->m_orgSaved = false;
// restore original texture code
if (blendMats)
self->m_matTexture->swapTexture(self->m_orgTex);
else
self->m_imgTexture->bindcode = self->m_orgTex;
// drop actual texture
if (self->m_actTex != 0)
{
glDeleteTextures(1, (GLuint *)&self->m_actTex);
self->m_actTex = 0;
}
}
Py_RETURN_NONE;
}
// refresh texture
PyObject * Texture_refresh (Texture * self, PyObject * args)
{
// get parameter - refresh source
PyObject * param;
if (!PyArg_ParseTuple(args, "O", &param) || !PyBool_Check(param))
{
// report error
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return NULL;
}
// some trick here: we are in the business of loading a texture,
// no use to do it if we are still in the same rendering frame.
// We find this out by looking at the engine current clock time
KX_KetsjiEngine* engine = KX_GetActiveEngine();
if (engine->GetClockTime() != self->m_lastClock)
{
self->m_lastClock = engine->GetClockTime();
// set source refresh
bool refreshSource = (param == Py_True);
// try to proces texture from source
try
{
// if source is available
if (self->m_source != NULL)
{
// check texture code
if (!self->m_orgSaved)
{
self->m_orgSaved = true;
// save original image code
if (blendMats)
self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex);
else
{
self->m_orgTex = self->m_imgTexture->bindcode;
self->m_imgTexture->bindcode = self->m_actTex;
}
}
// get texture
unsigned int * texture = self->m_source->m_image->getImage(self->m_actTex);
// if texture is available
if (texture != NULL)
{
// get texture size
short * orgSize = self->m_source->m_image->getSize();
// calc scaled sizes
short size[] = {ImageBase::calcSize(orgSize[0]), ImageBase::calcSize(orgSize[1])};
// scale texture if needed
if (size[0] != orgSize[0] || size[1] != orgSize[1])
{
// if scaled image buffer is smaller than needed
if (self->m_scaledImgSize < (unsigned int)(size[0] * size[1]))
{
// new size
self->m_scaledImgSize = size[0] * size[1];
// allocate scaling image
delete [] self->m_scaledImg;
self->m_scaledImg = new unsigned int[self->m_scaledImgSize];
}
// scale texture
gluScaleImage(GL_RGBA, orgSize[0], orgSize[1], GL_UNSIGNED_BYTE, texture,
size[0], size[1], GL_UNSIGNED_BYTE, self->m_scaledImg);
// use scaled image instead original
texture = self->m_scaledImg;
}
// load texture for rendering
loadTexture (self->m_actTex, texture, size, self->m_mipmap);
// refresh texture source, if required
if (refreshSource) self->m_source->m_image->refresh();
}
}
}
CATCH_EXCP;
}
Py_RETURN_NONE;
}
// get mipmap value
PyObject * Texture_getMipmap (Texture * self, void * closure)
{
// return true if flag is set, otherwise false
if (self->m_mipmap) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
// set mipmap value
int Texture_setMipmap (Texture * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
// set mipmap
self->m_mipmap = value == Py_True;
// success
return 0;
}
// get source object
PyObject * Texture_getSource (Texture * self, PyObject * value, void * closure)
{
// if source exists
if (self->m_source != NULL)
{
Py_INCREF(self->m_source);
return reinterpret_cast<PyObject*>(self->m_source);
}
// otherwise return None
Py_RETURN_NONE;
}
// set source object
int Texture_setSource (Texture * self, PyObject * value, void * closure)
{
// check new value
if (value == NULL || !pyImageTypes.in(value->ob_type))
{
// report value error
PyErr_SetString(PyExc_TypeError, "Invalid type of value");
return -1;
}
// increase ref count for new value
Py_INCREF(value);
// release previous
Py_XDECREF(self->m_source);
// set new value
self->m_source = reinterpret_cast<PyImage*>(value);
// return success
return 0;
}
// class Texture methods
static PyMethodDef textureMethods[] =
{
{ "close", (PyCFunction)Texture_close, METH_NOARGS, "Close dynamic texture and restore original"},
{ "refresh", (PyCFunction)Texture_refresh, METH_VARARGS, "Refresh texture from source"},
{NULL} /* Sentinel */
};
// class Texture attributes
static PyGetSetDef textureGetSets[] =
{
{"source", (getter)Texture_getSource, (setter)Texture_setSource, "source of texture", NULL},
{"mipmap", (getter)Texture_getMipmap, (setter)Texture_setMipmap, "mipmap texture", NULL},
{NULL}
};
// class Texture declaration
PyTypeObject TextureType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.Texture", /*tp_name*/
sizeof(Texture), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Texture_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Texture objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
textureMethods, /* tp_methods */
0, /* tp_members */
textureGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Texture_init, /* tp_init */
0, /* tp_alloc */
Texture_new, /* tp_new */
};

@ -0,0 +1,87 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined TEXTURE_H
#define TEXTURE_H
#include <Python.h>
#include <structmember.h>
#include <DNA_image_types.h>
#include <BL_Texture.h>
#include <KX_BlenderMaterial.h>
#include "ImageBase.h"
#include "BlendType.h"
// type Texture declaration
struct Texture
{
PyObject_HEAD
// video texture bind code
unsigned int m_actTex;
// original texture bind code
unsigned int m_orgTex;
// original texture saved
bool m_orgSaved;
// texture image for game materials
Image * m_imgTexture;
// texture for blender materials
BL_Texture * m_matTexture;
// use mipmapping
bool m_mipmap;
// scaled image buffer
unsigned int * m_scaledImg;
// scaled image buffer size
unsigned int m_scaledImgSize;
// last refresh
double m_lastClock;
// image source
PyImage * m_source;
};
// Texture type description
extern PyTypeObject TextureType;
// usage of Blender materials
extern bool blendMats;
// load texture
void loadTexture (unsigned int texId, unsigned int * texture, short * size,
bool mipmap = false);
// get material
RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID);
// get material ID
short getMaterialID (PyObject * obj, char * name);
#endif

@ -0,0 +1,183 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if defined WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>
#endif
#include "VideoBase.h"
#include "FilterSource.h"
// VideoBase implementation
// initialize image data
void VideoBase::init(short width, short height)
{
// save original sizes
m_orgSize[0] = width;
m_orgSize[1] = height;
// call base class initialization
ImageBase::init(width, height);
}
// process video frame
void VideoBase::process (BYTE * sample)
{
// if scale was changed
if (m_scaleChange)
// reset image
init(m_orgSize[0], m_orgSize[1]);
// if image is allocated and is able to store new image
if (m_image != NULL && !m_avail)
{
// filters used
FilterRGB24 filtRGB;
FilterYV12 filtYUV;
// convert video format to image
switch (m_format)
{
case RGB24:
// use filter object for format to convert image
filterImage(filtRGB, sample, m_orgSize);
// finish
break;
case YV12:
// use filter object for format to convert image
filtYUV.setBuffs(sample, m_orgSize);
filterImage(filtYUV, sample, m_orgSize);
// finish
break;
}
}
}
// python functions
// exceptions for video source initialization
ExceptionID SourceVideoEmpty, SourceVideoCreation;
ExpDesc SourceVideoEmptyDesc (SourceVideoEmpty, "Source Video is empty");
ExpDesc SourceVideoCreationDesc (SourceVideoCreation, "SourceVideo object was not created");
// open video source
void Video_open (VideoBase * self, char * file, short captureID)
{
// if file is empty, throw exception
if (file == NULL) THRWEXCP(SourceVideoEmpty, S_OK);
// open video file or capture device
if (captureID >= 0)
self->openCam(file, captureID);
else
self->openFile(file);
}
// play video
PyObject * Video_play (PyImage * self)
{ if (getVideo(self)->play()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
// stop video
PyObject * Video_stop (PyImage * self)
{ if (getVideo(self)->stop()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
// get status
PyObject * Video_getStatus (PyImage * self, void * closure)
{
return Py_BuildValue("h", getVideo(self)->getStatus());
}
// refresh video
PyObject * Video_refresh (PyImage * self)
{
getVideo(self)->refresh();
return Video_getStatus(self, NULL);
}
// get range
PyObject * Video_getRange (PyImage * self, void * closure)
{
return Py_BuildValue("[ff]", getVideo(self)->getRange()[0],
getVideo(self)->getRange()[1]);
}
// set range
int Video_setRange (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2
|| !PyFloat_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyFloat_Check(PySequence_Fast_GET_ITEM(value, 1)))
{
PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 longs");
return -1;
}
// set range
getVideo(self)->setRange(PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)),
PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)));
// success
return 0;
}
// get repeat
PyObject * Video_getRepeat (PyImage * self, void * closure)
{ return Py_BuildValue("h", getVideo(self)->getRepeat()); }
// set repeat
int Video_setRepeat (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PyInt_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be an int");
return -1;
}
// set repeat
getVideo(self)->setRepeat(int(PyInt_AsLong(value)));
// success
return 0;
}
// get frame rate
PyObject * Video_getFrameRate (PyImage * self, void * closure)
{ return Py_BuildValue("f", double(getVideo(self)->getFrameRate())); }
// set frame rate
int Video_setFrameRate (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PyFloat_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a float");
return -1;
}
// set repeat
getVideo(self)->setFrameRate(float(PyFloat_AsDouble(value)));
// success
return 0;
}

@ -0,0 +1,185 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined VIDEOBASE_H
#define VIDEOBASE_H
#include <Python.h>
#include "ImageBase.h"
#include "Exception.h"
// source states
const int SourceError = -1;
const int SourceEmpty = 0;
const int SourceReady = 1;
const int SourcePlaying = 2;
const int SourceStopped = 3;
// video source formats
enum VideoFormat { None, RGB24, YV12 };
/// base class for video source
class VideoBase : public ImageBase
{
public:
/// constructor
VideoBase (void) : ImageBase(true), m_format(None), m_status(SourceEmpty),
m_repeat(0), m_frameRate(1.0)
{
m_orgSize[0] = m_orgSize[1] = 0;
m_range[0] = m_range[1] = 0.0;
}
/// destructor
virtual ~VideoBase (void) {}
/// open video file
virtual void openFile (char * file)
{
m_isFile = true;
m_status = SourceReady;
}
/// open video capture device
virtual void openCam (char * file, short camIdx)
{
m_isFile = false;
m_status = SourceReady;
}
/// play video
virtual bool play (void)
{
if (m_status == SourceReady || m_status == SourceStopped)
{
m_status = SourcePlaying;
return true;
}
return false;
}
/// stop/pause video
virtual bool stop (void)
{
if (m_status == SourcePlaying)
{
m_status = SourceStopped;
return true;
}
return false;
}
// get video status
int getStatus (void) { return m_status; }
/// get play range
const double * getRange (void) { return m_range; }
/// set play range
virtual void setRange (double start, double stop)
{
if (m_isFile)
{
m_range[0] = start;
m_range[1] = stop;
}
}
// get video repeat
int getRepeat (void) { return m_repeat; }
/// set video repeat
virtual void setRepeat (int rep)
{ if (m_isFile) m_repeat = rep; }
/// get frame rate
float getFrameRate (void) { return m_frameRate; }
/// set frame rate
virtual void setFrameRate (float rate)
{ if (m_isFile) m_frameRate = rate > 0.0 ? rate : 1.0f; }
protected:
/// video format
VideoFormat m_format;
/// original video size
short m_orgSize[2];
/// video status
int m_status;
/// is source file
bool m_isFile;
/// replay range
double m_range[2];
/// repeat count
int m_repeat;
/// frame rate
float m_frameRate;
/// initialize image data
void init (short width, short height);
/// process source data
void process (BYTE * sample);
};
// python fuctions
// cast Image pointer to Video
inline VideoBase * getVideo (PyImage * self)
{ return static_cast<VideoBase*>(self->m_image); }
extern ExceptionID SourceVideoCreation;
// object initialization
template <class T> void Video_init (PyImage * self)
{
// create source video object
if (self->m_image != NULL) delete self->m_image;
HRESULT hRslt = S_OK;
self->m_image = new T(&hRslt);
CHCKHRSLT(hRslt, SourceVideoCreation);
}
// video functions
void Video_open (VideoBase * self, char * file, short captureID);
PyObject * Video_play (PyImage * self);
PyObject * Video_stop (PyImage * self);
PyObject * Video_refresh (PyImage * self);
PyObject * Video_getStatus (PyImage * self, void * closure);
PyObject * Video_getRange (PyImage * self, void * closure);
int Video_setRange (PyImage * self, PyObject * value, void * closure);
PyObject * Video_getRepeat (PyImage * self, void * closure);
int Video_setRepeat (PyImage * self, PyObject * value, void * closure);
PyObject * Video_getFrameRate (PyImage * self, void * closure);
int Video_setFrameRate (PyImage * self, PyObject * value, void * closure);
#endif

@ -0,0 +1,753 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
#include <string>
#include "Exception.h"
#include "VideoFFmpeg.h"
#ifdef WITH_FFMPEG
// default framerate
const double defFrameRate = 25.0;
// time scale constant
const long timeScale = 1000;
// macro for exception handling and logging
#define CATCH_EXCP catch (Exception & exp) \
{ exp.report(); m_status = SourceError; }
extern "C" void do_init_ffmpeg();
// class RenderVideo
// constructor
VideoFFmpeg::VideoFFmpeg (HRESULT * hRslt) : VideoBase(),
m_codec(NULL), m_formatCtx(NULL), m_codecCtx(NULL),
m_frame(NULL), m_frameDeinterlaced(NULL), m_frameBGR(NULL), m_imgConvertCtx(NULL),
m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0),
m_lastFrame(-1), m_curPosition(-1), m_startTime(0),
m_captWidth(0), m_captHeight(0), m_captRate(0.f)
{
// set video format
m_format = RGB24;
// force flip because ffmpeg always return the image in the wrong orientation for texture
setFlip(true);
// construction is OK
*hRslt = S_OK;
}
// destructor
VideoFFmpeg::~VideoFFmpeg ()
{
}
// release components
bool VideoFFmpeg::release()
{
// release
if (m_codecCtx)
{
avcodec_close(m_codecCtx);
}
if (m_formatCtx)
{
av_close_input_file(m_formatCtx);
}
if (m_frame)
{
av_free(m_frame);
}
if (m_frameDeinterlaced)
{
MEM_freeN(m_frameDeinterlaced->data[0]);
av_free(m_frameDeinterlaced);
}
if (m_frameBGR)
{
MEM_freeN(m_frameBGR->data[0]);
av_free(m_frameBGR);
}
if (m_imgConvertCtx)
{
sws_freeContext(m_imgConvertCtx);
}
m_codec = NULL;
m_codecCtx = NULL;
m_formatCtx = NULL;
m_frame = NULL;
m_frame = NULL;
m_frameBGR = NULL;
m_imgConvertCtx = NULL;
// object will be deleted after that
return true;
}
// set initial parameters
void VideoFFmpeg::initParams (short width, short height, float rate)
{
m_captWidth = width;
m_captHeight = height;
m_captRate = rate;
}
int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams)
{
AVFormatContext *formatCtx;
int i, videoStream;
AVCodec *codec;
AVCodecContext *codecCtx;
if(av_open_input_file(&formatCtx, filename, inputFormat, 0, formatParams)!=0)
return -1;
if(av_find_stream_info(formatCtx)<0)
{
av_close_input_file(formatCtx);
return -1;
}
/* Find the first video stream */
videoStream=-1;
for(i=0; i<formatCtx->nb_streams; i++)
{
if(formatCtx->streams[i] &&
get_codec_from_stream(formatCtx->streams[i]) &&
(get_codec_from_stream(formatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO))
{
videoStream=i;
break;
}
}
if(videoStream==-1)
{
av_close_input_file(formatCtx);
return -1;
}
codecCtx = get_codec_from_stream(formatCtx->streams[videoStream]);
/* Find the decoder for the video stream */
codec=avcodec_find_decoder(codecCtx->codec_id);
if(codec==NULL)
{
av_close_input_file(formatCtx);
return -1;
}
codecCtx->workaround_bugs = 1;
if(avcodec_open(codecCtx, codec)<0)
{
av_close_input_file(formatCtx);
return -1;
}
#ifdef FFMPEG_OLD_FRAME_RATE
if(codecCtx->frame_rate>1000 && codecCtx->frame_rate_base==1)
codecCtx->frame_rate_base=1000;
m_baseFrameRate = (double)codecCtx->frame_rate / (double)codecCtx->frame_rate_base;
#else
m_baseFrameRate = av_q2d(formatCtx->streams[videoStream]->r_frame_rate);
#endif
if (m_baseFrameRate <= 0.0)
m_baseFrameRate = defFrameRate;
m_codec = codec;
m_codecCtx = codecCtx;
m_formatCtx = formatCtx;
m_videoStream = videoStream;
m_frame = avcodec_alloc_frame();
m_frameDeinterlaced = avcodec_alloc_frame();
m_frameBGR = avcodec_alloc_frame();
// allocate buffer if deinterlacing is required
avpicture_fill((AVPicture*)m_frameDeinterlaced,
(uint8_t*)MEM_callocN(avpicture_get_size(
m_codecCtx->pix_fmt,
m_codecCtx->width, m_codecCtx->height),
"ffmpeg deinterlace"),
m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height);
// allocate buffer to store final decoded frame
avpicture_fill((AVPicture*)m_frameBGR,
(uint8_t*)MEM_callocN(avpicture_get_size(
PIX_FMT_BGR24,
m_codecCtx->width, m_codecCtx->height),
"ffmpeg bgr"),
PIX_FMT_BGR24, m_codecCtx->width, m_codecCtx->height);
// allocate sws context
m_imgConvertCtx = sws_getContext(
m_codecCtx->width,
m_codecCtx->height,
m_codecCtx->pix_fmt,
m_codecCtx->width,
m_codecCtx->height,
PIX_FMT_BGR24,
SWS_FAST_BILINEAR,
NULL, NULL, NULL);
if (!m_imgConvertCtx) {
avcodec_close(m_codecCtx);
av_close_input_file(m_formatCtx);
av_free(m_frame);
MEM_freeN(m_frameDeinterlaced->data[0]);
av_free(m_frameDeinterlaced);
MEM_freeN(m_frameBGR->data[0]);
av_free(m_frameBGR);
return -1;
}
return 0;
}
// open video file
void VideoFFmpeg::openFile (char * filename)
{
do_init_ffmpeg();
if (openStream(filename, NULL, NULL) != 0)
return;
if (m_codecCtx->gop_size)
m_preseek = (m_codecCtx->gop_size < 25) ? m_codecCtx->gop_size+1 : 25;
else if (m_codecCtx->has_b_frames)
m_preseek = 25; // should determine gopsize
else
m_preseek = 0;
// get video time range
m_range[0] = 0.0;
m_range[1] = (double)m_formatCtx->duration / AV_TIME_BASE;
// open base class
VideoBase::openFile(filename);
if (
#ifdef FFMPEG_PB_IS_POINTER
m_formatCtx->pb->is_streamed
#else
m_formatCtx->pb.is_streamed
#endif
)
{
// the file is in fact a streaming source, prevent seeking
m_isFile = false;
// for streaming it is important to do non blocking read
m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK;
}
}
// open video capture device
void VideoFFmpeg::openCam (char * file, short camIdx)
{
// open camera source
AVInputFormat *inputFormat;
AVFormatParameters formatParams;
AVRational frameRate;
char *p, filename[28], rateStr[20];
do_init_ffmpeg();
memset(&formatParams, 0, sizeof(formatParams));
#ifdef WIN32
// video capture on windows only through Video For Windows driver
inputFormat = av_find_input_format("vfwcap");
if (!inputFormat)
// Video For Windows not supported??
return;
sprintf(filename, "%d", camIdx);
#else
// In Linux we support two types of devices: VideoForLinux and DV1394.
// the user specify it with the filename:
// [<device_type>][:<standard>]
// <device_type> : 'v4l' for VideoForLinux, 'dv1394' for DV1394. By default 'v4l'
// <standard> : 'pal', 'secam' or 'ntsc'. By default 'ntsc'
// The driver name is constructed automatically from the device type:
// v4l : /dev/video<camIdx>
// dv1394: /dev/dv1394/<camIdx>
// If you have different driver name, you can specify the driver name explicitely
// instead of device type. Examples of valid filename:
// /dev/v4l/video0:pal
// /dev/ieee1394/1:ntsc
// dv1394:secam
// v4l:pal
if (file && strstr(file, "1394") != NULL)
{
// the user specifies a driver, check if it is v4l or d41394
inputFormat = av_find_input_format("dv1394");
sprintf(filename, "/dev/dv1394/%d", camIdx);
} else
{
inputFormat = av_find_input_format("video4linux");
sprintf(filename, "/dev/video%d", camIdx);
}
if (!inputFormat)
// these format should be supported, check ffmpeg compilation
return;
if (file && strncmp(file, "/dev", 4) == 0)
{
// user does not specify a driver
strncpy(filename, file, sizeof(filename));
filename[sizeof(filename)-1] = 0;
if ((p = strchr(filename, ':')) != 0)
*p = 0;
}
if (file && (p = strchr(file, ':')) != NULL)
formatParams.standard = p+1;
#endif
//frame rate
if (m_captRate <= 0.f)
m_captRate = defFrameRate;
sprintf(rateStr, "%f", m_captRate);
av_parse_video_frame_rate(&frameRate, rateStr);
// populate format parameters
// need to specify the time base = inverse of rate
formatParams.time_base.num = frameRate.den;
formatParams.time_base.den = frameRate.num;
formatParams.width = m_captWidth;
formatParams.height = m_captHeight;
if (openStream(filename, inputFormat, &formatParams) != 0)
return;
// for video capture it is important to do non blocking read
m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK;
// open base class
VideoBase::openCam(file, camIdx);
}
// play video
bool VideoFFmpeg::play (void)
{
try
{
// if object is able to play
if (VideoBase::play())
{
// set video position
setPositions();
// return success
return true;
}
}
CATCH_EXCP;
return false;
}
// stop video
bool VideoFFmpeg::stop (void)
{
try
{
if (VideoBase::stop())
{
return true;
}
}
CATCH_EXCP;
return false;
}
// set video range
void VideoFFmpeg::setRange (double start, double stop)
{
try
{
// set range
VideoBase::setRange(start, stop);
// set range for video
setPositions();
}
CATCH_EXCP;
}
// set framerate
void VideoFFmpeg::setFrameRate (float rate)
{
VideoBase::setFrameRate(rate);
}
// image calculation
void VideoFFmpeg::calcImage (unsigned int texId)
{
loadFrame();
}
// load frame from video
void VideoFFmpeg::loadFrame (void)
{
// get actual time
double actTime = PIL_check_seconds_timer() - m_startTime;
// if video has ended
if (m_isFile && actTime * m_frameRate >= m_range[1])
{
// if repeats are set, decrease them
if (m_repeat > 0)
--m_repeat;
// if video has to be replayed
if (m_repeat != 0)
{
// reset its position
actTime -= (m_range[1] - m_range[0]) / m_frameRate;
m_startTime += (m_range[1] - m_range[0]) / m_frameRate;
}
// if video has to be stopped, stop it
else
m_status = SourceStopped;
}
// if video is playing
if (m_status == SourcePlaying)
{
// actual frame
long actFrame = m_isFile ? long(actTime * actFrameRate()) : m_lastFrame + 1;
// if actual frame differs from last frame
if (actFrame != m_lastFrame)
{
// get image
if(grabFrame(actFrame))
{
AVFrame* frame = getFrame();
// save actual frame
m_lastFrame = actFrame;
// init image, if needed
init(short(m_codecCtx->width), short(m_codecCtx->height));
// process image
process((BYTE*)(frame->data[0]));
}
}
}
}
// set actual position
void VideoFFmpeg::setPositions (void)
{
// set video start time
m_startTime = PIL_check_seconds_timer();
// if file is played and actual position is before end position
if (m_isFile && m_lastFrame >= 0 && m_lastFrame < m_range[1] * actFrameRate())
// continue from actual position
m_startTime -= double(m_lastFrame) / actFrameRate();
else
m_startTime -= m_range[0];
}
// position pointer in file, position in second
bool VideoFFmpeg::grabFrame(long position)
{
AVPacket packet;
int frameFinished;
int posFound = 1;
bool frameLoaded = false;
long long targetTs = 0;
// first check if the position that we are looking for is in the preseek range
// if so, just read the frame until we get there
if (position > m_curPosition + 1
&& m_preseek
&& position - (m_curPosition + 1) < m_preseek)
{
while(av_read_frame(m_formatCtx, &packet)>=0)
{
if (packet.stream_index == m_videoStream)
{
avcodec_decode_video(
m_codecCtx,
m_frame, &frameFinished,
packet.data, packet.size);
if (frameFinished)
m_curPosition++;
}
av_free_packet(&packet);
if (position == m_curPosition+1)
break;
}
}
// if the position is not in preseek, do a direct jump
if (position != m_curPosition + 1) {
double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
long long pos = (long long)
((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate);
long long startTs = m_formatCtx->streams[m_videoStream]->start_time;
if (pos < 0)
pos = 0;
if (startTs != AV_NOPTS_VALUE)
pos += (long long)(startTs * AV_TIME_BASE * timeBase);
av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
// current position is now lost, guess a value.
// It's not important because it will be set at this end of this function
m_curPosition = position - m_preseek - 1;
// this is the timestamp of the frame we're looking for
targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase);
if (startTs != AV_NOPTS_VALUE)
targetTs += startTs;
posFound = 0;
avcodec_flush_buffers(m_codecCtx);
}
while(av_read_frame(m_formatCtx, &packet)>=0)
{
if(packet.stream_index == m_videoStream)
{
avcodec_decode_video(m_codecCtx,
m_frame, &frameFinished,
packet.data, packet.size);
if (frameFinished && !posFound)
{
if (packet.dts >= targetTs)
posFound = 1;
}
if(frameFinished && posFound == 1)
{
AVFrame * input = m_frame;
/* This means the data wasnt read properly,
this check stops crashing */
if ( input->data[0]==0 && input->data[1]==0
&& input->data[2]==0 && input->data[3]==0)
{
av_free_packet(&packet);
break;
}
if (m_deinterlace)
{
if (avpicture_deinterlace(
(AVPicture*) m_frameDeinterlaced,
(const AVPicture*) m_frame,
m_codecCtx->pix_fmt,
m_codecCtx->width,
m_codecCtx->height) >= 0)
{
input = m_frameDeinterlaced;
}
}
// convert to BGR24
sws_scale(m_imgConvertCtx,
input->data,
input->linesize,
0,
m_codecCtx->height,
m_frameBGR->data,
m_frameBGR->linesize);
av_free_packet(&packet);
frameLoaded = true;
break;
}
}
av_free_packet(&packet);
}
if (frameLoaded)
m_curPosition = position;
return frameLoaded;
}
// python methods
// cast Image pointer to VideoFFmpeg
inline VideoFFmpeg * getVideoFFmpeg (PyImage * self)
{ return static_cast<VideoFFmpeg*>(self->m_image); }
// object initialization
static int VideoFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
{
PyImage * self = reinterpret_cast<PyImage*>(pySelf);
// parameters - video source
// file name or format type for capture (only for Linux: video4linux or dv1394)
char * file = NULL;
// capture device number
short capt = -1;
// capture width, only if capt is >= 0
short width = 0;
// capture height, only if capt is >= 0
short height = 0;
// capture rate, only if capt is >= 0
float rate = 25.f;
static char *kwlist[] = {"file", "capture", "rate", "width", "height", NULL};
// get parameters
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|hfhh", kwlist, &file, &capt,
&rate, &width, &height))
return -1;
try
{
// create video object
Video_init<VideoFFmpeg>(self);
// set thread usage
getVideoFFmpeg(self)->initParams(width, height, rate);
// open video source
Video_open(getVideo(self), file, capt);
}
catch (Exception & exp)
{
exp.report();
return -1;
}
// initialization succeded
return 0;
}
PyObject * VideoFFmpeg_getPreseek (PyImage *self, void * closure)
{
return Py_BuildValue("h", getFFmpeg(self)->getPreseek());
}
// set range
int VideoFFmpeg_setPreseek (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PyInt_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be an integer");
return -1;
}
// set preseek
getFFmpeg(self)->setPreseek(PyInt_AsLong(value));
// success
return 0;
}
// get deinterlace
PyObject * VideoFFmpeg_getDeinterlace (PyImage * self, void * closure)
{
if (getFFmpeg(self)->getDeinterlace())
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
// set flip
int VideoFFmpeg_setDeinterlace (PyImage * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
{
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
// set deinterlace
getFFmpeg(self)->setDeinterlace(value == Py_True);
// success
return 0;
}
// methods structure
static PyMethodDef videoMethods[] =
{ // methods from VideoBase class
{"play", (PyCFunction)Video_play, METH_NOARGS, "Play video"},
{"stop", (PyCFunction)Video_stop, METH_NOARGS, "Stop (pause) video"},
{"refresh", (PyCFunction)Video_refresh, METH_NOARGS, "Refresh video - get its status"},
{NULL}
};
// attributes structure
static PyGetSetDef videoGetSets[] =
{ // methods from VideoBase class
{"status", (getter)Video_getStatus, NULL, "video status", NULL},
{"range", (getter)Video_getRange, (setter)Video_setRange, "replay range", NULL},
{"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, "repeat count, -1 for infinite repeat", NULL},
{"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, "frame rate", NULL},
// attributes from ImageBase class
{"image", (getter)Image_getImage, NULL, "image data", NULL},
{"size", (getter)Image_getSize, NULL, "image size", NULL},
{"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL},
{"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
{"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
{"preseek", (getter)VideoFFmpeg_getPreseek, (setter)VideoFFmpeg_setPreseek, "nb of frames of preseek", NULL},
{"deinterlace", (getter)VideoFFmpeg_getDeinterlace, (setter)VideoFFmpeg_setDeinterlace, "deinterlace image", NULL},
{NULL}
};
// python type declaration
PyTypeObject VideoFFmpegType =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"VideoTexture.VideoFFmpeg", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Image_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"FFmpeg video source", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
videoMethods, /* tp_methods */
0, /* tp_members */
videoGetSets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)VideoFFmpeg_init, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};
#endif //WITH_FFMPEG

@ -0,0 +1,163 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexture library
Copyright (c) 2007 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#if !defined VIDEOFFMPEG_H
#define VIDEOFFMPEG_H
#ifdef WITH_FFMPEG
extern "C" {
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
#include <ffmpeg/rational.h>
#include <ffmpeg/swscale.h>
}
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
#else
#define FFMPEG_CODEC_IS_POINTER 1
#endif
#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
#define FFMPEG_PB_IS_POINTER 1
#endif
#ifdef FFMPEG_CODEC_IS_POINTER
static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return stream->codec;
}
#else
static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return &stream->codec;
}
#endif
#include "VideoBase.h"
// type VideoFFmpeg declaration
class VideoFFmpeg : public VideoBase
{
public:
/// constructor
VideoFFmpeg (HRESULT * hRslt);
/// destructor
virtual ~VideoFFmpeg ();
/// set initial parameters
void initParams (short width, short height, float rate);
/// open video file
virtual void openFile (char * file);
/// open video capture device
virtual void openCam (char * driver, short camIdx);
/// release video source
virtual bool release (void);
/// play video
virtual bool play (void);
/// stop/pause video
virtual bool stop (void);
/// set play range
virtual void setRange (double start, double stop);
/// set frame rate
virtual void setFrameRate (float rate);
// some specific getters and setters
int getPreseek(void) { return m_preseek; }
void setPreseek(int preseek) { if (preseek >= 0) m_preseek = preseek; }
bool getDeinterlace(void) { return m_deinterlace; }
void setDeinterlace(bool deinterlace) { m_deinterlace = deinterlace; }
protected:
// format and codec information
AVCodec *m_codec;
AVFormatContext *m_formatCtx;
AVCodecContext *m_codecCtx;
// raw frame extracted from video file
AVFrame *m_frame;
// deinterlaced frame if codec requires it
AVFrame *m_frameDeinterlaced;
// decoded RGB24 frame if codec requires it
AVFrame *m_frameBGR;
// conversion from raw to RGB is done with sws_scale
struct SwsContext *m_imgConvertCtx;
// should the codec be deinterlaced?
bool m_deinterlace;
// number of frame of preseek
int m_preseek;
// order number of stream holding the video in format context
int m_videoStream;
// the actual frame rate
double m_baseFrameRate;
/// last displayed frame
long m_lastFrame;
/// current file pointer position in file expressed in frame number
long m_curPosition;
/// time of video play start
double m_startTime;
/// width of capture in pixel
short m_captWidth;
/// height of capture in pixel
short m_captHeight;
/// frame rate of capture in frames per seconds
float m_captRate;
/// image calculation
virtual void calcImage (unsigned int texId);
/// load frame from video
void loadFrame (void);
/// set actual position
void setPositions (void);
/// get actual framerate
double actFrameRate (void) { return m_frameRate * m_baseFrameRate; }
/// common function to video file and capture
int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams);
/// check if a frame is available and load it in pFrame, return true if a frame could be retrieved
bool grabFrame(long frame);
/// return the frame in RGB24 format, the image data is found in AVFrame.data[0]
AVFrame* getFrame(void) { return m_frameBGR; }
};
inline VideoFFmpeg * getFFmpeg (PyImage * self)
{
return static_cast<VideoFFmpeg*>(self->m_image);
}
#endif //WITH_FFMPEG
#endif

@ -0,0 +1,207 @@
/* $Id$
-----------------------------------------------------------------------------
This source file is part of VideoTexure library
Copyright (c) 2006 The Zdeno Ash Miklas
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/
#define PY_ARRAY_UNIQUE_SYMBOL numpyPtr
#include <Python.h>
#include <RAS_GLExtensionManager.h>
#include <RAS_IPolygonMaterial.h>
#include <numpy/arrayobject.h>
//Old API
//#include "TexPlayer.h"
//#include "TexImage.h"
//#include "TexFrameBuff.h"
//#include "TexPlayerGL.h"
#include "ImageBase.h"
#include "FilterBase.h"
#include "Texture.h"
#include "Exception.h"
// get material id
static PyObject * getMaterialID (PyObject *self, PyObject *args)
{
// parameters - game object with video texture
PyObject * obj = NULL;
// material name
char * matName;
// get parameters
if (!PyArg_ParseTuple(args, "Os", &obj, &matName))
return NULL;
// get material id
short matID = getMaterialID(obj, matName);
// if material was not found, report errot
if (matID < 0)
{
PyErr_SetString(PyExc_RuntimeError, "object doesn't have material with given name");
return NULL;
}
// return material ID
return Py_BuildValue("h", matID);
}
// get last error description
static PyObject * getLastError (PyObject *self, PyObject *args)
{
return Py_BuildValue("s", Exception::m_lastError.c_str());
}
// set log file
static PyObject * setLogFile (PyObject *self, PyObject *args)
{
// get parameters
if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile))
return Py_BuildValue("i", -1);
// log file was loaded
return Py_BuildValue("i", 0);
}
// function to initialize numpy structures
static bool initNumpy (void)
{
// init module and report failure
import_array1(false);
// report success
return true;
}
// image to numpy array
static PyObject * imageToArray (PyObject * self, PyObject *args)
{
// parameter is Image object
PyObject * pyImg;
if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
{
// if object is incorect, report error
PyErr_SetString(PyExc_TypeError, "The value must be a image source object");
return NULL;
}
// get image structure
PyImage * img = reinterpret_cast<PyImage*>(pyImg);
// check initialization of numpy interface, and initialize it if needed
if (numpyPtr == NULL && !initNumpy()) Py_RETURN_NONE;
// create array object
npy_intp dim[1];
dim[0] = img->m_image->getBuffSize() / sizeof(unsigned int);
unsigned int * imgBuff = img->m_image->getImage();
// if image is available, convert it to array
if (imgBuff != NULL)
return PyArray_SimpleNewFromData(1, dim, NPY_UBYTE, imgBuff);
// otherwise return None
Py_RETURN_NONE;
}
// metody modulu
static PyMethodDef moduleMethods[] =
{
{"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"},
{"getLastError", getLastError, METH_NOARGS, "Gets last error description"},
{"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"},
{"imageToArray", imageToArray, METH_VARARGS, "get array from image source"},
{NULL} /* Sentinel */
};
#if WITH_FFMPEG
extern PyTypeObject VideoFFmpegType;
#endif
extern PyTypeObject FilterBlueScreenType;
extern PyTypeObject FilterGrayType;
extern PyTypeObject FilterColorType;
extern PyTypeObject FilterLevelType;
extern PyTypeObject FilterNormalType;
extern PyTypeObject FilterRGB24Type;
extern PyTypeObject FilterBGR24Type;
extern PyTypeObject ImageBuffType;
extern PyTypeObject ImageMixType;
extern PyTypeObject ImageRenderType;
extern PyTypeObject ImageViewportType;
extern PyTypeObject ImageViewportType;
static void registerAllTypes(void)
{
#if WITH_FFMPEG
pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg");
#endif
pyImageTypes.add(&ImageBuffType, "ImageBuff");
pyImageTypes.add(&ImageMixType, "ImageMix");
//pyImageTypes.add(&ImageRenderType, "ImageRender");
pyImageTypes.add(&ImageViewportType, "ImageViewport");
pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen");
pyFilterTypes.add(&FilterGrayType, "FilterGray");
pyFilterTypes.add(&FilterColorType, "FilterColor");
pyFilterTypes.add(&FilterLevelType, "FilterLevel");
pyFilterTypes.add(&FilterNormalType, "FilterNormal");
pyFilterTypes.add(&FilterRGB24Type, "FilterRGB24");
pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
}
PyObject* initVideoTexture(void)
{
// initialize GL extensions
//bgl::InitExtensions(0);
// prepare classes
registerAllTypes();
registerAllExceptions();
if (!pyImageTypes.ready())
return NULL;
if (!pyFilterTypes.ready())
return NULL;
if (PyType_Ready(&TextureType) < 0)
return NULL;
PyObject * m = Py_InitModule4("VideoTexture", moduleMethods,
"Module that allows to play video files on textures in GameBlender.",
(PyObject*)NULL,PYTHON_API_VERSION);
if (m == NULL)
return NULL;
// prepare numpy array
numpyPtr = NULL;
// initialize classes
pyImageTypes.reg(m);
pyFilterTypes.reg(m);
Py_INCREF(&TextureType);
PyModule_AddObject(m, "Texture", (PyObject*)&TextureType);
// init last error description
Exception::m_lastError[0] = '\0';
return m;
}
// registration to Image types, put here because of silly linker bug