merging trunk 17221:17300
authorMartin Poirier <theeth@yahoo.com>
Sun, 2 Nov 2008 19:44:18 +0000 (19:44 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 2 Nov 2008 19:44:18 +0000 (19:44 +0000)
95 files changed:
CMakeLists.txt
SConstruct
config/darwin-config.py
config/linux2-config.py
config/openbsd3-config.py
config/sunos5-config.py
config/win32-mingw-config.py
config/win32-vc-config.py
doc/blender-scons.txt
extern/verse/dist/SConstruct
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/Makefile
source/blender/blenkernel/BKE_fluidsim.h
source/blender/blenkernel/BKE_writeffmpeg.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/fluidsim.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/imbuf/intern/util.c
source/blender/makesdna/intern/SConscript
source/blender/python/api2_2x/Armature.c
source/blender/python/api2_2x/doc/SConscript
source/blender/python/api2_2x/matrix.c
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/sss.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/interface.c
source/creator/CMakeLists.txt
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/Makefile
source/gameengine/Physics/Sumo/SConscript
source/gameengine/PyDoc/SConscript
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]
source/nan_compile.mk
tools/Blender.py
tools/btools.py

index 41f2311af985a4daea4ee4f472ee071e04265ba9..e01a37d3b3edfa2d2b834cd4d020c77c977686cf 100644 (file)
@@ -88,14 +88,16 @@ INCLUDE(CMake/macros.cmake)
 #Platform specifics
 
 IF(UNIX)
