svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17236:HEAD
authorCampbell Barton <ideasman42@gmail.com>
Sat, 1 Nov 2008 22:04:41 +0000 (22:04 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 1 Nov 2008 22:04:41 +0000 (22:04 +0000)
67 files changed:
config/darwin-config.py
config/openbsd3-config.py
config/sunos5-config.py
config/win32-mingw-config.py
config/win32-vc-config.py
doc/blender-scons.txt
intern/ghost/intern/GHOST_WindowWin32.cpp
projectfiles_vc7/blender/blender.sln
projectfiles_vc7/blender/blender.vcproj
projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
projectfiles_vc7/blender/src/BL_src.vcproj
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/imbuf/intern/util.c
source/blender/python/api2_2x/matrix.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/sss.c
source/blender/src/interface.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/CMakeLists.txt
source/gameengine/Ketsji/BL_Texture.h
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h
source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
source/gameengine/Rasterizer/RAS_2DFilterManager.h
source/gameengine/SConscript
source/gameengine/VideoTexture/BlendType.h [new file with mode: 0644]
source/gameengine/VideoTexture/CMakeLists.txt [new file with mode: 0644]
source/gameengine/VideoTexture/Common.h [new file with mode: 0644]
source/gameengine/VideoTexture/Exception.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/Exception.h [new file with mode: 0644]
source/gameengine/VideoTexture/FilterBase.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/FilterBase.h [new file with mode: 0644]
source/gameengine/VideoTexture/FilterBlueScreen.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/FilterBlueScreen.h [new file with mode: 0644]
source/gameengine/VideoTexture/FilterColor.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/FilterColor.h [new file with mode: 0644]
source/gameengine/VideoTexture/FilterNormal.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/FilterNormal.h [new file with mode: 0644]
source/gameengine/VideoTexture/FilterSource.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/FilterSource.h [new file with mode: 0644]
source/gameengine/VideoTexture/ImageBase.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/ImageBase.h [new file with mode: 0644]
source/gameengine/VideoTexture/ImageBuff.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/ImageBuff.h [new file with mode: 0644]
source/gameengine/VideoTexture/ImageMix.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/ImageMix.h [new file with mode: 0644]
source/gameengine/VideoTexture/ImageRender.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/ImageRender.h [new file with mode: 0644]
source/gameengine/VideoTexture/ImageViewport.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/ImageViewport.h [new file with mode: 0644]
source/gameengine/VideoTexture/Makefile [new file with mode: 0644]
source/gameengine/VideoTexture/PyTypeList.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/PyTypeList.h [new file with mode: 0644]
source/gameengine/VideoTexture/SConscript [new file with mode: 0644]
source/gameengine/VideoTexture/Texture.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/Texture.h [new file with mode: 0644]
source/gameengine/VideoTexture/VideoBase.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/VideoBase.h [new file with mode: 0644]
source/gameengine/VideoTexture/VideoFFmpeg.cpp [new file with mode: 0644]
source/gameengine/VideoTexture/VideoFFmpeg.h [new file with mode: 0644]
source/gameengine/VideoTexture/blendVideoTex.cpp [new file with mode: 0644]

index ccc3eb5a0d0ccc9032a89d761774df3fa8c19a23..547d655b531ad93e52c2d6cb3e6fb000cc8814e1 100644 (file)
@@ -251,9 +251,9 @@ else:
 ##
 CC = 'gcc'
 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
 
index b2112c84b9895698d2c745e4c995faacf9fd0d68..0a4f75e3bccc4fc4d777cc7309e3a3fc9739866d 100644 (file)
@@ -145,9 +145,9 @@ REL_CCFLAGS = ['-O2']
 ##
 CC = 'gcc'
 CXX = 'g++'
-C_WARN = '-Wall -Wdeclaration-after-statement'
+C_WARN = ['-Wdeclaration-after-statement']
 
-CC_WARN = '-Wall'
+CC_WARN = ['-Wall']
 
 ##FIX_STUBS_WARNINGS = -Wno-unused
 
index bb6c5d89e4633ffb755ee602611450481e4725ff..2343ce69060ceaaf5228d5b3679f8d3446952d43 100644 (file)
@@ -159,9 +159,9 @@ REL_CCFLAGS = ['-O2']
 ##ARFLAGS = ruv
 ##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
 
index d7ecad33bca48043799782ba5264eb638a894f08..bdeca1ddc9182ab9e43d0b23f00c8d817d65b5df 100644 (file)
@@ -153,7 +153,7 @@ CXXFLAGS = ['-pipe', '-mwindows', '-funsigned-char', '-fno-strict-aliasing' ]
 REL_CFLAGS = [ '-O2' ]
 REL_CCFLAGS = [ '-O2' ]
 
-C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
+C_WARN = [ '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
 
 CC_WARN = [ '-Wall' ]
 
index 6cc09748a1088542bf8168ca95701e66454db707..a5aa76c2868a9b8016c5cb22b6e5f4ec3d689314 100644 (file)
@@ -161,6 +161,7 @@ CC = 'cl.exe'
 CXX = 'cl.exe'
 
 CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
+CXXFLAGS = ['/EHsc']
 
 BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
 
index 8578d3f2fd42a987848bc66d6339f820f676e424..f7ea7767441abbeec575cc82bb009255618f5f1d 100644 (file)
@@ -1,9 +1,5 @@
 $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
     ============================
 
@@ -31,7 +27,7 @@ $Id$
 
     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
-    installation, version v0.97 (http://www.scons.org).
+    installation, version v1.1.0 (http://www.scons.org).
 
     Check from the page
     http://www.blender.org/development/building-blender/getting-dependencies/
index 6a06f4d715a65863b38c6556eede99c16ed874fa..2094ae87c677eae1c33960c81b3bec66176d173b 100644 (file)
@@ -854,7 +854,7 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
 static int EnumPixelFormats(HDC hdc) {
        int iPixelFormat;
        int i, n, w, weight = 0;
-       PIXELFORMATDESCRIPTOR pfd, pfd_fallback;
+       PIXELFORMATDESCRIPTOR pfd;
        
        /* we need a device context to do anything */
        if(!hdc) return 0;
index eb2355319847756f5b87981a623ad06d73a9a2f3..c1628614642c6b88e4272b9999ca11f38d137350 100644 (file)
@@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj",
                {138DD16C-CC78-4F6C-A898-C8DA68D89067} = {138DD16C-CC78-4F6C-A898-C8DA68D89067}
                {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292}
                {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}
                {6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC}
                {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
        EndProjectSection
 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
        GlobalSection(SolutionConfiguration) = preSolution
                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}.Release.ActiveCfg = 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
        GlobalSection(ExtensibilityGlobals) = postSolution
        EndGlobalSection
index 26cb3fb79e189b70cd59c204a9cc2ed47c36f1db..ef6900b7b75cd563eab4f8eb5eb4be74acb6d4f5 100644 (file)
@@ -124,7 +124,7 @@ ECHO Done
                                Name="VCLinkerTool"
                                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"
                                OutputFile="..\..\bin\debug\blender.exe"
                                LinkIncremental="2"
index 0dfbcaa55779e145e41aa2c9f6cba7914c07c4da..aadef58f84a510e3e007e3700fd42508464489cd 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\blenlib\intern\freetypefont.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenlib\intern\graph.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenlib\intern\gsqueue.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenlib\BLI_ghash.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenlib\BLI_graph.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenlib\BLI_heap.h">
                        </File>
index 80694690107e5370681bb9fef7546dca28375386..d6e436635cbb573dca2ac8a2c18f3f64fd4b4d8c 100644 (file)
                <Filter
                        Name="Source Files"
                        Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+                       <File
+                               RelativePath="..\..\..\source\blender\src\autoarmature.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\B.blend.c">
                        </File>
index ce4458b43070bf3596549a7d6cd000c4a2717fc7..cee032f364eb74c78a70b84f40ffe057c306b2f0 100644 (file)
@@ -1245,9 +1245,11 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
                        }
                }
 
-               avgSharpness /= sharpCount;
-               if (avgSharpness>1.0) {
-                       avgSharpness = 1.0;
+               if(sharpCount) {
+                       avgSharpness /= sharpCount;
+                       if (avgSharpness>1.0) {
+                               avgSharpness = 1.0;
+                       }
                }
 
                if (seam && seamEdges < 2)
@@ -1543,9 +1545,11 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
                                }
                        }
 
-                       avgSharpness /= sharpCount;
-                       if (avgSharpness>1.0) {
-                               avgSharpness = 1.0;
+                       if(sharpCount) {
+                               avgSharpness /= sharpCount;
+                               if (avgSharpness>1.0) {
+                                       avgSharpness = 1.0;
+                               }
                        }
 
                        if (seam && seamEdges < 2)
index 4f6730db1f1efe7f9872dc098dca2e51f12dc3f8..cd58d9e4e960b5d87ce75d9dd578c3221a71f4b8 100644 (file)
@@ -64,6 +64,7 @@
 #ifdef WITH_FFMPEG
 #include <ffmpeg/avcodec.h>
 #include <ffmpeg/avformat.h>
+//#include <ffmpeg/avdevice.h>
 
 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
 #define FFMPEG_OLD_FRAME_RATE 1
@@ -236,6 +237,7 @@ void do_init_ffmpeg()
        if (!ffmpeg_init) {
                ffmpeg_init = 1;
                av_register_all();
+               //avdevice_register_all();
        }
 }
 
index 79ca5e09b250fd2402ca5bbefa10edb6b3fb4faf..7802de822cb3fce5ee613dab62811b46a890c6e8 100644 (file)
@@ -246,8 +246,8 @@ PyObject *Matrix_Invert(MatrixObject * self)
                /*calculate the classical adjoint*/
                if(self->rowSize == 2) {
                        mat[0] = self->matrix[1][1];
-                       mat[1] = -self->matrix[1][0];
-                       mat[2] = -self->matrix[0][1];
+                       mat[1] = -self->matrix[0][1];
+                       mat[2] = -self->matrix[1][0];
                        mat[3] = self->matrix[0][0];
                } else if(self->rowSize == 3) {
                        Mat3Adj((float (*)[3]) mat,(float (*)[3]) *self->matrix);
index d281ac9e5c85145fb68e325fdddcb582aaef9781..13fa9b17b715c8ac2f23699b10fa04fb7a265dff 100644 (file)
@@ -439,12 +439,19 @@ static void render_envmap(Render *re, EnvMap *env)
 
                if(re->test_break()==0) {
                        RenderLayer *rl= envre->result->layers.first;
+                       int y;
+                       char *alpha;
                        
                        ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect, 0);
                        ibuf->rect_float= rl->rectf;
                        IMB_rect_from_float(ibuf);
                        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;
                }
                
index 9fb48a08503ec88c87213c239f0fd968ab453649..9bde66757983302f849294428e215a60ad719458 100644 (file)
@@ -451,13 +451,13 @@ static void compute_radiance(ScatterTree *tree, float *co, float *rad)
        VECCOPY(rdsum, result.rdsum);
        VECADD(backrdsum, result.rdsum, result.backrdsum);
 
-       if(rdsum[0] > 0.0f) 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[2] > 0.0f) rad[2]= tree->ss[2]->color*rad[2]/rdsum[2];
+       if(rdsum[0] > 1e-16f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0];
+       if(rdsum[1] > 1e-16f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1];
+       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[1] > 0.0f) 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[0] > 1e-16f) backrad[0]= tree->ss[0]->color*backrad[0]/backrdsum[0];
+       if(backrdsum[1] > 1e-16f) backrad[1]= tree->ss[1]->color*backrad[1]/backrdsum[1];
+       if(backrdsum[2] > 1e-16f) backrad[2]= tree->ss[2]->color*backrad[2]/backrdsum[2];
 
        rad[0]= MAX2(rad[0], backrad[0]);
        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;
                node->rad[0] *= inv;
                node->rad[1] *= inv;
                node->rad[2] *= inv;
        }