-  INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake)
-  IF(OPENAL_FOUND)
-    SET(WITH_OPENAL ON)
-    SET(OPENAL_LIB ${OPENAL_LIBRARY})
-    SET(OPENAL_INC ${OPENAL_INCLUDE_DIR})
-  ELSE(OPENAL_FOUND)
-    SET(WITH_OPENAL OFF)
-  ENDIF(OPENAL_FOUND)
+  IF(WITH_OPENAL)
+    INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake)
+    IF(OPENAL_FOUND)
+      SET(WITH_OPENAL ON)
+      SET(OPENAL_LIB ${OPENAL_LIBRARY})
+      SET(OPENAL_INC ${OPENAL_INCLUDE_DIR})
+    ELSE(OPENAL_FOUND)
+      SET(WITH_OPENAL OFF)
+    ENDIF(OPENAL_FOUND)
+  ENDIF(WITH_OPENAL)
 
   FIND_LIBRARY(ALUT_LIBRARY
     NAMES alut
index 25cb6800b1d8afefac6829f5f5a0719ba1ff9977..91603ce772464a53a38eec23d3d67d20e0e99bb7 100644 (file)
@@ -42,6 +42,8 @@ import tools.Blender
 import tools.btools
 import tools.bcolors
 
+EnsureSConsVersion(1,0,0)
+
 BlenderEnvironment = tools.Blender.BlenderEnvironment
 btools = tools.btools
 B = tools.Blender
@@ -172,6 +174,9 @@ opts.Update(env)
 if not env['BF_FANCY']:
     B.bc.disable()
 
+SetOption('num_jobs', int(env['BF_NUMJOBS']))
+print "Build with %d parallel jobs" % (GetOption('num_jobs'))
+
 # disable elbeem (fluidsim) compilation?
 if env['BF_NO_ELBEEM'] == 1:
     env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
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 181f1d5364da8afd740e11e4c74a94ecbf50bd35..ca07bf10ab8836339b862cc1b6e00dda83e04c9c 100644 (file)
@@ -187,9 +187,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 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 ec401e3ad57a85c882f9ebb7c9890b82217a9e3c..a5aa76c2868a9b8016c5cb22b6e5f4ec3d689314 100644 (file)
@@ -161,14 +161,18 @@ CC = 'cl.exe'
 CXX = 'cl.exe'
 
 CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
+CXXFLAGS = ['/EHsc']
 
-BF_DEBUG_FLAGS = ['/Zi', '/FR${TARGET}.sbr']
+BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
 
 CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
 REL_CFLAGS = ['-O2', '-DNDEBUG']
 REL_CCFLAGS = ['-O2', '-DNDEBUG']
+REL_CXXFLAGS = ['-O2', '-DNDEBUG']
+
 C_WARN = []
 CC_WARN = []
+CXX_WARN = []
 
 LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid'
 
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 ecdc31780283ce830d7991e081c7c3ca49c911a9..a80a1ac79e9d2298a7a09c19c101bc524203c9eb 100644 (file)
@@ -56,7 +56,7 @@ else:
         platform_linkflags += ['/DEBUG','/PDB:verse.pdb']
 
 
-verse_env = env.Copy()
+verse_env = env.Clone()
 
 cmd_gen_files = (['v_cmd_gen.c',
                   'v_cmd_def_a.c',
@@ -71,7 +71,7 @@ cmd_gen_files = (['v_cmd_gen.c',
 
 cmd_gen_deps = (['v_gen_pack_init.c'])
 
-proto_env = env.Copy()
+proto_env = env.Clone()
 proto_env.Append(CPPDEFINES=['V_GENERATE_FUNC_MODE'])
 mkprot_tool = proto_env.Program(target = 'mkprot', source = cmd_gen_files)
 
@@ -130,10 +130,10 @@ server_source_files = (['vs_connection.c',
                         'vs_node_text.c'
                         ])
 
-verselib_env = verse_env.Copy()
+verselib_env = verse_env.Clone()
 verselib_env.Append(CPPDEFINES = defines)
 
-verseserver_env = verse_env.Copy()
+verseserver_env = verse_env.Clone()
 verseserver_env.Append(CPPDEFINES = defines)
 verseserver_env.Append (LIBPATH = ['.'])
 verseserver_env.Append (LIBS= ['verse'])
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 99155206987448c4edb90fd2cbbf0b047c8d61b8..558a844eca790df8d58096d6b7f3e663e45f54cd 100644 (file)
@@ -142,6 +142,7 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/OpenGLrasterizer/$(DEBUG_DIR)libOpenGLrasterizer.a
     COMLIB += $(OCGDIR)/gameengine/expression/$(DEBUG_DIR)libexpression.a
     COMLIB += $(OCGDIR)/gameengine/scenegraph/$(DEBUG_DIR)libscenegraph.a
+    COMLIB += $(OCGDIR)/gameengine/videotex/$(DEBUG_DIR)libvideotex.a
 #    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libfuzzics.a
 #    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libsolid.a
     COMLIB += $(NAN_MOTO)/lib/libmoto.a
index 33c706da82b6120593247d95ed60960c91ca5c73..4aac5eafa0036f16268e5258f457ff4e7c84de0d 100644 (file)
@@ -45,6 +45,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd);
 void fluidsim_free(FluidsimModifierData *fluidmd);
 
 DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams);
+void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename);
 DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 
 // get bounding box of mesh
index 02f7ba6f8602861b3805d404f075c773efe5eccd..50053446294096e786c519bfc058bbad2fc10d03 100644 (file)
@@ -59,6 +59,8 @@ extern void start_ffmpeg(struct RenderData *rd, int rectx, int recty);
 extern void end_ffmpeg(void);
 extern void append_ffmpeg(int frame, int *pixels, int rectx, int recty);
 
+void silence_log_ffmpeg(int quiet);
+
 #ifdef __cplusplus
 }
 #endif
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 b090ac2b538466081caa7dc58f167af137fbe179..1a671dfe771ec73d5ad2f473317280148ae1a421 100644 (file)
@@ -1100,9 +1100,12 @@ float *make_orco_curve(Object *ob)
                                                fp[1]= 2.0f*v/(dl->nr-1) - 1.0f;
                                                fp[2]= 0.0;
                                        } else {
+                                               float *vert;
                                                int realv= v % dl->nr;
-
-                                               VECCOPY(fp, &dl->verts[(dl->nr*u + realv)*3]);
+                                               int realu= u % dl->parts;
+                                               
+                                               vert= dl->verts + 3*(dl->nr*realu + realv);
+                                               VECCOPY(fp, vert);
 
                                                fp[0]= (fp[0]-cu->loc[0])/cu->size[0];
                                                fp[1]= (fp[1]-cu->loc[1])/cu->size[1];
index 6914de29d43a99f60cf5d50a9cd2b0c2e7bcd43d..59619b25f8bbd2c7716bae15595a281f4e4d2086 100644 (file)
@@ -495,8 +495,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
                                        else
                                                dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Curve Parent");
                                }
-                                       else
-                                               dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Curve Parent");
+                               else
+                                       dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Parent");
                }
                /* exception case: parent is duplivert */
                if(ob->type==OB_MBALL && (ob->parent->transflag & OB_DUPLIVERTS)) {
index 4580c6cbf8ba649ad9b32a553836022cc9cfb610..29c4e0f2fb543470cc2e9ab6d14b72edf532c8da 100644 (file)
@@ -139,6 +139,9 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
                fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); 
                */
                
+               // (ab)used to store velocities
+               fss->meshSurfNormals = NULL;
+               
                fss->lastgoodframe = -1;
                
                fss->flag = 0;
@@ -153,6 +156,11 @@ void fluidsim_free(FluidsimModifierData *fluidmd)
 #ifndef DISABLE_ELBEEM
        if(fluidmd)
        {
+               if(fluidmd->fss->meshSurfNormals)
+               {
+                       MEM_freeN(fluidmd->fss->meshSurfNormals);
+                       fluidmd->fss->meshSurfNormals = NULL;
+               }
                MEM_freeN(fluidmd->fss);
        }
 #endif
@@ -462,21 +470,86 @@ DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifie
        // load vertex velocities, if they exist...
        // TODO? use generate flag as loading flag as well?
        // warning, needs original .bobj.gz mesh loading filename
-       /*
        if(displaymode==3) 
        {
-               readVelgz(targetFile, srcob);
+               fluidsim_read_vel_cache(fluidmd, dm, targetFile);
        } 
        else 
        {
-               // no data for preview, only clear...
-               int i,j;
-               for(i=0; i<mesh->totvert;i++) { for(j=0; j<3; j++) { srcob->fluidsimSettings->meshSurfNormals[i].co[j] = 0.; }} 
-       }*/
+               if(fss->meshSurfNormals)
+                       MEM_freeN(fss->meshSurfNormals); 
+                       
+               fss->meshSurfNormals = NULL;
+       }
        
        return dm;
 }
 