-       if(node->backarea > 0) {
+       if(node->backarea > 1e-16f) {
                inv= 1.0/node->backarea;
                node->backrad[0] *= inv;
                node->backrad[1] *= inv;
                node->backrad[2] *= inv;
        }
 
-       if(totrad > 0.0f) {
+       if(totrad > 1e-16f) {
                inv= 1.0/totrad;
                node->co[0] *= inv;
                node->co[1] *= inv;
@@ -578,20 +578,20 @@ static void sum_branch_radiance(ScatterTree *tree, ScatterNode *node)
                node->backarea += subnode->backarea;
        }
 
-       if(node->area > 0) {
+       if(node->area > 1e-16f) {
                inv= 1.0/node->area;
                node->rad[0] *= inv;
                node->rad[1] *= inv;
                node->rad[2] *= inv;
        }
-       if(node->backarea > 0) {
+       if(node->backarea > 1e-16f) {
                inv= 1.0/node->backarea;
                node->backrad[0] *= inv;
                node->backrad[1] *= inv;
                node->backrad[2] *= inv;
        }
 
-       if(totrad > 0.0f) {
+       if(totrad > 1e-16f) {
                inv= 1.0/totrad;
                node->co[0] *= inv;
                node->co[1] *= inv;
index 28baf87baa1eb60e98fdef79574a423a08cf9a4e..9decbd9a1ce8ab67b7b8f226e93db68eb2b37d69 100644 (file)
@@ -1808,7 +1808,7 @@ static int ui_do_but_TEX(uiBut *but)
                         ((G.qual & LR_COMMANDKEY) || (G.qual & LR_CTRLKEY)) && 
                         ((dev==XKEY) || (dev==CKEY) || (dev==VKEY)) ) {
                                 
-                       char buf[UI_MAX_DRAW_STR]={0};
+                       char buf[UI_MAX_DRAW_STR+1]={0};
                        
                        /* paste */
                        if (dev==VKEY) {
index 9fbdc3fa1c9c454b662b15282f6146c99bc3c2fe..2d91bbcd7c1264247915a25ba2b36067fae0c85a 100644 (file)
@@ -364,6 +364,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                        initGameKeys();
                        initPythonConstraintBinding();
                        initMathutils();
+                       initVideoTexture();
 
                        if (sceneconverter)
                        {
index 93de588ba002e8a48934f4044d3d25a96454110a..3ea788791e2ca16b2c17eec462c44443ff668719 100644 (file)
@@ -40,6 +40,7 @@ SUBDIRS(
   SceneGraph
   Physics/Bullet
   Physics/Sumo
+  VideoTexture
 )
 
 IF(WITH_PLAYER)
index 0d0c7a277f291775ae09f0c06b3af480d2646c00..830ffceb0f78c151d478d0b89f6d5bceeba4c911 100644 (file)
@@ -59,6 +59,14 @@ public:
        void SetMapping(int mode);
        void DisableUnit();
        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__
index 4ddf5a924df21f3260cefbbda92487df57bd2e4c..b858fa3754cc92866d0738b814d110b6de0680c7 100644 (file)
@@ -67,6 +67,9 @@ public:
 
        MTFace* GetMTFace(void) const;
        unsigned int* GetMCol(void) const;
+       BL_Texture * getTex (unsigned int idx) { 
+               return (idx < MAXTEX) ? mTextures + idx : NULL; 
+       }
 
        // for ipos
        void UpdateIPO(
index 3830d42213866a941b8da300fa035c1367a742f4..53b3e348a36e3b6fbfddfe3e303e033e6457c467 100644 (file)
@@ -793,7 +793,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
 {
        class KX_Scene* scene;
        
-       scene = PHY_GetActiveScene();
+       scene = KX_GetActiveScene();
        MT_assert(scene);
        scene->SetCameraOnTop(this);
        Py_Return;
index 739c122a5ef52c1f8f1cc2cb553a5168d4c807eb..a168beb9a707a94119b9033430d4bfe23dcbf68d 100644 (file)
@@ -1027,7 +1027,7 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
 
 PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value)
 {
-       KX_Scene *scene = PHY_GetActiveScene();
+       KX_Scene *scene = KX_GetActiveScene();
        char* meshname;
        void* mesh_pt;
 
@@ -1050,7 +1050,7 @@ PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value)
 PyObject* KX_GameObject::PyEndObject(PyObject* self)
 {
 
-       KX_Scene *scene = PHY_GetActiveScene();
+       KX_Scene *scene = KX_GetActiveScene();
        scene->DelayedRemoveObject(this);
        
        Py_RETURN_NONE;
@@ -1447,7 +1447,7 @@ PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
        // The object we want to set as parent
        CValue *m_ob = (CValue*)value;
        KX_GameObject *obj = ((KX_GameObject*)m_ob);
-       KX_Scene *scene = PHY_GetActiveScene();
+       KX_Scene *scene = KX_GetActiveScene();
        
        this->SetParent(scene, obj);
                
@@ -1456,7 +1456,7 @@ PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
 
 PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
 {
-       KX_Scene *scene = PHY_GetActiveScene();
+       KX_Scene *scene = KX_GetActiveScene();
        this->RemoveParent(scene);
        Py_RETURN_NONE;
 }
index b1ab8e3e7def86b45319bf697404dc7394b2ba5e..8bcda4479e1dab9836202fc310f80a3e6e131a34 100644 (file)
@@ -470,7 +470,7 @@ else
                                m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
                                // set Python hooks for each scene
                                PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
-                               PHY_SetActiveScene(scene);
+                               KX_SetActiveScene(scene);
        
                                scene->GetPhysicsEnvironment()->endFrame();
                                
@@ -568,7 +568,7 @@ else
                                
                                // set Python hooks for each scene
                                PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
-                               PHY_SetActiveScene(scene);
+                               KX_SetActiveScene(scene);
                                
                                m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
                                scene->UpdateParents(m_clockTime);
@@ -1540,6 +1540,11 @@ double KX_KetsjiEngine::GetAnimFrameRate()
        return m_anim_framerate;
 }
 
+double KX_KetsjiEngine::GetClockTime(void) const
+{
+       return m_clockTime;
+}
+
 void KX_KetsjiEngine::SetAnimFrameRate(double framerate)
 {
        m_anim_framerate = framerate;
index 1aa067a99621dd536bc19aa25e39cfa9e01e5efd..4184202c51860265055a9840cf29224624a1e8ee 100644 (file)
@@ -253,6 +253,11 @@ public:
         */ 
        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
         * was running and not suspended) and the "curtime"
index eb56e8de6790b06187cd4e4c441e17320b16ab8a..89549ca6b5798aee1116d49d6cb2380ddce0fc0b 100644 (file)
@@ -119,7 +119,7 @@ bool KX_ParentActuator::Update()
                return false; // do nothing on negative events
 
        KX_GameObject *obj = (KX_GameObject*) GetParent();
-       KX_Scene *scene = PHY_GetActiveScene();
+       KX_Scene *scene = KX_GetActiveScene();
        switch (m_mode) {
                case KX_PARENT_SET:
                        if (m_ob)
index a30d9f4022ded92f64a36615ec3c737c48405cc6..0032d83c2ff7c773737e1b649004ad3c46087845 100644 (file)
@@ -1461,16 +1461,21 @@ PyObject* initMathutils()
        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;
 }
 
-class KX_Scene* PHY_GetActiveScene()
+class KX_Scene* KX_GetActiveScene()
 {
        return gp_KetsjiScene;
 }
 
+class KX_KetsjiEngine* KX_GetActiveEngine()
+{
+       return gp_KetsjiEngine;
+}
+
 // utility function for loading and saving the globalDict
 int saveGamePythonConfig( char **marshal_buffer)
 {
index 36e3db6ec354cdf2d6b7fb18fbed2c738615a3c8..57ee0be9400310c001acfd80a69e405311681260 100644 (file)
@@ -45,6 +45,7 @@ PyObject*     initGameKeys();
 PyObject*      initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
 PyObject*      initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level);
 PyObject*      initMathutils();
+PyObject*      initVideoTexture(void); 
 void           exitGamePlayerPythonScripting();
 PyObject*      initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
 void           exitGamePythonScripting();
@@ -54,8 +55,12 @@ void         pathGamePythonConfig( char *path );
 int                    saveGamePythonConfig( char **marshal_buffer);
 int                    loadGamePythonConfig(char *marshal_buffer, int marshal_length);
 
-void PHY_SetActiveScene(class KX_Scene* scene);
-class KX_Scene* PHY_GetActiveScene();
+class KX_KetsjiEngine;
+class KX_Scene;
+
+void KX_SetActiveScene(class KX_Scene* scene);
+class KX_Scene* KX_GetActiveScene();
+class KX_KetsjiEngine* KX_GetActiveEngine();
 #include "MT_Vector3.h"
 
 void           KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color);
index 6e5553d478106ac38c2dc86b35cce6f3b6e3518b..d2cfa7d07f9612e3c6dba89663f0409216d4c492 100644 (file)
@@ -78,6 +78,7 @@ numberoffilters(0)
                m_gameObjects[passindex] = NULL;
        }
        texname[0] = texname[1] = texname[2] = -1;
+       errorprinted= false;
 }
 
 RAS_2DFilterManager::~RAS_2DFilterManager()
@@ -85,76 +86,107 @@ RAS_2DFilterManager::~RAS_2DFilterManager()
        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)
 {
-               GLuint program = 0;     
-               GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
-        GLint success;
+       GLuint program = 0;     
+       GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
+       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();
-               glAttachObjectARB(program, fShader);
 
-               glLinkProgramARB(program);
-               glGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
-               if (!success)
-               {
-                       /*Program Link Error*/
-                       std::cout << "2dFilters - Shader program link error" << std::endl;
-                       return 0;
-               }
-               
-               glValidateProgramARB(program);
-               glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success);
-        if (!success)
-               {
-                       /*Program Validation Error*/
-                       std::cout << "2dFilters - Shader program validation error" << std::endl;
-                       return 0;
-               }
+       glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success);
+       if(!success)
+       {
+               /*Shader Comile Error*/
+               PrintShaderErrors(fShader, "compile", shadersource);
+               return 0;
+       }
+               
+       program = glCreateProgramObjectARB();
+       glAttachObjectARB(program, fShader);
+
+       glLinkProgramARB(program);
+       glGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
+       if (!success)
+       {
+               /*Program Link Error*/
+               PrintShaderErrors(fShader, "link", shadersource);
+               return 0;
+       }
+       
+       glValidateProgramARB(program);
+       glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success);
+       if (!success)
+       {
+               /*Program Validation Error*/
+               PrintShaderErrors(fShader, "validate", shadersource);
+               return 0;
+       }
 
-               return program;
+       return program;
 }
 
 unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
 {
-               switch(filtermode)
-               {
-                       case RAS_2DFILTER_BLUR:
-                               return CreateShaderProgram(BlurFragmentShader);
-                       case RAS_2DFILTER_SHARPEN:
-                               return CreateShaderProgram(SharpenFragmentShader);
-                       case RAS_2DFILTER_DILATION:
-                               return CreateShaderProgram(DilationFragmentShader);
-                       case RAS_2DFILTER_EROSION:
-                               return CreateShaderProgram(ErosionFragmentShader);
-                       case RAS_2DFILTER_LAPLACIAN:
-                               return CreateShaderProgram(LaplacionFragmentShader);
-                       case RAS_2DFILTER_SOBEL:
-                               return CreateShaderProgram(SobelFragmentShader);
-                       case RAS_2DFILTER_PREWITT:
-                               return CreateShaderProgram(PrewittFragmentShader);
-                       case RAS_2DFILTER_GRAYSCALE:
-                               return CreateShaderProgram(GrayScaleFragmentShader);
-                       case RAS_2DFILTER_SEPIA:
-                               return CreateShaderProgram(SepiaFragmentShader);
-                       case RAS_2DFILTER_INVERT:
-                               return CreateShaderProgram(InvertFragmentShader);
-               }
-               return 0;
+       switch(filtermode)
+       {
+               case RAS_2DFILTER_BLUR:
+                       return CreateShaderProgram(BlurFragmentShader);
+               case RAS_2DFILTER_SHARPEN:
+                       return CreateShaderProgram(SharpenFragmentShader);
+               case RAS_2DFILTER_DILATION:
+                       return CreateShaderProgram(DilationFragmentShader);
+               case RAS_2DFILTER_EROSION:
+                       return CreateShaderProgram(ErosionFragmentShader);
+               case RAS_2DFILTER_LAPLACIAN:
+                       return CreateShaderProgram(LaplacionFragmentShader);
+               case RAS_2DFILTER_SOBEL:
+                       return CreateShaderProgram(SobelFragmentShader);
+               case RAS_2DFILTER_PREWITT:
+                       return CreateShaderProgram(PrewittFragmentShader);
+               case RAS_2DFILTER_GRAYSCALE:
+                       return CreateShaderProgram(GrayScaleFragmentShader);
+               case RAS_2DFILTER_SEPIA:
+                       return CreateShaderProgram(SepiaFragmentShader);
+               case RAS_2DFILTER_INVERT:
+                       return CreateShaderProgram(InvertFragmentShader);
+       }
+       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;
        if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
@@ -249,11 +281,11 @@ void RAS_2DFilterManager::EndShaderProgram()
 
 void RAS_2DFilterManager::FreeTextures()
 {
-       if(texname[0]!=-1)
+       if(texname[0]!=(unsigned int)-1)
                glDeleteTextures(1, (GLuint*)&texname[0]);
-       if(texname[1]!=-1)
+       if(texname[1]!=(unsigned int)-1)
                glDeleteTextures(1, (GLuint*)&texname[1]);
-       if(texname[2]!=-1)
+       if(texname[2]!=(unsigned int)-1)
                glDeleteTextures(1, (GLuint*)&texname[2]);
 }
 
@@ -300,8 +332,8 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
        RAS_Rect canvas_rect = canvas->GetWindowArea();
        canvaswidth = canvas->GetWidth();
        canvasheight = canvas->GetHeight();
-       texturewidth = canvaswidth + canvas_rect.GetLeft();
-       textureheight = canvasheight + canvas_rect.GetBottom();
+       texturewidth = canvaswidth;
+       textureheight = canvasheight;
 
        GLint i,j;
        i = 0;
@@ -365,17 +397,17 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
        if(need_depth){
                glActiveTextureARB(GL_TEXTURE1);
                glBindTexture(GL_TEXTURE_2D, texname[1]);
-               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0);
+               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], texturewidth,textureheight, 0);
        }
        
        if(need_luminance){
                glActiveTextureARB(GL_TEXTURE2);
                glBindTexture(GL_TEXTURE_2D, texname[2]);
-               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0 , texturewidth,textureheight, 0);
+               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1] , texturewidth,textureheight, 0);
        }
 
        glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
-       glViewport(0,0, texturewidth, textureheight);
+       glViewport(viewport[0],viewport[1], texturewidth, textureheight);
 
        glDisable(GL_DEPTH_TEST);
        glMatrixMode(GL_TEXTURE);
@@ -393,15 +425,20 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 
                        glActiveTextureARB(GL_TEXTURE0);
                        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);
 
+                       float canvascoordx, canvascoordy;
+
+                       canvascoordx = (GLfloat) texturewidth / canvaswidth;
+                       canvascoordy = (GLfloat) textureheight / canvasheight;
+
                        glBegin(GL_QUADS);
                                glColor4f(1.f, 1.f, 1.f, 1.f);
-                               glTexCoord2f(1.0, 1.0); glVertex2f(1,1);
-                               glTexCoord2f(0.0, 1.0); glVertex2f(-1,1);
-                               glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1);
-                               glTexCoord2f(1.0, 0.0); glVertex2f(1,-1);
+                               glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, canvascoordy); glVertex2f(1,1);
+                               glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, canvascoordy);          glVertex2f(-1,1);
+                               glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0);                   glVertex2f(-1,-1);
+                               glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, 0.0);          glVertex2f(1,-1);
                        glEnd();
                }
        }
index c16bd41dd0e25699b6ad5f189dc3b64288da5622..454643a5077099345ccb0cbc782052c397978e5c 100644 (file)
@@ -38,6 +38,7 @@ private:
        void            AnalyseShader(int passindex, vector<STR_String>& propNames);
        void                    StartShaderProgram(int passindex);
        void                    EndShaderProgram();