+
+/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
+void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename)
+{
+       int wri, i, j;
+       float wrf;
+       gzFile gzf;
+       FluidsimSettings *fss = fluidmd->fss;
+       int len = strlen(filename);
+       int totvert = dm->getNumVerts(dm);
+       float *velarray = NULL;
+       
+       // mesh and vverts have to be valid from loading...
+       
+       if(fss->meshSurfNormals)
+               MEM_freeN(fss->meshSurfNormals);
+               
+       if(len<7) 
+       { 
+               return; 
+       }
+       
+       if(fss->domainNovecgen>0) return;
+       
+       // abusing pointer to hold an array of 3d-velocities
+       fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
+       // abusing pointer to hold an INT
+       fss->meshSurface = SET_INT_IN_POINTER(totvert);
+       
+       velarray = (float *)fss->meshSurfNormals;
+       
+       // .bobj.gz , correct filename
+       // 87654321
+       filename[len-6] = 'v';
+       filename[len-5] = 'e';
+       filename[len-4] = 'l';
+
+       gzf = gzopen(filename, "rb");
+       if (!gzf)
+       {
+               MEM_freeN(fss->meshSurfNormals);
+               fss->meshSurfNormals = NULL;    
+               return;
+       }
+
+       gzread(gzf, &wri, sizeof( wri ));
+       if(wri != totvert) 
+       {
+               MEM_freeN(fss->meshSurfNormals);
+               fss->meshSurfNormals = NULL;
+               return; 
+       }
+
+       for(i=0; i<totvert;i++) 
+       {
+               for(j=0; j<3; j++) 
+               {
+                       gzread(gzf, &wrf, sizeof( wrf )); 
+                       velarray[3*i + j] = wrf;
+               }
+       }
+
+       gzclose(gzf);
+}
+
 void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
                 /*RET*/ float start[3], /*RET*/ float size[3] )
 {
@@ -583,60 +656,5 @@ void initElbeemMesh(struct Object *ob,
        dm->release(dm);
 }
 
-/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
-void readVelgz(char *filename, Object *srcob)
-{
-       int wri, i, j;
-       float wrf;
-       gzFile gzf;
-       MVert *vverts = srcob->fluidsimSettings->meshSurfNormals;
-       int len = strlen(filename);
-       Mesh *mesh = srcob->data;
-       // mesh and vverts have to be valid from loading...
-
-       // clean up in any case
-       for(i=0; i<mesh->totvert;i++) 
-       { 
-               for(j=0; j<3; j++) 
-               {
-                       vverts[i].co[j] = 0.; 
-               } 
-       } 
-       if(srcob->fluidsimSettings->domainNovecgen>0) return;
-
-       if(len<7) 
-       { 
-               return; 
-       }
-
-       // .bobj.gz , correct filename
-       // 87654321
-       filename[len-6] = 'v';
-       filename[len-5] = 'e';
-       filename[len-4] = 'l';
-
-       gzf = gzopen(filename, "rb");
-       if (!gzf)
-               return;
-
-       gzread(gzf, &wri, sizeof( wri ));
-       if(wri != mesh->totvert) 
-       {
-               return; 
-       }
-
-       for(i=0; i<mesh->totvert;i++) 
-       {
-               for(j=0; j<3; j++) 
-               {
-                       gzread(gzf, &wrf, sizeof( wrf )); 
-                       vverts[i].co[j] = wrf;
-               }
-       }
-
-       gzclose(gzf);
-}
-
-
 #endif // DISABLE_ELBEEM
 
index 77c891ee82eb0bcabae44ac7c0240eb82d15effe..a25afeafaef5fb3edd115b3ff865439c82d6cecb 100644 (file)
@@ -1163,7 +1163,10 @@ static void copy_object_pose(Object *obn, Object *ob)
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
-                       if(con->ipo) {
+                       /* note that we can't change lib linked ipo blocks. for making
+                        * proxies this still works correct however because the object
+                        * is changed to object->proxy_from when evaluating the driver. */
+                       if(con->ipo && !con->ipo->id.lib) {
                                IpoCurve *icu;
                                for(icu= con->ipo->curve.first; icu; icu= icu->next) {
                                        if(icu->driver && icu->driver->ob==ob)
index cef6f802729cf5e13f53337b68a22fb72232b43a..642b4fd1b19eb0ca457ac067c511241e05f0585d 100644 (file)
@@ -34,6 +34,7 @@
 #include <ffmpeg/rational.h>
 #include <ffmpeg/swscale.h>
 #include <ffmpeg/opt.h>
+#include <ffmpeg/log.h>
 
 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
 #define FFMPEG_OLD_FRAME_RATE 1
@@ -104,6 +105,18 @@ static RenderData *ffmpeg_renderdata = 0;
 
 #define FFMPEG_AUTOSPLIT_SIZE 2000000000
 
+void silence_log_ffmpeg(int quiet)
+{
+       if (quiet)
+       {
+               av_log_set_level(AV_LOG_QUIET);
+       }
+       else
+       {
+               av_log_set_level(AV_LOG_INFO);
+       }
+}
+
 /* Delete a picture buffer */
 
 static void delete_picture(AVFrame* f)
index 5a75b5c8b110426dd5dcaac269dde28a6d1c51c3..e4bc6e3abb208b8e07ce0a82dee5bbbccc0ebaac 100644 (file)
@@ -364,6 +364,9 @@ BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, Ble
        if (fd) {
                strcpy(fd->filename, filename);
                
+               /* clear ob->proxy_from pointers in G.main */
+               blo_clear_proxy_pointers_from_lib(fd);
+
                /* separate libraries from G.main */
                blo_split_main(&mainlist, G.main);
                /* add the library pointers in oldmap lookup */
index 3a9d0a6ae6a16cd611658fe33c86cf2886cb4df8..acedf51e6191f050d02e7e8c67f3d8bd12766661 100644 (file)
@@ -1130,6 +1130,19 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi
        }
 }
 
+/* lib linked proxy objects point to our local data, we need
+ * to clear that pointer before reading the undo memfile since
+ * the object might be removed, it is set again in reading
+ * if the local object still exists */
+void blo_clear_proxy_pointers_from_lib(FileData *fd)
+{
+       Object *ob= G.main->object.first;
+       
+       for(;ob; ob= ob->id.next)
+               if(ob->id.lib)
+                       ob->proxy_from= NULL;
+}
+
 /* assumed; G.main still exists */
 void blo_make_image_pointer_map(FileData *fd)
 {
index 7ddb1e361da010cfde4ccaad36a356bae60ae9c9..8547a4d96523b6c6d82a230642ab15339bba514e 100644 (file)
@@ -112,6 +112,7 @@ FileData *blo_openblenderfile( char *name, BlendReadError *error_r);
 FileData *blo_openblendermemory( void *buffer, int buffersize, BlendReadError *error_r);
 FileData *blo_openblendermemfile(struct MemFile *memfile, BlendReadError *error_r);
 
+void blo_clear_proxy_pointers_from_lib(FileData *fd);
 void blo_make_image_pointer_map(FileData *fd);
 void blo_end_image_pointer_map(FileData *fd);
 void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);
index 4f6730db1f1efe7f9872dc098dca2e51f12dc3f8..05d594019a5a5796da44b7d3661b2a6caf9d305c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "DNA_userdef_types.h"
 #include "BKE_global.h"
+#include "BKE_writeffmpeg.h" /* for silence_log_ffmpeg */
 
 #include "imbuf.h"
 #include "imbuf_patch.h"
@@ -64,6 +65,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 +238,12 @@ void do_init_ffmpeg()
        if (!ffmpeg_init) {
                ffmpeg_init = 1;
                av_register_all();
+               //avdevice_register_all();
+               
+               if ((G.f & G_DEBUG) == 0)
+               {
+                       silence_log_ffmpeg(1);
+               }
        }
 }
 
index acba9ae2d1d4e096d7656448cce2adcf00aa33e3..aaf5ecc910bf6769a102c3baea0a22172c441a8f 100644 (file)
@@ -10,8 +10,8 @@ root_build_dir=env['BF_BUILDDIR']
 source_files = ['makesdna.c']
 header_files = env.Glob('../*.h')
 
-makesdna_tool = env.Copy()
-dna = env.Copy()
+makesdna_tool = env.Clone()
+dna = env.Clone()
 makesdna_tool.Append(CCFLAGS = '-DBASE_HEADER="\\"source/blender/makesdna/\\"" ')
 
 makesdna_tool.Append (CPPPATH = ['#/intern/guardedalloc',
index aa3ef82a3e8f6d7af7c455e33069bc6850e12a4a..99a4398ec89c3fe010d05109658cd3f5170178fc 100644 (file)
@@ -244,7 +244,8 @@ static PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
        }
        if(value == NULL){  /* item not found in dict. throw exception */
                char* key_str = PyString_AsString( key );
-               if (key_str) {
+               
+               if (key_str==NULL) {
                        return EXPP_ReturnPyObjError(PyExc_KeyError, "bone key must be a string" );
                } else {
                        char buffer[128];
index 49d20894c582d8411614541bfacea2e66414309c..eca5d9a615cc2eef011398a9e66a40d3ca5d3341 100644 (file)
@@ -23,6 +23,6 @@ if epydoc:
     optvalues["names"] = names
     optparser = OptionParser()
     optparser.set_defaults(**optvalues)
-    (options, args) = optparser.parse_args()
+    (options, args) = optparser.parse_args([])
     cli.write_html(docindex, options)
 
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 ae955a63f98443463b58d321e9053bbfdbd1bfe4..1a387ad74667bde1e8f9096fb6b5a854ac0c868c 100644 (file)
@@ -5141,23 +5141,30 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        float hoco[4], ho[4], fsvec[4], camco[4];
        float mat[4][4], winmat[4][4];
        float imat[4][4];
-       MVert *vverts;
-
+       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim);
+       FluidsimSettings *fss = fluidmd->fss;
+       float *velarray = NULL;
+       
        /* only one step needed */
        if(step) return 1;
        
+       if(fluidmd)
+               fss = fluidmd->fss;
+       else
+               return 0;
+       
        Mat4CpyMat4(mat, re->viewmat);
        MTC_Mat4Invert(imat, mat);
 
        /* set first vertex OK */
-       if( (!fsob->fluidsimSettings) || (!fsob->fluidsimSettings->meshSurfNormals) ) return 0;
-       vverts = fsob->fluidsimSettings->meshSurfNormals;
-       //fprintf(stderr, "GZ_VEL obj '%s', calc load_fluidsimspeedvectors\n",fsob->id.name); // NT DEBUG
-
-       if( obr->totvert != fsob->fluidsimSettings->meshSurface->totvert ) {
+       if(!fss->meshSurfNormals) return 0;
+       
+       if( obr->totvert != GET_INT_FROM_POINTER(fss->meshSurface) ) {
                //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
                return 0;
        }
+       
+       velarray = (float *)fss->meshSurfNormals;
 
        if(obi->flag & R_TRANSFORMED)
                Mat4MulMat4(winmat, obi->mat, re->winmat);
@@ -5169,7 +5176,8 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        so that also small drops/little water volumes return a velocity != 0. 
        But I had no luck in fixing that function - DG */
        for(a=0; a<obr->totvert; a++) {
-               for(j=0;j<3;j++) avgvel[j] += vverts[a].co[j];
+               for(j=0;j<3;j++) avgvel[j] += velarray[3*a + j];
+               
        }
        for(j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert);
        
@@ -5183,7 +5191,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
                // get fluid velocity
                fsvec[3] = 0.; 
                //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
-               for(j=0;j<3;j++) fsvec[j] = vverts[a].co[j];
+               for(j=0;j<3;j++) fsvec[j] = velarray[3*a + j];
                
                /* (bad) HACK insert average velocity if none is there (see previous comment) */
                if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))
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 26c0496f1070aba73da8919f9aea928d7c4536ed..46b833fb6493be5ffb40a47c02ceff8dc26e54ab 100644 (file)
@@ -5852,8 +5852,10 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig
                uiBlockBeginAlign(block);
                uiDefBut(block,LABEL,B_NOP,"",cx,cy,115,20,0,0,0,0,0,""); /* Padding */
        } else {
+               ID *id = NULL;
+
                mtex= sd->mtex[sd->texact];
-               ID *id= NULL;
+
                uiBlockBeginAlign(block);
                
                if(mtex && mtex->tex) id= &mtex->tex->id;
index 0dcdc36fdcdda1eed2483a1a31dfc73f7494b6fe..8aca111f41ff24f65656a451d8bfd7cd83b23221 100644 (file)
@@ -3549,7 +3549,7 @@ void logic_buts(void)
                if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
                uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
                uiBlockEndAlign(block);
-               yco-=17;
+               yco-=20;
                
                /* mark all actuators linked to these controllers */
                /* note that some of these actuators could be from objects that are not in the display list.
index 28baf87baa1eb60e98fdef79574a423a08cf9a4e..7417218f2539a5e51552e8123cfe5b11d2b2f05e 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) {
@@ -2153,7 +2153,7 @@ static int ui_act_as_text_but(uiBut *but)
                value = 0.0f; /* Zero out value on error */
                
                if(str[0]) 
-                       retval = 0;  /* invalidate return value if eval failed, except when string was null */
+                       retval = B_NOP;  /* invalidate return value if eval failed, except when string was null */
        }
 #else
        value=atof(str);
index e84d1aac3a797e3d05b8e4c3d2c1504f46353c45..ee6f19e457d00690b36c0c93664fbe2c802180b2 100644 (file)
@@ -143,6 +143,7 @@ IF(WIN32)
     COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\.blender\\scripts\"
     COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\"
     COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\"
+    COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python25.zip\" \"${TARGETDIR}\\\"
   )
   
   FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR)
@@ -265,7 +266,8 @@ IF(UNIX)
     blender_python
     bf_quicktime
     extern_binreloc
-       extern_glew
+    extern_glew
+    bf_videotex
   )
 
   FOREACH(SORTLIB ${BLENDER_SORTED_LIBS})
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 1d3bc8c2058f89a78bdcd29ab0f9d4964a245215..51bc0f7d39f4ce657d4a4455be3bc4261371e3be 100644 (file)
@@ -35,7 +35,7 @@ DIR = $(OCGDIR)/gameengine
 DIRS = BlenderRoutines
 DIRS += Converter
 DIRS += Expressions GameLogic Ketsji Rasterizer SceneGraph
-DIRS += Network Physics
+DIRS += Network Physics VideoTexture
 
 ifeq ($(WITH_BF_BLENDERGAMEENGINE),true)
   DIRS += GamePlayer
index be7922efd446e3cbe4a65387ee6270905651b8e4..86e8db5919fe64c40530672e5e68ea0fb15d170e 100644 (file)
@@ -1,7 +1,6 @@
 #!/usr/bin/python
 Import ('env')
 
-sumoenv = env.Copy()
 sources = ['SumoPHYCallbackBridge.cpp',
                 'SumoPhysicsController.cpp',
                 'SumoPhysicsEnvironment.cpp',
@@ -16,7 +15,7 @@ incs =['.',
        'Fuzzics/include',
        '#/intern/moto/include'
        ]
-incs += [sumoenv['BF_SOLID_INC']]
+incs += [env['BF_SOLID_INC']]
 
 cflags = []
 if env['OURPLATFORM']=='win32-vc':
index 3d1aa66bc69d41fd52a3d7cdcca8a02c998d13e3..ac0b163d7bd00ca84f5817f07f2f28747e49ffc2 100644 (file)
@@ -23,6 +23,6 @@ if epydoc:
     optvalues["names"] = names
     optparser = OptionParser()
     optparser.set_defaults(**optvalues)
-    (options, args) = optparser.parse_args()
+    (options, args) = optparser.parse_args([])
     cli.write_html(docindex, options)
 
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..3ac8b8e
--- /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 <PyObjectPlus.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..b0112cd
--- /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 <PyObjectPlus.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..c530e38
--- /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 <PyObjectPlus.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..50c3a87
--- /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 <PyObjectPlus.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..a1ddf58
--- /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 <PyObjectPlus.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..514214b
--- /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 <PyObjectPlus.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..8d8749d
--- /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 <PyObjectPlus.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..c3d4e00
--- /dev/null
@@ -0,0 +1,231 @@
+/* $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..dcca20d
--- /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 <PyObjectPlus.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..138580c
--- /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 <PyObjectPlus.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..a0c6e1f
--- /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 <PyObjectPlus.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..8532249
--- /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 <PyObjectPlus.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..fb28426
--- /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 <PyObjectPlus.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..4ed1cd9
--- /dev/null
@@ -0,0 +1,297 @@
+/* $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 <PyObjectPlus.h>
+#include <structmember.h>
+
+#include <BIF_gl.h>
+
+#include "Texture.h"
+#include "ImageBase.h"
+#include "FilterSource.h"
+#include "ImageViewport.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] = short(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 (GLint * 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], (GLsizei)m_capSize[0], (GLsizei)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], (GLsizei)m_capSize[0], (GLsizei)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
+       GLint pos [] = {
+               GLint(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
+                       GLint(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..4265906
--- /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
+       GLint * getPosition (void) { return m_position; }
+       /// set position in viewport
+       void setPosition (GLint * pos = NULL);
+
+protected:
+       /// frame buffer rectangle
+       GLint m_viewport[4];
+
+       /// size of captured area
+       short m_capSize[2];
+       /// use whole viewport
+       bool m_whole;
+
+       /// position of capture rectangle in viewport
+       GLint m_position[2];
+       /// upper left point for capturing
+       GLint 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
+       GLint * 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..0451d74
--- /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 <PyObjectPlus.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..4daf88b
--- /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 <PyObjectPlus.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..f3fe0da
--- /dev/null
@@ -0,0 +1,32 @@
+#!/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_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..ceda39a
--- /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 <PyObjectPlus.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..569e34d
--- /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 <PyObjectPlus.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..5bb635e
--- /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 <PyObjectPlus.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];
+