+       void                    PrintShaderErrors(unsigned int shader, const char *task, const char *code);
 
        void SetupTextures(bool depth, bool luminance);
        void FreeTextures();
@@ -58,6 +59,7 @@ private:
        short                   texflag[MAX_RENDER_PASS];
 
        bool                    isshadersupported;
+       bool                    errorprinted;
 
        unsigned int    m_filters[MAX_RENDER_PASS];
        short           m_enabled[MAX_RENDER_PASS];
index c2750d19706c0f1aef58969af372b69d6ea4a07e..e841f206eee47cb1bf5feb9e0eb3b93853aebed5 100644 (file)
@@ -15,7 +15,8 @@ SConscript(['BlenderRoutines/SConscript',
             'Rasterizer/RAS_OpenGLRasterizer/SConscript',
             'SceneGraph/SConscript',
             'Physics/Bullet/SConscript',
-            'Physics/Sumo/SConscript'
+            'Physics/Sumo/SConscript',
+            'VideoTexture/SConscript'
             ])
 
 if env['WITH_BF_PLAYER']:
diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h
new file mode 100644 (file)
index 0000000..ac3ed88
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1674602
--- /dev/null
@@ -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 )
diff --git a/source/gameengine/VideoTexture/Common.h b/source/gameengine/VideoTexture/Common.h
new file mode 100644 (file)
index 0000000..f771077
--- /dev/null
@@ -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>
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
new file mode 100644 (file)
index 0000000..c576ceb
--- /dev/null
@@ -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();
+}
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
new file mode 100644 (file)
index 0000000..5345e87
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp
new file mode 100644 (file)
index 0000000..078a096
--- /dev/null
@@ -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;
+}
diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h
new file mode 100644 (file)
index 0000000..1c9a2b4
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp
new file mode 100644 (file)
index 0000000..d911b1d
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h
new file mode 100644 (file)
index 0000000..2066080
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp
new file mode 100644 (file)
index 0000000..c45804c
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h
new file mode 100644 (file)
index 0000000..ae2e98f
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp
new file mode 100644 (file)
index 0000000..5eeb63b
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h
new file mode 100644 (file)
index 0000000..ec51ca3
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp
new file mode 100644 (file)
index 0000000..4b96a97
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h
new file mode 100644 (file)
index 0000000..7bed5c7
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
new file mode 100644 (file)
index 0000000..d2e980d
--- /dev/null
@@ -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;
+}
diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h
new file mode 100644 (file)
index 0000000..2b923a0
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp
new file mode 100644 (file)
index 0000000..f09514a
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/ImageBuff.h b/source/gameengine/VideoTexture/ImageBuff.h
new file mode 100644 (file)
index 0000000..fa2025f
--- /dev/null
@@ -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
+
diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp
new file mode 100644 (file)
index 0000000..7125000
--- /dev/null
@@ -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 */
+};
+
diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h
new file mode 100644 (file)
index 0000000..b4842bd
--- /dev/null
@@ -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
+
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
new file mode 100644 (file)
index 0000000..ce27a24
--- /dev/null
@@ -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 */
+};
+
+
diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h
new file mode 100644 (file)
index 0000000..66255f0
--- /dev/null
@@ -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
+
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
new file mode 100644 (file)
index 0000000..e1d3316
--- /dev/null
@@ -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 */
+};
diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h
new file mode 100644 (file)
index 0000000..9fd3aeb
--- /dev/null
@@ -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
+
diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile
new file mode 100644 (file)
index 0000000..bead176
--- /dev/null
@@ -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
+
+
diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp
new file mode 100644 (file)
index 0000000..b8c4005
--- /dev/null
@@ -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());
+               }
+}
diff --git a/source/gameengine/VideoTexture/PyTypeList.h b/source/gameengine/VideoTexture/PyTypeList.h
new file mode 100644 (file)
index 0000000..736fc9a
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
new file mode 100644 (file)
index 0000000..bf8d7c1
--- /dev/null
@@ -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 )
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
new file mode 100644 (file)
index 0000000..ea3f60b
--- /dev/null
@@ -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 */
+};
diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h
new file mode 100644 (file)
index 0000000..f19f8da
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp
new file mode 100644 (file)
index 0000000..038a04a
--- /dev/null
@@ -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;
+}
diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h
new file mode 100644 (file)
index 0000000..78e8ba6
--- /dev/null
@@ -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
+
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
new file mode 100644 (file)
index 0000000..272d269
--- /dev/null
@@ -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
+
+
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
new file mode 100644 (file)
index 0000000..4720bef
--- /dev/null
@@ -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
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
new file mode 100644 (file)
index 0000000..d08762b
--- /dev/null
@@ -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