From 68cde07b99a716e66f4d242bc90236881333172d Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 31 Oct 2008 13:58:59 +0000 Subject: [PATCH 01/51] corrections to the C_WARN and CC_WARN variables for scons config. I didn't actually changed what the flags were, just the format, but Platform Maintainers, please check. --- config/darwin-config.py | 4 ++-- config/openbsd3-config.py | 4 ++-- config/sunos5-config.py | 4 ++-- config/win32-mingw-config.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/darwin-config.py b/config/darwin-config.py index ccc3eb5a0d0..547d655b531 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -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 diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index b2112c84b98..0a4f75e3bcc 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -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 diff --git a/config/sunos5-config.py b/config/sunos5-config.py index bb6c5d89e46..2343ce69060 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -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 diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index d7ecad33bca..bdeca1ddc91 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -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' ] From 25a2753877a8e63e2f3eca24818d76a99f628a8c Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 31 Oct 2008 14:15:35 +0000 Subject: [PATCH 02/51] This is coverity issue CID: 456 fixes a buffer overrun issue. Kent --- source/blender/src/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 28baf87baa1..9decbd9a1ce 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -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) { From 027d86b9ff5a4f7b859b28e33d3d40f264a4e55b Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 31 Oct 2008 16:33:42 +0000 Subject: [PATCH 03/51] * doc update --- doc/blender-scons.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/blender-scons.txt b/doc/blender-scons.txt index 8578d3f2fd4..f7ea7767441 100644 --- a/doc/blender-scons.txt +++ b/doc/blender-scons.txt @@ -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/ From 3f7535d3c3fa5e72ee7640c27827c47ad27c908e Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 31 Oct 2008 20:35:14 +0000 Subject: [PATCH 04/51] * silence compiler about warnings for C++ files a bit more. - from what I can see now, the larger part of warnings is now about conversions "possible loss of data" (ie. double to float, etc). --- config/win32-vc-config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 6cc09748a10..a5aa76c2868 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -161,6 +161,7 @@ CC = 'cl.exe' CXX = 'cl.exe' CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT'] +CXXFLAGS = ['/EHsc'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] From 44efce4f669a95291b96fff52b7cb664f50447fb Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 31 Oct 2008 20:47:30 +0000 Subject: [PATCH 05/51] * remove unreferenced var --- intern/ghost/intern/GHOST_WindowWin32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 6a06f4d715a..2094ae87c67 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -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; From 858581369342466b557019b5530d4c0e389fe707 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 31 Oct 2008 20:50:07 +0000 Subject: [PATCH 06/51] Update MSVC project files --- projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj | 6 ++++++ projectfiles_vc7/blender/src/BL_src.vcproj | 3 +++ 2 files changed, 9 insertions(+) diff --git a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj index 0dfbcaa5577..aadef58f84a 100644 --- a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj +++ b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj @@ -382,6 +382,9 @@ + + @@ -458,6 +461,9 @@ + + diff --git a/projectfiles_vc7/blender/src/BL_src.vcproj b/projectfiles_vc7/blender/src/BL_src.vcproj index 80694690107..d6e436635cb 100644 --- a/projectfiles_vc7/blender/src/BL_src.vcproj +++ b/projectfiles_vc7/blender/src/BL_src.vcproj @@ -121,6 +121,9 @@ + + From 77b4c66cc3de461fdd0074e46a3a77de1fd83447 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 31 Oct 2008 21:06:48 +0000 Subject: [PATCH 07/51] Preparation to VideoTexture: everything but the VideoTexture module itself. Rename PHY_GetActiveScene() to KX_GetActiveScene(): more logical name Add KX_GetActiveEngine() new KX_KetsjiEngine::GetClockTime(void) to return current render frame time: if the CPU does not keep up with the frame rate, up to 5 consecutive logic frames are processed between each render frame, so that the logic system stays accurate even if the graphic system is slow. For the video texture module, it is important to stay in sync with the render frame: no need to update the texture for logic frame. BL_Texture::swapTexture(): texture id manipulation BL_Texture::getTex() : return material texture Enable video support in ffmpeg for Linux. --- projectfiles_vc7/blender/blender.vcproj | 2 +- source/blender/imbuf/intern/util.c | 2 ++ .../gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp | 1 + source/gameengine/Ketsji/BL_Texture.h | 8 ++++++++ source/gameengine/Ketsji/KX_BlenderMaterial.h | 3 +++ source/gameengine/Ketsji/KX_Camera.cpp | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 8 ++++---- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 9 +++++++-- source/gameengine/Ketsji/KX_KetsjiEngine.h | 5 +++++ source/gameengine/Ketsji/KX_ParentActuator.cpp | 2 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 9 +++++++-- source/gameengine/Ketsji/KX_PythonInit.h | 9 +++++++-- 12 files changed, 47 insertions(+), 13 deletions(-) diff --git a/projectfiles_vc7/blender/blender.vcproj b/projectfiles_vc7/blender/blender.vcproj index 26cb3fb79e1..ef6900b7b75 100644 --- a/projectfiles_vc7/blender/blender.vcproj +++ b/projectfiles_vc7/blender/blender.vcproj @@ -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" diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 4f6730db1f1..70a02d72b01 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -64,6 +64,7 @@ #ifdef WITH_FFMPEG #include #include +#include #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -236,6 +237,7 @@ void do_init_ffmpeg() if (!ffmpeg_init) { ffmpeg_init = 1; av_register_all(); + avdevice_register_all(); } } diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 9fbdc3fa1c9..2b3ef1b31e3 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -364,6 +364,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, initGameKeys(); initPythonConstraintBinding(); initMathutils(); + //initVideoTexture(); if (sceneconverter) { diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index 0d0c7a277f2..830ffceb0f7 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -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__ diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 4ddf5a924df..b858fa3754c 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -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( diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 3830d422138..53b3e348a36 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -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; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 739c122a5ef..a168beb9a70 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -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; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index b1ab8e3e7de..8bcda4479e1 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -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; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 1aa067a9962..4184202c518 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -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" diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index eb56e8de679..89549ca6b57 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -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) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index a30d9f4022d..0032d83c2ff 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -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) { diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 36e3db6ec35..57ee0be9400 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -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); From a8c4eef3265358d3d70c6c448fe4d1c4273defee Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 31 Oct 2008 22:35:52 +0000 Subject: [PATCH 08/51] VideoTexture module. The only compilation system that works for sure is the MSVC project files. I've tried my best to update the other compilation system but I count on the community to check and fix them. This is Zdeno Miklas video texture plugin ported to trunk. The original plugin API is maintained (can be found here http://home.scarlet.be/~tsi46445/blender/blendVideoTex.html) EXCEPT for the following: The module name is changed to VideoTexture (instead of blendVideoTex). A new (and only) video source is now available: VideoFFmpeg() You must pass 1 to 4 arguments when you create it (you can use named arguments): VideoFFmpeg(file) : play a video file VideoFFmpeg(file, capture, rate, width, height) : start a live video capture file: In the first form, file is a video file name, relative to startup directory. It can also be a URL, FFmpeg will happily stream a video from a network source. In the second form, file is empty or is a hint for the format of the video capture. In Windows, file is ignored and should be empty or not specified. In Linux, ffmpeg supports two types of device: VideoForLinux and DV1394. The user specifies the type of device with the file parameter: [][:] : 'v4l' for VideoForLinux, 'dv1394' for DV1394; default to 'v4l' : 'pal', 'secam' or 'ntsc', default to 'ntsc' The driver name is constructed automatically from the device types: v4l : /dev/video dv1394: /dev/dv1394/ If you have different driver name, you can specify the driver name explicitely instead of device type. Examples of valid file parameter: /dev/v4l/video0:pal /dev/ieee1394/1:ntsc dv1394:ntsc v4l:pal :secam capture: Defines the index number of the capture source, starting from 0. The first capture device is always 0. The VideoTexutre modules knows that you want to start a live video capture when you set this parameter to a number >= 0. Setting this parameter < 0 indicates a video file playback. Default value is -1. rate: the capture frame rate, by default 25 frames/sec width: height: Width and height of the video capture in pixel, default value 0. In Windows you must specify these values and they must fit with the capture device capability. For example, if you have a webcam that can capture at 160x120, 320x240 or 640x480, you must specify one of these couple of values or the opening of the video source will fail. In Linux, default values are provided by the VideoForLinux driver if you don't specify width and height. Simple example ************** 1. Texture definition script: import VideoTexture contr = GameLogic.getCurrentController() obj = contr.getOwner() if not hasattr(GameLogic, 'video'): matID = VideoTexture.materialID(obj, 'MAVideoMat') GameLogic.video = VideoTexture.Texture(obj, matID) GameLogic.vidSrc = VideoTexture.VideoFFmpeg('trailer_400p.ogg') # Streaming is also possible: #GameLogic.vidSrc = VideoTexture.VideoFFmpeg('http://10.32.1.10/trailer_400p.ogg') GameLogic.vidSrc.repeat = -1 # If the video dimensions are not a power of 2, scaling must be done before # sending the texture to the GPU. This is done by default with gluScaleImage() # but you can also use a faster, but less precise, scaling by setting scale # to True. Best approach is to convert the video offline and set the dimensions right. GameLogic.vidSrc.scale = True # FFmpeg always delivers the video image upside down, so flipping is enabled automatically #GameLogic.vidSrc.flip = True if contr.getSensors()[0].isPositive(): GameLogic.video.source = GameLogic.vidSrc GameLogic.vidSrc.play() 2. Texture refresh script: obj = GameLogic.getCurrentController().getOwner() if hasattr(GameLogic, 'video') != 0: GameLogic.video.refresh(True) You can download this demo here: http://home.scarlet.be/~tsi46445/blender/VideoTextureDemo.blend http://home.scarlet.be/~tsi46445/blender/trailer_400p.ogg --- projectfiles_vc7/blender/blender.sln | 17 + .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 2 +- source/gameengine/CMakeLists.txt | 1 + source/gameengine/SConscript | 3 +- source/gameengine/VideoTexture/BlendType.h | 75 ++ source/gameengine/VideoTexture/CMakeLists.txt | 60 ++ source/gameengine/VideoTexture/Common.h | 55 ++ source/gameengine/VideoTexture/Exception.cpp | 198 +++++ source/gameengine/VideoTexture/Exception.h | 195 +++++ source/gameengine/VideoTexture/FilterBase.cpp | 150 ++++ source/gameengine/VideoTexture/FilterBase.h | 132 ++++ .../VideoTexture/FilterBlueScreen.cpp | 178 +++++ .../VideoTexture/FilterBlueScreen.h | 98 +++ .../gameengine/VideoTexture/FilterColor.cpp | 350 ++++++++ source/gameengine/VideoTexture/FilterColor.h | 164 ++++ .../gameengine/VideoTexture/FilterNormal.cpp | 162 ++++ source/gameengine/VideoTexture/FilterNormal.h | 98 +++ .../gameengine/VideoTexture/FilterSource.cpp | 125 +++ source/gameengine/VideoTexture/FilterSource.h | 233 ++++++ source/gameengine/VideoTexture/ImageBase.cpp | 529 +++++++++++++ source/gameengine/VideoTexture/ImageBase.h | 349 ++++++++ source/gameengine/VideoTexture/ImageBuff.cpp | 166 ++++ source/gameengine/VideoTexture/ImageBuff.h | 51 ++ source/gameengine/VideoTexture/ImageMix.cpp | 205 +++++ source/gameengine/VideoTexture/ImageMix.h | 123 +++ .../gameengine/VideoTexture/ImageRender.cpp | 261 ++++++ source/gameengine/VideoTexture/ImageRender.h | 90 +++ .../gameengine/VideoTexture/ImageViewport.cpp | 298 +++++++ .../gameengine/VideoTexture/ImageViewport.h | 84 ++ source/gameengine/VideoTexture/Makefile | 65 ++ source/gameengine/VideoTexture/PyTypeList.cpp | 83 ++ source/gameengine/VideoTexture/PyTypeList.h | 85 ++ source/gameengine/VideoTexture/SConscript | 32 + source/gameengine/VideoTexture/Texture.cpp | 463 +++++++++++ source/gameengine/VideoTexture/Texture.h | 87 ++ source/gameengine/VideoTexture/VideoBase.cpp | 183 +++++ source/gameengine/VideoTexture/VideoBase.h | 185 +++++ .../gameengine/VideoTexture/VideoFFmpeg.cpp | 747 ++++++++++++++++++ source/gameengine/VideoTexture/VideoFFmpeg.h | 159 ++++ .../gameengine/VideoTexture/blendVideoTex.cpp | 206 +++++ 40 files changed, 6745 insertions(+), 2 deletions(-) create mode 100644 source/gameengine/VideoTexture/BlendType.h create mode 100644 source/gameengine/VideoTexture/CMakeLists.txt create mode 100644 source/gameengine/VideoTexture/Common.h create mode 100644 source/gameengine/VideoTexture/Exception.cpp create mode 100644 source/gameengine/VideoTexture/Exception.h create mode 100644 source/gameengine/VideoTexture/FilterBase.cpp create mode 100644 source/gameengine/VideoTexture/FilterBase.h create mode 100644 source/gameengine/VideoTexture/FilterBlueScreen.cpp create mode 100644 source/gameengine/VideoTexture/FilterBlueScreen.h create mode 100644 source/gameengine/VideoTexture/FilterColor.cpp create mode 100644 source/gameengine/VideoTexture/FilterColor.h create mode 100644 source/gameengine/VideoTexture/FilterNormal.cpp create mode 100644 source/gameengine/VideoTexture/FilterNormal.h create mode 100644 source/gameengine/VideoTexture/FilterSource.cpp create mode 100644 source/gameengine/VideoTexture/FilterSource.h create mode 100644 source/gameengine/VideoTexture/ImageBase.cpp create mode 100644 source/gameengine/VideoTexture/ImageBase.h create mode 100644 source/gameengine/VideoTexture/ImageBuff.cpp create mode 100644 source/gameengine/VideoTexture/ImageBuff.h create mode 100644 source/gameengine/VideoTexture/ImageMix.cpp create mode 100644 source/gameengine/VideoTexture/ImageMix.h create mode 100644 source/gameengine/VideoTexture/ImageRender.cpp create mode 100644 source/gameengine/VideoTexture/ImageRender.h create mode 100644 source/gameengine/VideoTexture/ImageViewport.cpp create mode 100644 source/gameengine/VideoTexture/ImageViewport.h create mode 100644 source/gameengine/VideoTexture/Makefile create mode 100644 source/gameengine/VideoTexture/PyTypeList.cpp create mode 100644 source/gameengine/VideoTexture/PyTypeList.h create mode 100644 source/gameengine/VideoTexture/SConscript create mode 100644 source/gameengine/VideoTexture/Texture.cpp create mode 100644 source/gameengine/VideoTexture/Texture.h create mode 100644 source/gameengine/VideoTexture/VideoBase.cpp create mode 100644 source/gameengine/VideoTexture/VideoBase.h create mode 100644 source/gameengine/VideoTexture/VideoFFmpeg.cpp create mode 100644 source/gameengine/VideoTexture/VideoFFmpeg.h create mode 100644 source/gameengine/VideoTexture/blendVideoTex.cpp diff --git a/projectfiles_vc7/blender/blender.sln b/projectfiles_vc7/blender/blender.sln index eb235531984..c1628614642 100644 --- a/projectfiles_vc7/blender/blender.sln +++ b/projectfiles_vc7/blender/blender.sln @@ -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 diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 2b3ef1b31e3..2d91bbcd7c1 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -364,7 +364,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, initGameKeys(); initPythonConstraintBinding(); initMathutils(); - //initVideoTexture(); + initVideoTexture(); if (sceneconverter) { diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt index 93de588ba00..3ea788791e2 100644 --- a/source/gameengine/CMakeLists.txt +++ b/source/gameengine/CMakeLists.txt @@ -40,6 +40,7 @@ SUBDIRS( SceneGraph Physics/Bullet Physics/Sumo + VideoTexture ) IF(WITH_PLAYER) diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index c2750d19706..e841f206eee 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/SConscript @@ -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 index 00000000000..ac3ed8812a6 --- /dev/null +++ b/source/gameengine/VideoTexture/BlendType.h @@ -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 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 index 00000000000..fbae66e0ef4 --- /dev/null +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -0,0 +1,60 @@ +# $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) +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 index 00000000000..f771077bbba --- /dev/null +++ b/source/gameengine/VideoTexture/Common.h @@ -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 diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp new file mode 100644 index 00000000000..a326430b27a --- /dev/null +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -0,0 +1,198 @@ +/* $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 +#include + +#include + +#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) +{ + m_expDescs.push_back(this); +} + +// destructor +ExpDesc::~ExpDesc (void) {} + +// list of descriptions +std::vector 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::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; +} diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h new file mode 100644 index 00000000000..85865fb3654 --- /dev/null +++ b/source/gameengine/VideoTexture/Exception.h @@ -0,0 +1,195 @@ +/* $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 +#include +#include + +#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; + } + + // list of exception descriptions + static std::vector 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; + +}; + +#endif diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp new file mode 100644 index 00000000000..078a096aff7 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -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 +#include + + +// 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(type->tp_alloc(type, 0)); + // initialize object structure + self->m_filter = NULL; + // return allocated object + return reinterpret_cast(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(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(value)); + } + // return success + return 0; +} diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h new file mode 100644 index 00000000000..fa6f9a754d4 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -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 + +#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 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 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 static int Filter_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + PyFilter * self = reinterpret_cast(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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp new file mode 100644 index 00000000000..d911b1d7743 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -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 +#include + +#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(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, /* 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 index 00000000000..1871fbc0516 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterBlueScreen.h @@ -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 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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp new file mode 100644 index 00000000000..c45804caf9d --- /dev/null +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -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 +#include + +#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, /* 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(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, /* 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(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, /* 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 index 00000000000..4465df97340 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterColor.h @@ -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 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 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 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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp new file mode 100644 index 00000000000..5eeb63b7128 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -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 +#include + +#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(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, /* 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 index 00000000000..fa61f04c0b7 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterNormal.h @@ -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 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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp new file mode 100644 index 00000000000..4b96a9792e2 --- /dev/null +++ b/source/gameengine/VideoTexture/FilterSource.cpp @@ -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 +#include + +#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, /* 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, /* 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 index 00000000000..b18186210dc --- /dev/null +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -0,0 +1,233 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of blendTex library + +Copyright (c) 2007 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#if !defined FILTERSOURCE_H +#define FILTERSOURCE_H + +#include "Common.h" + +#include "FilterBase.h" + + +/// class for RGB24 conversion +class FilterRGB24 : public FilterBase +{ +public: + /// constructor + FilterRGB24 (void) {} + /// destructor + virtual ~FilterRGB24 (void) {} + + /// get source pixel size + virtual unsigned int getPixelSize (void) { return 3; } + +protected: + /// filter pixel, source byte buffer + virtual unsigned int filter (unsigned char * src, short x, short y, + short * size, unsigned int pixSize, unsigned int val) + { return 0xFF000000 | src[0] << 16 | src[1] << 8 | src[2]; } +}; + + +/// class for BGR24 conversion +class FilterBGR24 : public FilterBase +{ +public: + /// constructor + FilterBGR24 (void) {} + /// destructor + virtual ~FilterBGR24 (void) {} + + /// get source pixel size + virtual unsigned int getPixelSize (void) { return 3; } + +protected: + /// filter pixel, source byte buffer + virtual unsigned int filter (unsigned char * src, short x, short y, + short * size, unsigned int pixSize, unsigned int val) + { return 0xFF000000 | src[2] << 16 | src[1] << 8 | src[0]; } +}; + + +/// class for YV12 conversion +class FilterYV12 : public FilterBase +{ +public: + /// constructor + FilterYV12 (void) {} + /// destructor + virtual ~FilterYV12 (void) {} + + /// get source pixel size + virtual unsigned int getPixelSize (void) { return 1; } + + /// set pointers to color buffers + void setBuffs (unsigned char * buff, short * size) + { + unsigned int buffSize = size[0] * size[1]; + m_buffV = buff + buffSize; + m_buffU = m_buffV + (buffSize >> 2); + m_pitchUV = size[0] >> 1; + } + +protected: + /// begin of V buffer + unsigned char * m_buffV; + /// begin of U buffer + unsigned char * m_buffU; + /// pitch for V & U buffers + short m_pitchUV; + + /// interpolation function + int interpol (int a, int b, int c, int d) + { return (9 * (b + c) - a - d + 8) >> 4; } + + /// common horizontal interpolation + int interpolH (unsigned char * src) + { return interpol(*(src-1), *src, *(src+1), *(src+2)); } + + /// common vertical interpolation + int interpolV (unsigned char * src) + { return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); } + + /// common joined vertical and horizontal interpolation + int interpolVH (unsigned char * src) + { + return interpol(interpolV(src-1), interpolV(src), interpolV(src+1), + interpolV(src+2)); + } + + /// is pixel on edge + bool isEdge (short x, short y, short * size) + { return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; } + + /// get the first parameter on the low edge + unsigned char * interParA (unsigned char * src, short x, short size, short shift) + { return x > 1 ? src - shift : src; } + /// get the third parameter on the high edge + unsigned char * interParC (unsigned char * src, short x, short size, short shift) + { return x < size - 2 ? src + shift : src; } + /// get the fourth parameter on the high edge + unsigned char * interParD (unsigned char * src, short x, short size, short shift) + { return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; } + + /// horizontal interpolation on edges + int interpolEH (unsigned char * src, short x, short size) + { + return interpol(*interParA(src, x, size, 1), *src, + *interParC(src, x, size, 1), *interParD(src, x, size, 1)); + } + + /// vertical interpolation on edges + int interpolEV (unsigned char * src, short y, short size) + { + return interpol(*interParA(src, y, size, m_pitchUV), *src, + *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV)); + } + + /// joined vertical and horizontal interpolation on edges + int interpolEVH (unsigned char * src, short x, short y, short * size) + { + return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]), + interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]), + interpolEV(interParD(src, x, size[0], 1), y, size[1])); + } + + + /// filter pixel, source byte buffer + virtual unsigned int filter (unsigned char * src, short x, short y, + short * size, unsigned int pixSize, unsigned int val) + { + // V & U offset + long offset = (x >> 1) + m_pitchUV * (y >> 1); + // get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128 + int c = *src - 16; + int d = m_buffU[offset] - 128; + int e = m_buffV[offset] - 128; + // if horizontal interpolation is needed + if ((x & 1) == 1) + // if vertical interpolation is needed too + if ((y & 1) == 1) + // if this pixel is on the edge + if (isEdge(x, y, size)) + { + // get U & V from edge + d = interpolEVH(m_buffU + offset, x, y, size) - 128; + e = interpolEVH(m_buffV + offset, x, y, size) - 128; + } + // otherwise get U & V from inner range + else + { + d = interpolVH(m_buffU + offset) - 128; + e = interpolVH(m_buffV + offset) - 128; + } + // otherwise use horizontal interpolation only + else + // if this pixel is on the edge + if (isEdge(x, y, size)) + { + // get U & V from edge + d = interpolEH(m_buffU + offset, x, size[0]) - 128; + e = interpolEH(m_buffV + offset, x, size[0]) - 128; + } + // otherwise get U & V from inner range + else + { + d = interpolH(m_buffU + offset) - 128; + e = interpolH(m_buffV + offset) - 128; + } + // otherwise if only vertical interpolation is needed + else if ((y & 1) == 1) + // if this pixel is on the edge + if (isEdge(x, y, size)) + { + // get U & V from edge + d = interpolEV(m_buffU + offset, y, size[1]) - 128; + e = interpolEV(m_buffV + offset, y, size[1]) - 128; + } + // otherwise get U & V from inner range + else + { + d = interpolV(m_buffU + offset) - 128; + e = interpolV(m_buffV + offset) - 128; + } + // convert to RGB + // R = clip(( 298 * C + 409 * E + 128) >> 8) + // G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) + // B = clip(( 298 * C + 516 * D + 128) >> 8) + int red = (298 * c + 409 * e + 128) >> 8; + if (red >= 0x100) red = 0xFF; + else if (red < 0) red = 0; + int green = 298 * c - 100 * d - 208 * e; + if (green > 0x10000) green = 0xFF00; + else if (green < 0) green = 0; + int blue = (298 * c + 516 * d + 128) << 8; + if (blue > 0x1000000) blue = 0xFF0000; + else if (blue < 0) blue = 0; + // return result + return 0xFF000000 | blue & 0xFF0000 | green & 0xFF00 + | red & 0xFF; + } +}; + + +#endif \ No newline at end of file diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp new file mode 100644 index 00000000000..28e7ad49224 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -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 +#include + +#include +#include + +#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(type->tp_alloc(type, 0)); + // initialize object structure + self->m_image = NULL; + // return allocated object + return reinterpret_cast(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(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(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(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(value)); + } + // return success + return 0; +} \ No newline at end of file diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h new file mode 100644 index 00000000000..817223c3d31 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageBase.h @@ -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 +#include + +#include "PyTypeList.h" + +#include "FilterBase.h" + + +// forward declarations +struct PyImage; +class ImageSource; + + +/// type for list of image sources +typedef std::vector 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 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 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 static int Image_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + PyImage * self = reinterpret_cast(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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp new file mode 100644 index 00000000000..f09514a36f0 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -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 +#include + +#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(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, /* 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 index 00000000000..fa2025fa8c4 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageBuff.h @@ -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 index 00000000000..56503066161 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -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 +#include + +#include "ImageMix.h" + +#include "ImageBase.h" + +#include "Exception.h" + + +// cast ImageSource pointer to ImageSourceMix +inline ImageSourceMix * getImageSourceMix (ImageSource * src) +{ return static_cast(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; +} + +static ExceptionID ImageSizesNotMatch; + +static 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(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, /* 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 index 00000000000..b4842bd6b40 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageMix.h @@ -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(*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 index 00000000000..c800b92e71d --- /dev/null +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -0,0 +1,261 @@ +/* $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 +#include + +#include +#include +#include +#include +#include +#include + +#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); +} + + +// 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(self->m_image); } + + +// python methods + +// Blender Scene type +BlendType sceneType ("KX_Scene"); +// Blender Camera type +BlendType cameraType ("KX_Camera"); + + +static ExceptionID SceneInvalid, CameraInvalid; +static ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid"); +static 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(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 index 00000000000..66255f04d2c --- /dev/null +++ b/source/gameengine/VideoTexture/ImageRender.h @@ -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 +#include +#include +#include +#include +#include + +#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 index 00000000000..e1d3316a43e --- /dev/null +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -0,0 +1,298 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of VideoTexture library + +Copyright (c) 2007 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +// implementation + +#include +#include + +#include "ImageViewport.h" + +#include + +#include "Texture.h" +#include "ImageBase.h" +#include "FilterSource.h" + + +// constructor +ImageViewport::ImageViewport (void) : m_texInit(false) +{ + // get viewport rectangle + glGetIntegerv(GL_VIEWPORT, m_viewport); + // create buffer for viewport image + m_viewportImage = new BYTE [3 * getViewportSize()[0] * getViewportSize()[1]]; + // set attributes + setWhole(false); +} + +// destructor +ImageViewport::~ImageViewport (void) +{ delete m_viewportImage; } + + +// use whole viewport to capture image +void ImageViewport::setWhole (bool whole) +{ + // set whole + m_whole = whole; + // set capture size to viewport size, if whole, + // otherwise place area in the middle of viewport + for (int idx = 0; idx < 2; ++idx) + { + // capture size + m_capSize[idx] = whole ? short(getViewportSize()[idx]) + : calcSize(short(getViewportSize()[idx])); + // position + m_position[idx] = whole ? 0 : (getViewportSize()[idx] - m_capSize[idx]) >> 1; + } + // init image + init(m_capSize[0], m_capSize[1]); + // set capture position + setPosition(); +} + +void ImageViewport::setCaptureSize (short * size) +{ + m_whole = false; + if (size == NULL) + size = m_capSize; + for (int idx = 0; idx < 2; ++idx) + { + if (size[idx] < 1) + m_capSize[idx] = 1; + else if (size[idx] > getViewportSize()[idx]) + m_capSize[idx] = getViewportSize()[idx]; + else + m_capSize[idx] = size[idx]; + } + init(m_capSize[0], m_capSize[1]); + // set capture position + setPosition(); +} + +// set position of capture rectangle +void ImageViewport::setPosition (int * pos) +{ + // if new position is not provided, use existing position + if (pos == NULL) pos = m_position; + // save position + for (int idx = 0; idx < 2; ++idx) + m_position[idx] = pos[idx] < 0 ? 0 : pos[idx] >= getViewportSize()[idx] + - m_capSize[idx] ? getViewportSize()[idx] - m_capSize[idx] : pos[idx]; + // recalc up left corner + for (int idx = 0; idx < 2; ++idx) + m_upLeft[idx] = m_position[idx] + m_viewport[idx]; +} + + +// capture image from viewport +void ImageViewport::calcImage (unsigned int texId) +{ + // if scale was changed + if (m_scaleChange) + // reset image + init(m_capSize[0], m_capSize[1]); + // if texture wasn't initialized + if (!m_texInit) + { + // initialize it + loadTexture(texId, m_image, m_size); + m_texInit = true; + } + // if texture can be directly created + if (texId != 0 && m_pyfilter == NULL && m_capSize[0] == calcSize(m_capSize[0]) + && m_capSize[1] == calcSize(m_capSize[1]) && !m_flip) + { + // just copy current viewport to texture + glBindTexture(GL_TEXTURE_2D, texId); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1]); + // image is not available + m_avail = false; + } + // otherwise copy viewport to buffer, if image is not available + else if (!m_avail) + { + // get frame buffer data + glReadPixels(m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1], GL_RGB, + GL_UNSIGNED_BYTE, m_viewportImage); + // filter loaded data + FilterBGR24 filt; + filterImage(filt, m_viewportImage, m_capSize); + } +} + + + +// cast Image pointer to ImageViewport +inline ImageViewport * getImageViewport (PyImage * self) +{ return static_cast(self->m_image); } + + +// python methods + + +// get whole +static PyObject * ImageViewport_getWhole (PyImage * self, void * closure) +{ + if (self->m_image != NULL && getImageViewport(self)->getWhole()) Py_RETURN_TRUE; + else Py_RETURN_FALSE; +} + +// set whole +static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure) +{ + // check parameter, report failure + if (value == NULL || !PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "The value must be a bool"); + return -1; + } + // set whole + if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True); + // success + return 0; +} + + +// get position +static PyObject * ImageViewport_getPosition (PyImage * self, void * closure) +{ + return Py_BuildValue("(ii)", getImageViewport(self)->getPosition()[0], + getImageViewport(self)->getPosition()[1]); +} + +// set position +static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + { + PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); + return -1; + } + // set position + int pos [] = { + int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), + int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + }; + getImageViewport(self)->setPosition(pos); + // success + return 0; +} + +// get capture size +static PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure) +{ + return Py_BuildValue("(ii)", getImageViewport(self)->getCaptureSize()[0], + getImageViewport(self)->getCaptureSize()[1]); +} + +// set capture size +static int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + { + PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); + return -1; + } + // set capture size + short size [] = { + short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), + short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + }; + getImageViewport(self)->setCaptureSize(size); + // success + return 0; +} + + +// methods structure +static PyMethodDef imageViewportMethods[] = +{ // methods from ImageBase class + {"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"}, + {NULL} +}; +// attributes structure +static PyGetSetDef imageViewportGetSets[] = +{ + {"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, "use whole viewport to capture", NULL}, + {"position", (getter)ImageViewport_getPosition, (setter)ImageViewport_setPosition, "upper left corner of captured area", NULL}, + {"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, "size of viewport area being captured", NULL}, + // attributes from ImageBase class + {"image", (getter)Image_getImage, NULL, "image data", NULL}, + {"size", (getter)Image_getSize, NULL, "image size", NULL}, + {"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL}, + {"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL}, + {"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL}, + {NULL} +}; + + +// define python type +PyTypeObject ImageViewportType = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "VideoTexture.ImageViewport", /*tp_name*/ + sizeof(PyImage), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Image_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "Image source from viewport", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + imageViewportMethods, /* tp_methods */ + 0, /* tp_members */ + imageViewportGetSets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Image_init, /* 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 index 00000000000..9fd3aeb7ba9 --- /dev/null +++ b/source/gameengine/VideoTexture/ImageViewport.h @@ -0,0 +1,84 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of VideoTexture library + +Copyright (c) 2007 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#if !defined IMAGEVIEWPORT_H +#define IMAGEVIEWPORT_H + + +#include "Common.h" + +#include "ImageBase.h" + + +/// class for viewport access +class ImageViewport : public ImageBase +{ +public: + /// constructor + ImageViewport (void); + + /// destructor + virtual ~ImageViewport (void); + + /// is whole buffer used + bool getWhole (void) { return m_whole; } + /// set whole buffer use + void setWhole (bool whole); + /// get capture size in viewport + short * getCaptureSize (void) { return m_capSize; } + /// set capture size in viewport + void setCaptureSize (short * size = NULL); + + /// get position in viewport + int * getPosition (void) { return m_position; } + /// set position in viewport + void setPosition (int * pos = NULL); + +protected: + /// frame buffer rectangle + int m_viewport[4]; + + /// size of captured area + short m_capSize[2]; + /// use whole viewport + bool m_whole; + + /// position of capture rectangle in viewport + int m_position[2]; + /// upper left point for capturing + int m_upLeft[2]; + + /// buffer to copy viewport + BYTE * m_viewportImage; + /// texture is initialized + bool m_texInit; + + /// capture image from viewport + virtual void calcImage (unsigned int texId); + + /// get viewport size + int * getViewportSize (void) { return m_viewport + 2; } +}; + + +#endif + diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile new file mode 100644 index 00000000000..bead176808b --- /dev/null +++ b/source/gameengine/VideoTexture/Makefile @@ -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 index 00000000000..b8c40052e81 --- /dev/null +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -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 +#include + +#include + + +/// 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 index 00000000000..7069cf8bb43 --- /dev/null +++ b/source/gameengine/VideoTexture/PyTypeList.h @@ -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 +#include + +#include + +// forward declaration +class PyTypeListItem; + +// type for list of types +typedef std::vector 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 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 \ No newline at end of file diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript new file mode 100644 index 00000000000..e0972e045cc --- /dev/null +++ b/source/gameengine/VideoTexture/SConscript @@ -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') + defs += ' __STDC_CONSTANT_MACROS' + +incs += ' ' + env['BF_PYTHON_INC'] +#incs += ' ' + env['BF_OPENGL_INC'] + +if env['WITH_BF_FFMPEG']: + defs += ' WITH_FFMPEG' + incs += ' ' + env['BF_FFMPEG_INC'] + +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 index 00000000000..d208802675c --- /dev/null +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "KX_KetsjiEngine.h" +#include "KX_PythonInit.h" +#include "Texture.h" +#include "ImageBase.h" +#include "Exception.h" + +#include +#include + + +// 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 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->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(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(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); +} + + +static ExceptionID MaterialNotAvail; +static 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(mat)->getTex(texID); + else + { + // get texture pointer from polygon material + MTFace * tface = static_cast(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(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", ¶m) || !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(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(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 index 00000000000..f19f8da607d --- /dev/null +++ b/source/gameengine/VideoTexture/Texture.h @@ -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 +#include + +#include +#include +#include + +#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 index 00000000000..038a04a55a8 --- /dev/null +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -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 +#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 index 00000000000..78e8ba65909 --- /dev/null +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -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 + +#include "ImageBase.h" + +#include "Exception.h" + +// source states +const int SourceError = -1; +const int SourceEmpty = 0; +const int SourceReady = 1; +const int SourcePlaying = 2; +const int SourceStopped = 3; + + +// video source formats +enum VideoFormat { None, RGB24, YV12 }; + + +/// base class for video source +class VideoBase : public ImageBase +{ +public: + /// constructor + VideoBase (void) : ImageBase(true), m_format(None), m_status(SourceEmpty), + m_repeat(0), m_frameRate(1.0) + { + m_orgSize[0] = m_orgSize[1] = 0; + m_range[0] = m_range[1] = 0.0; + } + + /// destructor + virtual ~VideoBase (void) {} + + /// open video file + virtual void openFile (char * file) + { + m_isFile = true; + m_status = SourceReady; + } + /// open video capture device + virtual void openCam (char * file, short camIdx) + { + m_isFile = false; + m_status = SourceReady; + } + + /// play video + virtual bool play (void) + { + if (m_status == SourceReady || m_status == SourceStopped) + { + m_status = SourcePlaying; + return true; + } + return false; + } + /// stop/pause video + virtual bool stop (void) + { + if (m_status == SourcePlaying) + { + m_status = SourceStopped; + return true; + } + return false; + } + + // get video status + int getStatus (void) { return m_status; } + + /// get play range + const double * getRange (void) { return m_range; } + /// set play range + virtual void setRange (double start, double stop) + { + if (m_isFile) + { + m_range[0] = start; + m_range[1] = stop; + } + } + + // get video repeat + int getRepeat (void) { return m_repeat; } + /// set video repeat + virtual void setRepeat (int rep) + { if (m_isFile) m_repeat = rep; } + + /// get frame rate + float getFrameRate (void) { return m_frameRate; } + /// set frame rate + virtual void setFrameRate (float rate) + { if (m_isFile) m_frameRate = rate > 0.0 ? rate : 1.0f; } + +protected: + /// video format + VideoFormat m_format; + /// original video size + short m_orgSize[2]; + + /// video status + int m_status; + + /// is source file + bool m_isFile; + + /// replay range + double m_range[2]; + /// repeat count + int m_repeat; + /// frame rate + float m_frameRate; + + /// initialize image data + void init (short width, short height); + + /// process source data + void process (BYTE * sample); +}; + + + +// python fuctions + + +// cast Image pointer to Video +inline VideoBase * getVideo (PyImage * self) +{ return static_cast(self->m_image); } + + +extern ExceptionID SourceVideoCreation; + +// object initialization +template void Video_init (PyImage * self) +{ + // create source video object + if (self->m_image != NULL) delete self->m_image; + HRESULT hRslt = S_OK; + self->m_image = new T(&hRslt); + CHCKHRSLT(hRslt, SourceVideoCreation); +} + + +// video functions +void Video_open (VideoBase * self, char * file, short captureID); +PyObject * Video_play (PyImage * self); +PyObject * Video_stop (PyImage * self); +PyObject * Video_refresh (PyImage * self); +PyObject * Video_getStatus (PyImage * self, void * closure); +PyObject * Video_getRange (PyImage * self, void * closure); +int Video_setRange (PyImage * self, PyObject * value, void * closure); +PyObject * Video_getRepeat (PyImage * self, void * closure); +int Video_setRepeat (PyImage * self, PyObject * value, void * closure); +PyObject * Video_getFrameRate (PyImage * self, void * closure); +int Video_setFrameRate (PyImage * self, PyObject * value, void * closure); + + +#endif + diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp new file mode 100644 index 00000000000..b12bad4b416 --- /dev/null +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -0,0 +1,747 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of VideoTexture library + +Copyright (c) 2007 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#include "MEM_guardedalloc.h" +#include "PIL_time.h" + +#include + +#include "Exception.h" +#include "VideoFFmpeg.h" + +#ifdef WITH_FFMPEG + +// default framerate +const double defFrameRate = 25.0; +// time scale constant +const long timeScale = 1000; + +// macro for exception handling and logging +#define CATCH_EXCP catch (Exception & exp) \ +{ exp.report(); m_status = SourceError; } + +extern "C" void do_init_ffmpeg(); + +// class RenderVideo + +// constructor +VideoFFmpeg::VideoFFmpeg (HRESULT * hRslt) : VideoBase(), +m_codec(NULL), m_formatCtx(NULL), m_codecCtx(NULL), +m_frame(NULL), m_frameDeinterlaced(NULL), m_frameBGR(NULL), m_imgConvertCtx(NULL), +m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0), +m_lastFrame(-1), m_curPosition(-1), m_startTime(0), +m_captWidth(0), m_captHeight(0), m_captRate(0.f) +{ + // set video format + m_format = RGB24; + // force flip because ffmpeg always return the image in the wrong orientation for texture + setFlip(true); + // construction is OK + *hRslt = S_OK; +} + +// destructor +VideoFFmpeg::~VideoFFmpeg () +{ +} + + +// release components +bool VideoFFmpeg::release() +{ + // release + if (m_codecCtx) + { + avcodec_close(m_codecCtx); + } + if (m_formatCtx) + { + av_close_input_file(m_formatCtx); + } + if (m_frame) + { + av_free(m_frame); + } + if (m_frameDeinterlaced) + { + MEM_freeN(m_frameDeinterlaced->data[0]); + av_free(m_frameDeinterlaced); + } + if (m_frameBGR) + { + MEM_freeN(m_frameBGR->data[0]); + av_free(m_frameBGR); + } + if (m_imgConvertCtx) + { + sws_freeContext(m_imgConvertCtx); + } + + m_codec = NULL; + m_codecCtx = NULL; + m_formatCtx = NULL; + m_frame = NULL; + m_frame = NULL; + m_frameBGR = NULL; + m_imgConvertCtx = NULL; + + // object will be deleted after that + return true; +} + + +// set initial parameters +void VideoFFmpeg::initParams (short width, short height, float rate) +{ + m_captWidth = width; + m_captHeight = height; + m_captRate = rate; +} + +int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams) +{ + AVFormatContext *formatCtx; + int i, videoStream; + AVCodec *codec; + AVCodecContext *codecCtx; + + if(av_open_input_file(&formatCtx, filename, inputFormat, 0, formatParams)!=0) + return -1; + + if(av_find_stream_info(formatCtx)<0) + { + av_close_input_file(formatCtx); + return -1; + } + + /* Find the first video stream */ + videoStream=-1; + for(i=0; inb_streams; i++) + { + if(formatCtx->streams[i] && + get_codec_from_stream(formatCtx->streams[i]) && + (get_codec_from_stream(formatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO)) + { + videoStream=i; + break; + } + } + + if(videoStream==-1) + { + av_close_input_file(formatCtx); + return -1; + } + + codecCtx = get_codec_from_stream(formatCtx->streams[videoStream]); + + /* Find the decoder for the video stream */ + codec=avcodec_find_decoder(codecCtx->codec_id); + if(codec==NULL) + { + av_close_input_file(formatCtx); + return -1; + } + codecCtx->workaround_bugs = 1; + if(avcodec_open(codecCtx, codec)<0) + { + av_close_input_file(formatCtx); + return -1; + } + +#ifdef FFMPEG_OLD_FRAME_RATE + if(codecCtx->frame_rate>1000 && codecCtx->frame_rate_base==1) + codecCtx->frame_rate_base=1000; + m_baseFrameRate = (double)codecCtx->frame_rate / (double)codecCtx->frame_rate_base; +#else + m_baseFrameRate = av_q2d(formatCtx->streams[videoStream]->r_frame_rate); +#endif + if (m_baseFrameRate <= 0.0) + m_baseFrameRate = defFrameRate; + + m_codec = codec; + m_codecCtx = codecCtx; + m_formatCtx = formatCtx; + m_videoStream = videoStream; + m_frame = avcodec_alloc_frame(); + m_frameDeinterlaced = avcodec_alloc_frame(); + m_frameBGR = avcodec_alloc_frame(); + + + // allocate buffer if deinterlacing is required + avpicture_fill((AVPicture*)m_frameDeinterlaced, + (uint8_t*)MEM_callocN(avpicture_get_size( + m_codecCtx->pix_fmt, + m_codecCtx->width, m_codecCtx->height), + "ffmpeg deinterlace"), + m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height); + + // allocate buffer to store final decoded frame + avpicture_fill((AVPicture*)m_frameBGR, + (uint8_t*)MEM_callocN(avpicture_get_size( + PIX_FMT_BGR24, + m_codecCtx->width, m_codecCtx->height), + "ffmpeg bgr"), + PIX_FMT_BGR24, m_codecCtx->width, m_codecCtx->height); + // allocate sws context + m_imgConvertCtx = sws_getContext( + m_codecCtx->width, + m_codecCtx->height, + m_codecCtx->pix_fmt, + m_codecCtx->width, + m_codecCtx->height, + PIX_FMT_BGR24, + SWS_FAST_BILINEAR, + NULL, NULL, NULL); + + if (!m_imgConvertCtx) { + avcodec_close(m_codecCtx); + av_close_input_file(m_formatCtx); + av_free(m_frame); + MEM_freeN(m_frameDeinterlaced->data[0]); + av_free(m_frameDeinterlaced); + MEM_freeN(m_frameBGR->data[0]); + av_free(m_frameBGR); + return -1; + } + return 0; +} + +// open video file +void VideoFFmpeg::openFile (char * filename) +{ + do_init_ffmpeg(); + + if (openStream(filename, NULL, NULL) != 0) + return; + + if (m_codecCtx->gop_size) + m_preseek = (m_codecCtx->gop_size < 25) ? m_codecCtx->gop_size+1 : 25; + else if (m_codecCtx->has_b_frames) + m_preseek = 25; // should determine gopsize + else + m_preseek = 0; + + // get video time range + m_range[0] = 0.0; + m_range[1] = (double)m_formatCtx->duration / AV_TIME_BASE; + + // open base class + VideoBase::openFile(filename); + + if (m_formatCtx->pb->is_streamed) + { + // the file is in fact a streaming source, prevent seeking + m_isFile = false; + // for streaming it is important to do non blocking read + m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK; + } +} + + +// open video capture device +void VideoFFmpeg::openCam (char * file, short camIdx) +{ + // open camera source + AVInputFormat *inputFormat; + AVFormatParameters formatParams; + AVRational frameRate; + char *p, filename[28], rateStr[20]; + + do_init_ffmpeg(); + + memset(&formatParams, 0, sizeof(formatParams)); +#ifdef WIN32 + // video capture on windows only through Video For Windows driver + inputFormat = av_find_input_format("vfwcap"); + if (!inputFormat) + // Video For Windows not supported?? + return; + sprintf(filename, "%d", camIdx); +#else + // In Linux we support two types of devices: VideoForLinux and DV1394. + // the user specify it with the filename: + // [][:] + // : 'v4l' for VideoForLinux, 'dv1394' for DV1394. By default 'v4l' + // : 'pal', 'secam' or 'ntsc'. By default 'ntsc' + // The driver name is constructed automatically from the device type: + // v4l : /dev/video + // dv1394: /dev/dv1394/ + // If you have different driver name, you can specify the driver name explicitely + // instead of device type. Examples of valid filename: + // /dev/v4l/video0:pal + // /dev/ieee1394/1:ntsc + // dv1394:secam + // v4l:pal + if (file && strstr(file, "1394") != NULL) + { + // the user specifies a driver, check if it is v4l or d41394 + inputFormat = av_find_input_format("dv1394"); + sprintf(filename, "/dev/dv1394/%d", camIdx); + } else + { + inputFormat = av_find_input_format("video4linux"); + sprintf(filename, "/dev/video%d", camIdx); + } + if (!inputFormat) + // these format should be supported, check ffmpeg compilation + return; + if (file && strncmp(file, "/dev", 4) == 0) + { + // user does not specify a driver + strncpy(filename, file, sizeof(filename)); + filename[sizeof(filename)-1] = 0; + if ((p = strchr(filename, ':')) != 0) + *p = 0; + } + if (file && (p = strchr(file, ":")) != NULL) + formatParams.standard = p+1; +#endif + //frame rate + if (m_captRate <= 0.f) + m_captRate = defFrameRate; + sprintf(rateStr, "%f", m_captRate); + av_parse_video_frame_rate(&frameRate, rateStr); + // populate format parameters + // need to specify the time base = inverse of rate + formatParams.time_base.num = frameRate.den; + formatParams.time_base.den = frameRate.num; + formatParams.width = m_captWidth; + formatParams.height = m_captHeight; + + if (openStream(filename, inputFormat, &formatParams) != 0) + return; + + // for video capture it is important to do non blocking read + m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK; + // open base class + VideoBase::openCam(file, camIdx); +} + + +// play video +bool VideoFFmpeg::play (void) +{ + try + { + // if object is able to play + if (VideoBase::play()) + { + // set video position + setPositions(); + // return success + return true; + } + } + CATCH_EXCP; + return false; +} + + +// stop video +bool VideoFFmpeg::stop (void) +{ + try + { + if (VideoBase::stop()) + { + return true; + } + } + CATCH_EXCP; + return false; +} + + +// set video range +void VideoFFmpeg::setRange (double start, double stop) +{ + try + { + // set range + VideoBase::setRange(start, stop); + // set range for video + setPositions(); + } + CATCH_EXCP; +} + +// set framerate +void VideoFFmpeg::setFrameRate (float rate) +{ + VideoBase::setFrameRate(rate); +} + + +// image calculation +void VideoFFmpeg::calcImage (unsigned int texId) +{ + loadFrame(); +} + + +// load frame from video +void VideoFFmpeg::loadFrame (void) +{ + // get actual time + double actTime = PIL_check_seconds_timer() - m_startTime; + // if video has ended + if (m_isFile && actTime * m_frameRate >= m_range[1]) + { + // if repeats are set, decrease them + if (m_repeat > 0) + --m_repeat; + // if video has to be replayed + if (m_repeat != 0) + { + // reset its position + actTime -= (m_range[1] - m_range[0]) / m_frameRate; + m_startTime += (m_range[1] - m_range[0]) / m_frameRate; + } + // if video has to be stopped, stop it + else + m_status = SourceStopped; + } + // if video is playing + if (m_status == SourcePlaying) + { + // actual frame + long actFrame = m_isFile ? long(actTime * actFrameRate()) : m_lastFrame + 1; + // if actual frame differs from last frame + if (actFrame != m_lastFrame) + { + // get image + if(grabFrame(actFrame)) + { + AVFrame* frame = getFrame(); + // save actual frame + m_lastFrame = actFrame; + // init image, if needed + init(short(m_codecCtx->width), short(m_codecCtx->height)); + // process image + process((BYTE*)(frame->data[0])); + } + } + } +} + + +// set actual position +void VideoFFmpeg::setPositions (void) +{ + // set video start time + m_startTime = PIL_check_seconds_timer(); + // if file is played and actual position is before end position + if (m_isFile && m_lastFrame >= 0 && m_lastFrame < m_range[1] * actFrameRate()) + // continue from actual position + m_startTime -= double(m_lastFrame) / actFrameRate(); + else + m_startTime -= m_range[0]; +} + +// position pointer in file, position in second +bool VideoFFmpeg::grabFrame(long position) +{ + AVPacket packet; + int frameFinished; + int posFound = 1; + bool frameLoaded = false; + long long targetTs = 0; + + // first check if the position that we are looking for is in the preseek range + // if so, just read the frame until we get there + if (position > m_curPosition + 1 + && m_preseek + && position - (m_curPosition + 1) < m_preseek) + { + while(av_read_frame(m_formatCtx, &packet)>=0) + { + if (packet.stream_index == m_videoStream) + { + avcodec_decode_video( + m_codecCtx, + m_frame, &frameFinished, + packet.data, packet.size); + if (frameFinished) + m_curPosition++; + } + av_free_packet(&packet); + if (position == m_curPosition+1) + break; + } + } + // if the position is not in preseek, do a direct jump + if (position != m_curPosition + 1) { + double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base); + long long pos = (long long) + ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate); + long long startTs = m_formatCtx->streams[m_videoStream]->start_time; + + if (pos < 0) + pos = 0; + + if (startTs != AV_NOPTS_VALUE) + pos += (long long)(startTs * AV_TIME_BASE * timeBase); + + av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD); + // current position is now lost, guess a value. + // It's not important because it will be set at this end of this function + m_curPosition = position - m_preseek - 1; + // this is the timestamp of the frame we're looking for + targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase); + if (startTs != AV_NOPTS_VALUE) + targetTs += startTs; + + posFound = 0; + avcodec_flush_buffers(m_codecCtx); + } + + while(av_read_frame(m_formatCtx, &packet)>=0) + { + if(packet.stream_index == m_videoStream) + { + avcodec_decode_video(m_codecCtx, + m_frame, &frameFinished, + packet.data, packet.size); + + if (frameFinished && !posFound) + { + if (packet.dts >= targetTs) + posFound = 1; + } + + if(frameFinished && posFound == 1) + { + AVFrame * input = m_frame; + + /* This means the data wasnt read properly, + this check stops crashing */ + if ( input->data[0]==0 && input->data[1]==0 + && input->data[2]==0 && input->data[3]==0) + { + av_free_packet(&packet); + break; + } + + if (m_deinterlace) + { + if (avpicture_deinterlace( + (AVPicture*) m_frameDeinterlaced, + (const AVPicture*) m_frame, + m_codecCtx->pix_fmt, + m_codecCtx->width, + m_codecCtx->height) >= 0) + { + input = m_frameDeinterlaced; + } + } + // convert to BGR24 + sws_scale(m_imgConvertCtx, + input->data, + input->linesize, + 0, + m_codecCtx->height, + m_frameBGR->data, + m_frameBGR->linesize); + av_free_packet(&packet); + frameLoaded = true; + break; + } + } + av_free_packet(&packet); + } + if (frameLoaded) + m_curPosition = position; + return frameLoaded; +} + + +// python methods + + +// cast Image pointer to VideoFFmpeg +inline VideoFFmpeg * getVideoFFmpeg (PyImage * self) +{ return static_cast(self->m_image); } + + +// object initialization +static int VideoFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + PyImage * self = reinterpret_cast(pySelf); + // parameters - video source + // file name or format type for capture (only for Linux: video4linux or dv1394) + char * file = NULL; + // capture device number + short capt = -1; + // capture width, only if capt is >= 0 + short width = 0; + // capture height, only if capt is >= 0 + short height = 0; + // capture rate, only if capt is >= 0 + float rate = 25.f; + + static char *kwlist[] = {"file", "capture", "rate", "width", "height", NULL}; + + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|hfhh", kwlist, &file, &capt, + &rate, &width, &height)) + return -1; + + try + { + // create video object + Video_init(self); + + // set thread usage + getVideoFFmpeg(self)->initParams(width, height, rate); + + // open video source + Video_open(getVideo(self), file, capt); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} + +PyObject * VideoFFmpeg_getPreseek (PyImage *self, void * closure) +{ + return Py_BuildValue("h", getFFmpeg(self)->getPreseek()); +} + +// set range +int VideoFFmpeg_setPreseek (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + if (value == NULL || !PyInt_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "The value must be an integer"); + return -1; + } + // set preseek + getFFmpeg(self)->setPreseek(PyInt_AsLong(value)); + // success + return 0; +} + +// get deinterlace +PyObject * VideoFFmpeg_getDeinterlace (PyImage * self, void * closure) +{ + if (getFFmpeg(self)->getDeinterlace()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +// set flip +int VideoFFmpeg_setDeinterlace (PyImage * self, PyObject * value, void * closure) +{ + // check parameter, report failure + if (value == NULL || !PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "The value must be a bool"); + return -1; + } + // set deinterlace + getFFmpeg(self)->setDeinterlace(value == Py_True); + // success + return 0; +} + +// methods structure +static PyMethodDef videoMethods[] = +{ // methods from VideoBase class + {"play", (PyCFunction)Video_play, METH_NOARGS, "Play video"}, + {"stop", (PyCFunction)Video_stop, METH_NOARGS, "Stop (pause) video"}, + {"refresh", (PyCFunction)Video_refresh, METH_NOARGS, "Refresh video - get its status"}, + {NULL} +}; +// attributes structure +static PyGetSetDef videoGetSets[] = +{ // methods from VideoBase class + {"status", (getter)Video_getStatus, NULL, "video status", NULL}, + {"range", (getter)Video_getRange, (setter)Video_setRange, "replay range", NULL}, + {"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, "repeat count, -1 for infinite repeat", NULL}, + {"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, "frame rate", NULL}, + // attributes from ImageBase class + {"image", (getter)Image_getImage, NULL, "image data", NULL}, + {"size", (getter)Image_getSize, NULL, "image size", NULL}, + {"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL}, + {"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL}, + {"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL}, + {"preseek", (getter)VideoFFmpeg_getPreseek, (setter)VideoFFmpeg_setPreseek, "nb of frames of preseek", NULL}, + {"deinterlace", (getter)VideoFFmpeg_getDeinterlace, (setter)VideoFFmpeg_setDeinterlace, "deinterlace image", NULL}, + {NULL} +}; + +// python type declaration +PyTypeObject VideoFFmpegType = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "VideoTexture.VideoFFmpeg", /*tp_name*/ + sizeof(PyImage), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Image_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "FFmpeg video source", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + videoMethods, /* tp_methods */ + 0, /* tp_members */ + videoGetSets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)VideoFFmpeg_init, /* tp_init */ + 0, /* tp_alloc */ + Image_allocNew, /* tp_new */ +}; + + + +#endif //WITH_FFMPEG + + diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h new file mode 100644 index 00000000000..7980e06686c --- /dev/null +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -0,0 +1,159 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of VideoTexture library + +Copyright (c) 2007 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ +#if !defined VIDEOFFMPEG_H +#define VIDEOFFMPEG_H + +#ifdef WITH_FFMPEG +extern "C" { +#include +#include +#include +#include +} + +#if LIBAVFORMAT_VERSION_INT < (49 << 16) +#define FFMPEG_OLD_FRAME_RATE 1 +#else +#define FFMPEG_CODEC_IS_POINTER 1 +#endif + +#ifdef FFMPEG_CODEC_IS_POINTER +static inline AVCodecContext* get_codec_from_stream(AVStream* stream) +{ + return stream->codec; +} +#else +static inline AVCodecContext* get_codec_from_stream(AVStream* stream) +{ + return &stream->codec; +} +#endif + +#include "VideoBase.h" + + +// type VideoFFmpeg declaration +class VideoFFmpeg : public VideoBase +{ +public: + /// constructor + VideoFFmpeg (HRESULT * hRslt); + /// destructor + virtual ~VideoFFmpeg (); + + /// set initial parameters + void initParams (short width, short height, float rate); + /// open video file + virtual void openFile (char * file); + /// open video capture device + virtual void openCam (char * driver, short camIdx); + + /// release video source + virtual bool release (void); + + /// play video + virtual bool play (void); + /// stop/pause video + virtual bool stop (void); + + /// set play range + virtual void setRange (double start, double stop); + /// set frame rate + virtual void setFrameRate (float rate); + // some specific getters and setters + int getPreseek(void) { return m_preseek; } + void setPreseek(int preseek) { if (preseek >= 0) m_preseek = preseek; } + bool getDeinterlace(void) { return m_deinterlace; } + void setDeinterlace(bool deinterlace) { m_deinterlace = deinterlace; } + +protected: + + // format and codec information + AVCodec *m_codec; + AVFormatContext *m_formatCtx; + AVCodecContext *m_codecCtx; + // raw frame extracted from video file + AVFrame *m_frame; + // deinterlaced frame if codec requires it + AVFrame *m_frameDeinterlaced; + // decoded RGB24 frame if codec requires it + AVFrame *m_frameBGR; + // conversion from raw to RGB is done with sws_scale + struct SwsContext *m_imgConvertCtx; + // should the codec be deinterlaced? + bool m_deinterlace; + // number of frame of preseek + int m_preseek; + // order number of stream holding the video in format context + int m_videoStream; + + // the actual frame rate + double m_baseFrameRate; + + /// last displayed frame + long m_lastFrame; + + /// current file pointer position in file expressed in frame number + long m_curPosition; + + /// time of video play start + double m_startTime; + + /// width of capture in pixel + short m_captWidth; + + /// height of capture in pixel + short m_captHeight; + + /// frame rate of capture in frames per seconds + float m_captRate; + + /// image calculation + virtual void calcImage (unsigned int texId); + + /// load frame from video + void loadFrame (void); + + /// set actual position + void setPositions (void); + + /// get actual framerate + double actFrameRate (void) { return m_frameRate * m_baseFrameRate; } + + /// common function to video file and capture + int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams); + + /// check if a frame is available and load it in pFrame, return true if a frame could be retrieved + bool grabFrame(long frame); + + /// return the frame in RGB24 format, the image data is found in AVFrame.data[0] + AVFrame* getFrame(void) { return m_frameBGR; } +}; + +inline VideoFFmpeg * getFFmpeg (PyImage * self) +{ + return static_cast(self->m_image); +} + +#endif //WITH_FFMPEG + +#endif diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp new file mode 100644 index 00000000000..0f15a26db2f --- /dev/null +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -0,0 +1,206 @@ +/* $Id$ +----------------------------------------------------------------------------- +This source file is part of VideoTexure library + +Copyright (c) 2006 The Zdeno Ash Miklas + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#define PY_ARRAY_UNIQUE_SYMBOL numpyPtr + +#include + +#include + +#include + +#include + +//Old API +//#include "TexPlayer.h" +//#include "TexImage.h" +//#include "TexFrameBuff.h" + +//#include "TexPlayerGL.h" + +#include "ImageBase.h" +#include "FilterBase.h" +#include "Texture.h" + +#include "Exception.h" + + +// get material id +static PyObject * getMaterialID (PyObject *self, PyObject *args) +{ + // parameters - game object with video texture + PyObject * obj = NULL; + // material name + char * matName; + + // get parameters + if (!PyArg_ParseTuple(args, "Os", &obj, &matName)) + return NULL; + // get material id + short matID = getMaterialID(obj, matName); + // if material was not found, report errot + if (matID < 0) + { + PyErr_SetString(PyExc_RuntimeError, "object doesn't have material with given name"); + return NULL; + } + // return material ID + return Py_BuildValue("h", matID); +} + + +// get last error description +static PyObject * getLastError (PyObject *self, PyObject *args) +{ + return Py_BuildValue("s", Exception::m_lastError.c_str()); +} + +// set log file +static PyObject * setLogFile (PyObject *self, PyObject *args) +{ + // get parameters + if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile)) + return Py_BuildValue("i", -1); + // log file was loaded + return Py_BuildValue("i", 0); +} + + +// function to initialize numpy structures +static bool initNumpy (void) +{ + // init module and report failure + import_array1(false); + // report success + return true; +} + +// image to numpy array +static PyObject * imageToArray (PyObject * self, PyObject *args) +{ + // parameter is Image object + PyObject * pyImg; + if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type)) + { + // if object is incorect, report error + PyErr_SetString(PyExc_TypeError, "The value must be a image source object"); + return NULL; + } + // get image structure + PyImage * img = reinterpret_cast(pyImg); + // check initialization of numpy interface, and initialize it if needed + if (numpyPtr == NULL && !initNumpy()) Py_RETURN_NONE; + // create array object + npy_intp dim[1]; + dim[0] = img->m_image->getBuffSize() / sizeof(unsigned int); + unsigned int * imgBuff = img->m_image->getImage(); + // if image is available, convert it to array + if (imgBuff != NULL) + return PyArray_SimpleNewFromData(1, dim, NPY_UBYTE, imgBuff); + // otherwise return None + Py_RETURN_NONE; +} + + +// metody modulu +static PyMethodDef moduleMethods[] = +{ + {"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"}, + {"getLastError", getLastError, METH_NOARGS, "Gets last error description"}, + {"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"}, + {"imageToArray", imageToArray, METH_VARARGS, "get array from image source"}, + {NULL} /* Sentinel */ +}; + +#if WITH_FFMPEG +extern PyTypeObject VideoFFmpegType; +#endif +extern PyTypeObject FilterBlueScreenType; +extern PyTypeObject FilterGrayType; +extern PyTypeObject FilterColorType; +extern PyTypeObject FilterLevelType; +extern PyTypeObject FilterNormalType; +extern PyTypeObject FilterRGB24Type; +extern PyTypeObject FilterBGR24Type; +extern PyTypeObject ImageBuffType; +extern PyTypeObject ImageMixType; +extern PyTypeObject ImageRenderType; +extern PyTypeObject ImageViewportType; +extern PyTypeObject ImageViewportType; + + +static void registerAllTypes(void) +{ +#if WITH_FFMPEG + pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg"); +#endif + pyImageTypes.add(&ImageBuffType, "ImageBuff"); + pyImageTypes.add(&ImageMixType, "ImageMix"); + //pyImageTypes.add(&ImageRenderType, "ImageRender"); + pyImageTypes.add(&ImageViewportType, "ImageViewport"); + + pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen"); + pyFilterTypes.add(&FilterGrayType, "FilterGray"); + pyFilterTypes.add(&FilterColorType, "FilterColor"); + pyFilterTypes.add(&FilterLevelType, "FilterLevel"); + pyFilterTypes.add(&FilterNormalType, "FilterNormal"); + pyFilterTypes.add(&FilterRGB24Type, "FilterRGB24"); + pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24"); +} + +PyObject* initVideoTexture(void) +{ + // initialize GL extensions + //bgl::InitExtensions(0); + + // prepare classes + registerAllTypes(); + + if (!pyImageTypes.ready()) + return NULL; + if (!pyFilterTypes.ready()) + return NULL; + if (PyType_Ready(&TextureType) < 0) + return NULL; + + PyObject * m = Py_InitModule4("VideoTexture", moduleMethods, + "Module that allows to play video files on textures in GameBlender.", + (PyObject*)NULL,PYTHON_API_VERSION); + if (m == NULL) + return NULL; + + // prepare numpy array + numpyPtr = NULL; + + // initialize classes + pyImageTypes.reg(m); + pyFilterTypes.reg(m); + + Py_INCREF(&TextureType); + PyModule_AddObject(m, "Texture", (PyObject*)&TextureType); + + // init last error description + Exception::m_lastError[0] = '\0'; + return m; +} + +// registration to Image types, put here because of silly linker bug From 48fb0edc7811a7018f4c78cc998eab3274f4e1e9 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 11:15:13 +0000 Subject: [PATCH 09/51] Fix Cmake for MSVC 32bit --- source/gameengine/VideoTexture/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt index fbae66e0ef4..1674602edd7 100644 --- a/source/gameengine/VideoTexture/CMakeLists.txt +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -54,6 +54,7 @@ SET(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}") From b590b121d354ca1352191f56aa66d0c2ee494fb4 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Sat, 1 Nov 2008 11:35:08 +0000 Subject: [PATCH 10/51] fix a bug in matrix.invert() for 2x2 matrices reported by Hans in http://blenderartists.org/forum/showthread.php?t=139748 --- source/blender/python/api2_2x/matrix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index 79ca5e09b25..7802de822cb 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -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); From 54401d36aadabe38decd9cd64f1385e1757bd303 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 12:48:46 +0000 Subject: [PATCH 11/51] BGE Video Texture: fix constant initializer problem with Exception description. Uniformized the line ending. --- source/gameengine/VideoTexture/Exception.cpp | 13 ++++++++++++- source/gameengine/VideoTexture/Exception.h | 15 +++++++++++++++ source/gameengine/VideoTexture/ImageMix.cpp | 4 ++-- source/gameengine/VideoTexture/ImageRender.cpp | 10 +++++++--- source/gameengine/VideoTexture/Texture.cpp | 4 ++-- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 2 +- source/gameengine/VideoTexture/blendVideoTex.cpp | 1 + 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index a326430b27a..c576cebddc8 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -44,7 +44,6 @@ ExpDesc errNFoundDesc (ErrNotFound, "Error description not found"); ExpDesc::ExpDesc (ExceptionID & exp, char * desc, RESULT hres) : m_expID(exp), m_hRslt(hres), m_description(desc) { - m_expDescs.push_back(this); } // destructor @@ -196,3 +195,15 @@ void Exception::copy (const Exception & xpt) 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 index 85865fb3654..5345e87f199 100644 --- a/source/gameengine/VideoTexture/Exception.h +++ b/source/gameengine/VideoTexture/Exception.h @@ -27,6 +27,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include #include +#include #include "Common.h" @@ -117,6 +118,11 @@ public: 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 m_expDescs; @@ -192,4 +198,13 @@ protected: }; +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/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index 56503066161..71250005129 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -58,9 +58,9 @@ bool ImageMix::setWeight (const char * id, short weight) return true; } -static ExceptionID ImageSizesNotMatch; +ExceptionID ImageSizesNotMatch; -static ExpDesc ImageSizesNotMatchDesc (ImageSizesNotMatch, "Image sizes of sources are different"); +ExpDesc ImageSizesNotMatchDesc (ImageSizesNotMatch, "Image sizes of sources are different"); // calculate image from sources and set its availability void ImageMix::calcImage (unsigned int texId) diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index c800b92e71d..ce27a24d35a 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -94,6 +94,10 @@ void ImageRender::calcImage (unsigned int texId) ImageViewport::calcImage(texId); } +void ImageRender::Render() +{ + // +} // refresh lights void ImageRender::refreshLights (void) @@ -120,9 +124,9 @@ BlendType sceneType ("KX_Scene"); BlendType cameraType ("KX_Camera"); -static ExceptionID SceneInvalid, CameraInvalid; -static ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid"); -static ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid"); +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) diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index d208802675c..243c5f31db0 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -165,8 +165,8 @@ void Texture_dealloc (Texture * self) } -static ExceptionID MaterialNotAvail; -static ExpDesc MaterialNotAvailDesc (MaterialNotAvail, "Texture material is not available"); +ExceptionID MaterialNotAvail; +ExpDesc MaterialNotAvailDesc (MaterialNotAvail, "Texture material is not available"); // Texture object initialization int Texture_init (Texture *self, PyObject *args, PyObject *kwds) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index b12bad4b416..65bd5f4cbf4 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -265,7 +265,7 @@ void VideoFFmpeg::openCam (char * file, short camIdx) AVInputFormat *inputFormat; AVFormatParameters formatParams; AVRational frameRate; - char *p, filename[28], rateStr[20]; + char filename[28], rateStr[20]; do_init_ffmpeg(); diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 0f15a26db2f..d08762b1d7c 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -174,6 +174,7 @@ PyObject* initVideoTexture(void) // prepare classes registerAllTypes(); + registerAllExceptions(); if (!pyImageTypes.ready()) return NULL; From 00b02f055ae7e649d17ce6fc6a8dafe6138d3743 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 1 Nov 2008 14:00:16 +0000 Subject: [PATCH 12/51] Patch 17909: 2D Filter texture coordinates changes, by Dalai Felinto: * The second opengl texture coordinate (gl_TexCoord[1]) are now filled in as well, and will give canvas coordinates from 0.0 to 1.0. The first texture coordinates still give the coordinates in the texture that is being used, which may not match the canvas exactly, so both coordinates are needed. * Also optimization to allow using smaller texture sizes with multiple smaller viewports. * Print the detailed GLSL shader errors (once), for easier debugging. --- .../Rasterizer/RAS_2DFilterManager.cpp | 179 +++++++++++------- .../Rasterizer/RAS_2DFilterManager.h | 2 + 2 files changed, 110 insertions(+), 71 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 6e5553d4781..d2cfa7d07f9 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -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); - return program; + 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; } 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& propNames) + +void RAS_2DFilterManager::AnalyseShader(int passindex, vector& 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(); } } diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h index c16bd41dd0e..454643a5077 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h @@ -38,6 +38,7 @@ private: void AnalyseShader(int passindex, vector& 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]; From 5cb16c2d031dabe72ef5ea4adf8b1551f124e3e6 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 15:42:03 +0000 Subject: [PATCH 13/51] Video Texture: remove support for capture device, the linux ffmpeg repository is not ready yet. --- source/blender/imbuf/intern/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 70a02d72b01..cd58d9e4e96 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -64,7 +64,7 @@ #ifdef WITH_FFMPEG #include #include -#include +//#include #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -237,7 +237,7 @@ void do_init_ffmpeg() if (!ffmpeg_init) { ffmpeg_init = 1; av_register_all(); - avdevice_register_all(); + //avdevice_register_all(); } } From bd81d96b78bf0b53128d13ac8655a0397405e403 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 15:58:49 +0000 Subject: [PATCH 14/51] Video Texture: missing newlines at the end of several files. --- source/gameengine/VideoTexture/FilterBase.h | 2 +- source/gameengine/VideoTexture/FilterBlueScreen.h | 2 +- source/gameengine/VideoTexture/FilterColor.h | 2 +- source/gameengine/VideoTexture/FilterNormal.h | 2 +- source/gameengine/VideoTexture/FilterSource.h | 2 +- source/gameengine/VideoTexture/ImageBase.cpp | 2 +- source/gameengine/VideoTexture/ImageBase.h | 2 +- source/gameengine/VideoTexture/PyTypeList.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h index fa6f9a754d4..1c9a2b46927 100644 --- a/source/gameengine/VideoTexture/FilterBase.h +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -129,4 +129,4 @@ PyObject * Filter_getPrevious (PyFilter * self, void * closure); int Filter_setPrevious (PyFilter * self, PyObject * value, void * closure); -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h index 1871fbc0516..20660804f78 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.h +++ b/source/gameengine/VideoTexture/FilterBlueScreen.h @@ -95,4 +95,4 @@ protected: }; -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h index 4465df97340..ae2e98fa942 100644 --- a/source/gameengine/VideoTexture/FilterColor.h +++ b/source/gameengine/VideoTexture/FilterColor.h @@ -161,4 +161,4 @@ protected: }; -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h index fa61f04c0b7..ec51ca39db9 100644 --- a/source/gameengine/VideoTexture/FilterNormal.h +++ b/source/gameengine/VideoTexture/FilterNormal.h @@ -95,4 +95,4 @@ protected: }; -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index b18186210dc..7bed5c77a4d 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -230,4 +230,4 @@ protected: }; -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index 28e7ad49224..d2e980d979a 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -526,4 +526,4 @@ int Image_setFilter (PyImage * self, PyObject * value, void * closure) } // return success return 0; -} \ No newline at end of file +} diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h index 817223c3d31..2b923a06ee3 100644 --- a/source/gameengine/VideoTexture/ImageBase.h +++ b/source/gameengine/VideoTexture/ImageBase.h @@ -346,4 +346,4 @@ PyObject * Image_getFilter (PyImage * self, void * closure); int Image_setFilter (PyImage * self, PyObject * value, void * closure); -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/VideoTexture/PyTypeList.h b/source/gameengine/VideoTexture/PyTypeList.h index 7069cf8bb43..736fc9aaefd 100644 --- a/source/gameengine/VideoTexture/PyTypeList.h +++ b/source/gameengine/VideoTexture/PyTypeList.h @@ -82,4 +82,4 @@ protected: }; -#endif \ No newline at end of file +#endif From 0aff409d54720f2263c1b13f115409185e1f5f91 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 1 Nov 2008 16:09:36 +0000 Subject: [PATCH 15/51] Bugfix #17913 Bah... fix for envmaps just before 2.48 release gave good looking envmaps only when there was no sky involved... The alpha in environment maps should be reset to 255... something that was never done before, but also didn't show errors until other fixes in image rendering were done. --- source/blender/render/intern/source/envmap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index d281ac9e5c8..13fa9b17b71 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -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; } From 58d0dc21aa853ee9b6c70547c06ae64739a9f4b5 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 1 Nov 2008 17:06:36 +0000 Subject: [PATCH 16/51] Getting video texture closer to compiling under linux --- source/gameengine/VideoTexture/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index e0972e045cc..f3fe0dab6ad 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -20,7 +20,6 @@ defs = '' if env['OURPLATFORM'] == 'win32-vc': cflags.append('/GR') cflags.append('/Ox') - defs += ' __STDC_CONSTANT_MACROS' incs += ' ' + env['BF_PYTHON_INC'] #incs += ' ' + env['BF_OPENGL_INC'] @@ -28,5 +27,6 @@ incs += ' ' + env['BF_PYTHON_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 ) From 4870db578b8a08a58ae6e553094c3998a92fcb7e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 1 Nov 2008 17:07:24 +0000 Subject: [PATCH 17/51] Bug #17912: fix for some SSS floating point precision issues, and also fix a divide by zero in the subsurf code found in the process. --- source/blender/blenkernel/intern/CCGSubSurf.c | 16 ++++++++----- source/blender/render/intern/source/sss.c | 24 +++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index ce4458b4307..cee032f364e 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -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) diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 9fb48a08503..9bde6675798 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -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; From e6a2ab319f10fa318aa4d9b4e7c5cef0fd95dc87 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 17:15:17 +0000 Subject: [PATCH 18/51] VideoTexture: AVFormatContext::pb is not a pointer for avformat library older than 52 (linux uses 51) --- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 10 ++++++++-- source/gameengine/VideoTexture/VideoFFmpeg.h | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 65bd5f4cbf4..19e10cf02f8 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -248,7 +248,13 @@ void VideoFFmpeg::openFile (char * filename) // open base class VideoBase::openFile(filename); - if (m_formatCtx->pb->is_streamed) + if ( +#ifdef FFMPEG_PB_IS_POINTER + m_formatCtx->pb->is_streamed +#else + m_formatCtx->pb.is_streamed +#endif + ) { // the file is in fact a streaming source, prevent seeking m_isFile = false; @@ -265,7 +271,7 @@ void VideoFFmpeg::openCam (char * file, short camIdx) AVInputFormat *inputFormat; AVFormatParameters formatParams; AVRational frameRate; - char filename[28], rateStr[20]; + char *p, filename[28], rateStr[20]; do_init_ffmpeg(); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 7980e06686c..4720bef1841 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -36,6 +36,10 @@ extern "C" { #define FFMPEG_CODEC_IS_POINTER 1 #endif +#if LIBAVFORMAT_VERSION_INT >= (52 << 16) +#define FFMPEG_PB_IS_POINTER 1 +#endif + #ifdef FFMPEG_CODEC_IS_POINTER static inline AVCodecContext* get_codec_from_stream(AVStream* stream) { From 19cdef1f71ca862254d10ae33500dc24c35d2477 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 17:26:34 +0000 Subject: [PATCH 19/51] VideoTexture: typo in linux code --- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 19e10cf02f8..272d2695c4b 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -319,7 +319,7 @@ void VideoFFmpeg::openCam (char * file, short camIdx) if ((p = strchr(filename, ':')) != 0) *p = 0; } - if (file && (p = strchr(file, ":")) != NULL) + if (file && (p = strchr(file, ':')) != NULL) formatParams.standard = p+1; #endif //frame rate From b24c6ef70d4c6aa5b4e8539362eaa826b86343e2 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 1 Nov 2008 17:44:12 +0000 Subject: [PATCH 20/51] Adding include path for numpy to sconscript. There must be a better way to do this. --- source/gameengine/VideoTexture/SConscript | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index f3fe0dab6ad..bf8d7c133ff 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -21,6 +21,7 @@ if env['OURPLATFORM'] == 'win32-vc': cflags.append('/GR') cflags.append('/Ox') +incs += ' ' + env['BF_PYTHON'] + '/lib/python' + env['BF_PYTHON_VERSION'] + "/site-packages/numpy/core/include" incs += ' ' + env['BF_PYTHON_INC'] #incs += ' ' + env['BF_OPENGL_INC'] From e72d6c7bfaee29c0a1c360237299484ca5caaeb7 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 20:18:15 +0000 Subject: [PATCH 21/51] VideoTexture: fix NULL pointer crash when material name is not found. --- source/gameengine/VideoTexture/Texture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index 243c5f31db0..ea3f60b2775 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -96,7 +96,7 @@ RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID) // get material from mesh RAS_MeshObject * mesh = gameObj->GetMesh(0); RAS_MeshMaterial *meshMat = mesh->GetMeshMaterial(matID); - if (meshMat->m_bucket != NULL) + if (meshMat != NULL && meshMat->m_bucket != NULL) // return pointer to polygon or blender material return meshMat->m_bucket->GetPolyMaterial(); } From 68f50e0c6b147d9603d151d99f5085c09c0ce039 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 1 Nov 2008 22:28:27 +0000 Subject: [PATCH 22/51] VideoTexture: remove numpy dependency. --- .../gameengine/VideoTexture/blendVideoTex.cpp | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index d08762b1d7c..7f55024fe4c 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -20,16 +20,12 @@ http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ -#define PY_ARRAY_UNIQUE_SYMBOL numpyPtr - #include #include #include -#include - //Old API //#include "TexPlayer.h" //#include "TexImage.h" @@ -85,15 +81,6 @@ static PyObject * setLogFile (PyObject *self, PyObject *args) } -// function to initialize numpy structures -static bool initNumpy (void) -{ - // init module and report failure - import_array1(false); - // report success - return true; -} - // image to numpy array static PyObject * imageToArray (PyObject * self, PyObject *args) { @@ -107,15 +94,14 @@ static PyObject * imageToArray (PyObject * self, PyObject *args) } // get image structure PyImage * img = reinterpret_cast(pyImg); - // check initialization of numpy interface, and initialize it if needed - if (numpyPtr == NULL && !initNumpy()) Py_RETURN_NONE; // create array object - npy_intp dim[1]; - dim[0] = img->m_image->getBuffSize() / sizeof(unsigned int); unsigned int * imgBuff = img->m_image->getImage(); // if image is available, convert it to array if (imgBuff != NULL) - return PyArray_SimpleNewFromData(1, dim, NPY_UBYTE, imgBuff); + // Nasty problem here: the image buffer is an array of integers + // in the processor endian format. The user must take care of that in the script. + // Need to find an elegant solution to this problem + return Py_BuildValue("s#", imgBuff, img->m_image->getBuffSize()); // otherwise return None Py_RETURN_NONE; } @@ -189,9 +175,6 @@ PyObject* initVideoTexture(void) if (m == NULL) return NULL; - // prepare numpy array - numpyPtr = NULL; - // initialize classes pyImageTypes.reg(m); pyFilterTypes.reg(m); From a4f8f06479a962e52240ec4c7e3dd28b0213d691 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 2 Nov 2008 00:25:39 +0000 Subject: [PATCH 23/51] Fix for two proxy + undo related crashes: * When making a proxy, the lib linked IPO driver was also changed to point to the proxy object, and after undo this local proxy object was replaced so the pointer became invalid. In fact it is not needed at all to change this because the IPO code maps the pointer to the local proxy object already. * Undoing the make proxy operation would crash because the proxy_from pointer in the library linked object would still point to the removed object. Now it clears all these pointers before undo, because on each undo memory file read they will be set again anyway. --- source/blender/blenkernel/intern/object.c | 5 ++++- source/blender/blenloader/intern/readblenentry.c | 3 +++ source/blender/blenloader/intern/readfile.c | 13 +++++++++++++ source/blender/blenloader/intern/readfile.h | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 77c891ee82e..a25afeafaef 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 5a75b5c8b11..e4bc6e3abb2 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -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 */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3a9d0a6ae6a..acedf51e619 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) { diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 7ddb1e361da..8547a4d9652 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -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); From 30016909c72924c882a4fd1c233d799d552cb33c Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 2 Nov 2008 12:27:25 +0000 Subject: [PATCH 24/51] Bugfix #17920 When entering a wrong expression (or garbish) in a Nkey panel button, the cursor jumps to the place where the button was clicked. On failure the button could return a B_NOP, not a 0 --- source/blender/src/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 9decbd9a1ce..7417218f253 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -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); From 752920c53196585219cd50ee38f05bee0a885092 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 2 Nov 2008 12:50:11 +0000 Subject: [PATCH 25/51] python25.zip wasn't copied using cmake. Should fix win64 python e.g. "import random" problem --- source/creator/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index e84d1aac3a7..efeff572c74 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -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) From fdc1ef2c256748458254b23db43b5cca64dbef00 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 2 Nov 2008 14:03:47 +0000 Subject: [PATCH 26/51] Bugfix #17902 Black dots appearing in mirroring 3d beveled curves, when using orco texture coords. Appeared there was memory read just outside of the allocation. --- source/blender/blenkernel/intern/curve.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index b090ac2b538..1a671dfe771 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -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]; From 12b2f1c83c09ff75cf0987909f23523a071922a7 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 2 Nov 2008 14:36:32 +0000 Subject: [PATCH 27/51] Include path for numpy no longer needed. --- source/gameengine/VideoTexture/SConscript | 1 - 1 file changed, 1 deletion(-) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index bf8d7c133ff..f3fe0dab6ad 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -21,7 +21,6 @@ if env['OURPLATFORM'] == 'win32-vc': cflags.append('/GR') cflags.append('/Ox') -incs += ' ' + env['BF_PYTHON'] + '/lib/python' + env['BF_PYTHON_VERSION'] + "/site-packages/numpy/core/include" incs += ' ' + env['BF_PYTHON_INC'] #incs += ' ' + env['BF_OPENGL_INC'] From 407e38a7447a5c55aea4c9b8f4a3eebca26c687e Mon Sep 17 00:00:00 2001 From: Enrico Fracasso Date: Sun, 2 Nov 2008 14:54:44 +0000 Subject: [PATCH 28/51] Added bf_videotex to unix libraries (linking error) --- source/creator/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index efeff572c74..ee6f19e457d 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -266,7 +266,8 @@ IF(UNIX) blender_python bf_quicktime extern_binreloc - extern_glew + extern_glew + bf_videotex ) FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) From 719e30f70a2ab2de5c72e1ee5d9ccb42d3d83b8c Mon Sep 17 00:00:00 2001 From: Enrico Fracasso Date: Sun, 2 Nov 2008 15:16:17 +0000 Subject: [PATCH 29/51] Disable completely OpenAL if WITH_OPENAL is OFF --- CMakeLists.txt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f2311af98..e01a37d3b3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 From f180702a12de6ae1ce31e5c386b27bd1f39ef96b Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 2 Nov 2008 16:28:34 +0000 Subject: [PATCH 30/51] Quiet ffmpeg log by default. No more ugly stream info in console. Starting Blender with -d turns info logging back on. --- source/blender/blenkernel/BKE_writeffmpeg.h | 2 ++ source/blender/blenkernel/intern/writeffmpeg.c | 13 +++++++++++++ source/blender/imbuf/intern/util.c | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 02f7ba6f860..50053446294 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -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 diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index cef6f802729..642b4fd1b19 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -34,6 +34,7 @@ #include #include #include +#include #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) diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index cd58d9e4e96..05d594019a5 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -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" @@ -238,6 +239,11 @@ void do_init_ffmpeg() ffmpeg_init = 1; av_register_all(); //avdevice_register_all(); + + if ((G.f & G_DEBUG) == 0) + { + silence_log_ffmpeg(1); + } } } From 2973bd8ea27c83274669051297ee470723dfcf9d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 2 Nov 2008 18:02:31 +0000 Subject: [PATCH 31/51] VideoTexture: use PyObjectPlus.h instead of Python.h for compatibility with Python2.3 --- source/gameengine/VideoTexture/Exception.cpp | 2 +- source/gameengine/VideoTexture/FilterBase.cpp | 2 +- source/gameengine/VideoTexture/FilterBase.h | 2 +- source/gameengine/VideoTexture/FilterBlueScreen.cpp | 2 +- source/gameengine/VideoTexture/FilterColor.cpp | 2 +- source/gameengine/VideoTexture/FilterNormal.cpp | 2 +- source/gameengine/VideoTexture/FilterSource.cpp | 2 +- source/gameengine/VideoTexture/FilterSource.h | 2 -- source/gameengine/VideoTexture/ImageBase.cpp | 2 +- source/gameengine/VideoTexture/ImageBase.h | 2 +- source/gameengine/VideoTexture/ImageBuff.cpp | 2 +- source/gameengine/VideoTexture/ImageMix.cpp | 2 +- source/gameengine/VideoTexture/ImageRender.cpp | 2 +- source/gameengine/VideoTexture/ImageViewport.cpp | 2 +- source/gameengine/VideoTexture/PyTypeList.cpp | 2 +- source/gameengine/VideoTexture/PyTypeList.h | 2 +- source/gameengine/VideoTexture/Texture.cpp | 2 +- source/gameengine/VideoTexture/Texture.h | 2 +- source/gameengine/VideoTexture/VideoBase.h | 2 +- source/gameengine/VideoTexture/blendVideoTex.cpp | 2 +- 20 files changed, 19 insertions(+), 21 deletions(-) diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index c576cebddc8..3ac8b8e321d 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -24,7 +24,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include -#include +#include #include "Exception.h" diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp index 078a096aff7..b0112cd355b 100644 --- a/source/gameengine/VideoTexture/FilterBase.cpp +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include "FilterBase.h" -#include +#include #include diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h index 1c9a2b46927..c530e385ada 100644 --- a/source/gameengine/VideoTexture/FilterBase.h +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -25,7 +25,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include "Common.h" -#include +#include #include "PyTypeList.h" diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index d911b1d7743..50c3a87ffc4 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -21,7 +21,7 @@ http://www.gnu.org/copyleft/lesser.txt. */ -#include +#include #include #include "FilterBlueScreen.h" diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index c45804caf9d..a1ddf581aef 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -21,7 +21,7 @@ http://www.gnu.org/copyleft/lesser.txt. */ -#include +#include #include #include "FilterColor.h" diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 5eeb63b7128..514214bec8b 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -21,7 +21,7 @@ http://www.gnu.org/copyleft/lesser.txt. */ -#include +#include #include #include "FilterNormal.h" diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp index 4b96a9792e2..8d8749dbc8f 100644 --- a/source/gameengine/VideoTexture/FilterSource.cpp +++ b/source/gameengine/VideoTexture/FilterSource.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include "FilterSource.h" diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index 7bed5c77a4d..c3d4e0079f9 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -47,7 +47,6 @@ protected: { return 0xFF000000 | src[0] << 16 | src[1] << 8 | src[2]; } }; - /// class for BGR24 conversion class FilterBGR24 : public FilterBase { @@ -67,7 +66,6 @@ protected: { return 0xFF000000 | src[2] << 16 | src[1] << 8 | src[0]; } }; - /// class for YV12 conversion class FilterYV12 : public FilterBase { diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index d2e980d979a..dcca20de24a 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -25,7 +25,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include -#include +#include #include #include "FilterBase.h" diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h index 2b923a06ee3..138580ce701 100644 --- a/source/gameengine/VideoTexture/ImageBase.h +++ b/source/gameengine/VideoTexture/ImageBase.h @@ -26,7 +26,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include "Common.h" #include -#include +#include #include "PyTypeList.h" diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index f09514a36f0..a0c6e1f6f74 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include "ImageBuff.h" diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index 71250005129..8532249f7d8 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include "ImageMix.h" diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index ce27a24d35a..fb284261d70 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index e1d3316a43e..e2b4e469e80 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include "ImageViewport.h" diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp index b8c40052e81..0451d74c8ad 100644 --- a/source/gameengine/VideoTexture/PyTypeList.cpp +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -26,7 +26,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include -#include +#include /// check, if type is in list diff --git a/source/gameengine/VideoTexture/PyTypeList.h b/source/gameengine/VideoTexture/PyTypeList.h index 736fc9aaefd..4daf88bfa19 100644 --- a/source/gameengine/VideoTexture/PyTypeList.h +++ b/source/gameengine/VideoTexture/PyTypeList.h @@ -28,7 +28,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include -#include +#include // forward declaration class PyTypeListItem; diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index ea3f60b2775..ceda39aeff4 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -22,7 +22,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation -#include +#include #include #include diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index f19f8da607d..569e34da121 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -23,7 +23,7 @@ http://www.gnu.org/copyleft/lesser.txt. #if !defined TEXTURE_H #define TEXTURE_H -#include +#include #include #include diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 78e8ba65909..5bb635e1f19 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -24,7 +24,7 @@ http://www.gnu.org/copyleft/lesser.txt. #define VIDEOBASE_H -#include +#include #include "ImageBase.h" diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 7f55024fe4c..629b589c0e6 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -20,7 +20,7 @@ http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ -#include +#include #include From a775719e23aecfd09accff61d16ba59514538416 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 2 Nov 2008 18:05:11 +0000 Subject: [PATCH 32/51] Bugfix #17942 Python dict error: when trying to access a Bone via a key, and the key was not found, a wrong error message got printed. Fix provided by reporter Gregor Riepl. Thanks! --- source/blender/python/api2_2x/Armature.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index aa3ef82a3e8..99a4398ec89 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -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]; From db24487449b1340eed2f29394fdbcdf2e7acc3ea Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 2 Nov 2008 18:12:45 +0000 Subject: [PATCH 33/51] Makefile fixes for compiling with new videotexture code. Also: buttons for logic, controllers, didn't line up correct when multiple objects were selected (too little space) --- source/Makefile | 1 + source/blender/src/buttons_logic.c | 2 +- source/gameengine/Makefile | 2 +- source/nan_compile.mk | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/Makefile b/source/Makefile index 99155206987..558a844eca7 100644 --- a/source/Makefile +++ b/source/Makefile @@ -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 diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 0dcdc36fdcd..8aca111f41f 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -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. diff --git a/source/gameengine/Makefile b/source/gameengine/Makefile index 1d3bc8c2058..51bc0f7d39f 100644 --- a/source/gameengine/Makefile +++ b/source/gameengine/Makefile @@ -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 diff --git a/source/nan_compile.mk b/source/nan_compile.mk index 151c741e8b4..4b13ef8f678 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -89,8 +89,8 @@ ifeq ($(OS),darwin) CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing endif - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 +# REL_CFLAGS += -O2 +# REL_CCFLAGS += -O2 CPPFLAGS += -D_THREAD_SAFE NAN_DEPEND = true OPENGL_HEADERS = /System/Library/Frameworks/OpenGL.framework From 7d63f5a7fe7378f9bea9e39282828f74bba47287 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 2 Nov 2008 18:31:54 +0000 Subject: [PATCH 34/51] VideoTexture: fix compile error with GLint in ImageViewport under osx. --- source/gameengine/VideoTexture/ImageViewport.cpp | 11 +++++------ source/gameengine/VideoTexture/ImageViewport.h | 12 ++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index e2b4e469e80..59995198ba1 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -25,13 +25,12 @@ http://www.gnu.org/copyleft/lesser.txt. #include #include -#include "ImageViewport.h" - #include #include "Texture.h" #include "ImageBase.h" #include "FilterSource.h" +#include "ImageViewport.h" // constructor @@ -81,7 +80,7 @@ void ImageViewport::setCaptureSize (short * size) if (size[idx] < 1) m_capSize[idx] = 1; else if (size[idx] > getViewportSize()[idx]) - m_capSize[idx] = getViewportSize()[idx]; + m_capSize[idx] = short(getViewportSize()[idx]); else m_capSize[idx] = size[idx]; } @@ -91,7 +90,7 @@ void ImageViewport::setCaptureSize (short * size) } // set position of capture rectangle -void ImageViewport::setPosition (int * pos) +void ImageViewport::setPosition (GLint * pos) { // if new position is not provided, use existing position if (pos == NULL) pos = m_position; @@ -125,7 +124,7 @@ void ImageViewport::calcImage (unsigned int texId) { // just copy current viewport to texture glBindTexture(GL_TEXTURE_2D, texId); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1]); + 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; } @@ -133,7 +132,7 @@ void ImageViewport::calcImage (unsigned int texId) else if (!m_avail) { // get frame buffer data - glReadPixels(m_upLeft[0], m_upLeft[1], m_capSize[0], m_capSize[1], GL_RGB, + 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; diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h index 9fd3aeb7ba9..4265906b8f5 100644 --- a/source/gameengine/VideoTexture/ImageViewport.h +++ b/source/gameengine/VideoTexture/ImageViewport.h @@ -49,13 +49,13 @@ public: void setCaptureSize (short * size = NULL); /// get position in viewport - int * getPosition (void) { return m_position; } + GLint * getPosition (void) { return m_position; } /// set position in viewport - void setPosition (int * pos = NULL); + void setPosition (GLint * pos = NULL); protected: /// frame buffer rectangle - int m_viewport[4]; + GLint m_viewport[4]; /// size of captured area short m_capSize[2]; @@ -63,9 +63,9 @@ protected: bool m_whole; /// position of capture rectangle in viewport - int m_position[2]; + GLint m_position[2]; /// upper left point for capturing - int m_upLeft[2]; + GLint m_upLeft[2]; /// buffer to copy viewport BYTE * m_viewportImage; @@ -76,7 +76,7 @@ protected: virtual void calcImage (unsigned int texId); /// get viewport size - int * getViewportSize (void) { return m_viewport + 2; } + GLint * getViewportSize (void) { return m_viewport + 2; } }; From 17296efd62ff37f0f6f5ae812c3009baaa2c54a1 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 2 Nov 2008 18:41:24 +0000 Subject: [PATCH 35/51] VideoTexture: fix compile error with GLint in ImageViewport under osx, part 2 --- source/gameengine/VideoTexture/ImageViewport.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 59995198ba1..4ed1cd9e801 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -192,9 +192,9 @@ static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * c return -1; } // set position - int pos [] = { - int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - int(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + 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 From 858e2ec776dcea61b861d5da55e84ecca97ed321 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 3 Nov 2008 13:00:39 +0000 Subject: [PATCH 36/51] Bugfix #17921 ALT+select face-loop on mesh with hidden faces ignored the hidden part. Also caused errors on deleting faces that way. --- source/blender/src/editmesh_mods.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 81d0ffeeb3b..3dbbe7d7336 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -1864,7 +1864,7 @@ void faceloop_select(EditEdge *startedge, int select) looking= 0; for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->e4 && efa->f1==0) { /* not done quad */ + if(efa->h==0 && efa->e4 && efa->f1==0) { /* not done quad */ if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */ /* if edge tagged, select opposing edge and mark face ok */ From 6cc1466c61405721f5a7491914c722a2d2b10274 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 3 Nov 2008 13:33:11 +0000 Subject: [PATCH 37/51] Moving silence_log_ffmpeg to imbuf (it fits better there and fixes the link error in blenderplayer) --- source/blender/blenkernel/BKE_writeffmpeg.h | 2 -- source/blender/blenkernel/intern/writeffmpeg.c | 13 ------------- source/blender/imbuf/intern/util.c | 15 ++++++++++++++- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 50053446294..02f7ba6f860 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -59,8 +59,6 @@ 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 diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 642b4fd1b19..cef6f802729 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -34,7 +34,6 @@ #include #include #include -#include #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -105,18 +104,6 @@ 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) diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 05d594019a5..231d7254224 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -33,7 +33,6 @@ #include "DNA_userdef_types.h" #include "BKE_global.h" -#include "BKE_writeffmpeg.h" /* for silence_log_ffmpeg */ #include "imbuf.h" #include "imbuf_patch.h" @@ -66,6 +65,7 @@ #include #include //#include +#include #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -231,6 +231,19 @@ static int isqtime (char *name) { #endif #ifdef WITH_FFMPEG + +void silence_log_ffmpeg(int quiet) +{ + if (quiet) + { + av_log_set_level(AV_LOG_QUIET); + } + else + { + av_log_set_level(AV_LOG_INFO); + } +} + extern void do_init_ffmpeg(); void do_init_ffmpeg() { From ec462b8cead8766c9b12a962d460818d68788015 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 3 Nov 2008 23:17:36 +0000 Subject: [PATCH 38/51] Added Lattice vgroup support to shrinkwrap and simple deform modifier. --- source/blender/blenkernel/BKE_lattice.h | 3 ++ source/blender/blenkernel/BKE_shrinkwrap.h | 4 +++ source/blender/blenkernel/intern/deform.c | 5 +--- source/blender/blenkernel/intern/lattice.c | 12 ++++++++ source/blender/blenkernel/intern/modifier.c | 12 +++++--- source/blender/blenkernel/intern/shrinkwrap.c | 29 ++++++++++--------- .../blender/blenkernel/intern/simple_deform.c | 10 ++++++- 7 files changed, 53 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 5620674e791..131c8cb5aaf 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -35,6 +35,7 @@ struct Lattice; struct Object; struct DerivedMesh; struct BPoint; +struct MDeform; extern struct Lattice *editLatt; @@ -67,5 +68,7 @@ float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]; void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]); void lattice_calc_modifiers(struct Object *ob); +struct MDeform* lattice_get_deform_verts(struct Object *lattice); + #endif diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index e8276238ff2..d016348da3e 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -96,6 +96,7 @@ void space_transform_invert_normal(const SpaceTransform *data, float *no); struct Object; struct DerivedMesh; struct ShrinkwrapModifierData; +struct MDeform; struct BVHTree; @@ -109,6 +110,9 @@ typedef struct ShrinkwrapCalcData float (*vertexCos)[3]; //vertexs being shrinkwraped int numVerts; + struct MDeform* dvert; //Pointer to mdeform array + int vgroup; //Vertex group num + struct DerivedMesh *target; //mesh we are shrinking to SpaceTransform local2target; //transform to move bettwem local and target space diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 3143c5e4df2..47736865273 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -239,12 +239,9 @@ float deformvert_get_weight(const struct MDeformVert *dvert, int group_num) float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index, int group_num) { - if(group_num == -1) + if(group_num == -1 || dvert == NULL) return 1.0; - if(dvert == 0) - return 0.0; - return deformvert_get_weight(dvert+index, group_num); } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 54915058bab..2737cac149e 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -928,3 +928,15 @@ void lattice_calc_modifiers(Object *ob) BLI_addtail(&ob->disp, dl); } } + +struct MDeform* lattice_get_deform_verts(struct Object *oblatt) +{ + if(oblatt->type == OB_LATTICE) + { + Lattice *lt = (oblatt==G.obedit)?editLatt:(Lattice*)oblatt->data; + return lt->dvert; + } + + return NULL; +} + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 13dc2e834f2..6bdd395a2ac 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -7804,9 +7804,10 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived { if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dataMask & CD_MVERT) + if(dm != NULL && (dataMask & CD_MVERT)) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); @@ -7828,9 +7829,10 @@ static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditM { if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data); + else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dataMask & CD_MVERT) + if(dm != NULL && (dataMask & CD_MVERT)) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); @@ -7916,9 +7918,10 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv { if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dataMask & CD_MVERT) + if(dm != NULL && (dataMask & CD_MVERT)) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); @@ -7942,9 +7945,10 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, Edi { if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data); + else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dataMask & CD_MVERT) + if(dm != NULL && (dataMask & CD_MVERT)) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 28bf7aee884..ab98fb1f007 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -41,6 +41,7 @@ #include "BKE_shrinkwrap.h" #include "BKE_DerivedMesh.h" +#include "BKE_lattice.h" #include "BKE_utildefines.h" #include "BKE_deform.h" #include "BKE_cdderivedmesh.h" @@ -161,6 +162,18 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM calc.numVerts = numVerts; calc.vertexCos = vertexCos; + //DeformVertex + calc.vgroup = get_named_vertexgroup_num(calc.ob, calc.smd->vgroup_name); + if(calc.original) + { + calc.dvert = calc.original->getVertDataArray(calc.original, CD_MDEFORMVERT); + } + else if(calc.ob->type == OB_LATTICE) + { + calc.dvert = lattice_get_deform_verts(calc.ob); + } + + if(smd->target) { //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array @@ -207,8 +220,6 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) { int i; - const int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name); - MDeformVert *const dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL; BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; BVHTreeNearest nearest = NULL_BVHTreeNearest; @@ -230,7 +241,7 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) { float *co = calc->vertexCos[i]; float tmp_co[3]; - float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); if(weight == 0.0f) continue; VECCOPY(tmp_co, co); @@ -342,11 +353,6 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) MVert *vert = NULL; //Needed in case of vertex normal DerivedMesh* ss_mesh = NULL; - //Vertex group data - const int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name); - const MDeformVert *dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL; - - //Raycast and tree stuff BVHTreeRayHit hit; BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; //target @@ -441,7 +447,7 @@ do float *co = calc->vertexCos[i]; float tmp_co[3], tmp_no[3]; float lim = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that - float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); if(weight == 0.0f) continue; @@ -520,9 +526,6 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) { int i; - const int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name); - const MDeformVert *const dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL; - BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; BVHTreeNearest nearest = NULL_BVHTreeNearest; @@ -547,7 +550,7 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) { float *co = calc->vertexCos[i]; float tmp_co[3]; - float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); if(weight == 0.0f) continue; //Convert the vertex to tree coordinates diff --git a/source/blender/blenkernel/intern/simple_deform.c b/source/blender/blenkernel/intern/simple_deform.c index 0eb710fa48e..2978a6f7f01 100644 --- a/source/blender/blenkernel/intern/simple_deform.c +++ b/source/blender/blenkernel/intern/simple_deform.c @@ -32,6 +32,7 @@ #include "BKE_simple_deform.h" #include "BKE_DerivedMesh.h" +#include "BKE_lattice.h" #include "BKE_deform.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" @@ -204,7 +205,14 @@ void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, s if(dm) - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + { + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + } + else if(ob->type == OB_LATTICE) + { + dvert = lattice_get_deform_verts(ob); + } + switch(smd->mode) From b7fdf2ab50ef285fc88cb8a9bf6e39bf27a0ec75 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Mon, 3 Nov 2008 23:35:41 +0000 Subject: [PATCH 39/51] Add's GSR's INT64_C fix and removes dos line endings... Kent --- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 272d2695c4b..2af7228a192 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -20,6 +20,11 @@ http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ +// INT64_C fix for some linux machines (C99ism) +#define __STDC_CONSTANT_MACROS +#include + + #include "MEM_guardedalloc.h" #include "PIL_time.h" From 1f83dffeb49da9767fd1a35bb895e4c5b20636da Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 4 Nov 2008 00:15:27 +0000 Subject: [PATCH 40/51] Added a new interpolation type for colorbands: Constant This can be useful for toon shading etc. Example: http://mke3.net/blender/etc/constant_ss.png --- source/blender/blenkernel/intern/texture.c | 9 +++++++++ source/blender/src/buttons_shading.c | 16 +++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index bb726887d32..183f94c1517 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -348,6 +348,15 @@ int do_colorband(ColorBand *coba, float in, float out[4]) else fac= 0.0f; + if (coba->ipotype==4) { + /* constant */ + out[0]= cbd1->r; + out[1]= cbd1->g; + out[2]= cbd1->b; + out[3]= cbd1->a; + return 1; + } + if(coba->ipotype>=2) { /* ipo from right to left: 3 2 1 0 */ diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 5687651a6c5..f1250c975fb 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1468,10 +1468,9 @@ static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int uiDefButS(block, NUM, redraw, "Cur:", 117+xoffs,95+yoffs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active color from the colorband"); bt= uiDefBut(block, BUT, redraw, "Del", 199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position"); uiButSetFunc(bt, colorband_del_cb, coba, NULL); - uiDefButS(block, ROW, redraw, "E", 236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); - uiDefButS(block, ROW, redraw, "C", 252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); - uiDefButS(block, ROW, redraw, "L", 268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); - uiDefButS(block, ROW, redraw, "S", 284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + + uiDefButS(block, MENU, redraw, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", + 236+xoffs, 95+yoffs, 64, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Sets interpolation type"); uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); @@ -1506,11 +1505,10 @@ void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int uiButSetFunc(bt, colorband_add_cb, coba, NULL); bt= uiDefBut(block, BUT, event, "Del", xs+8.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Deletes the active position"); uiButSetFunc(bt, colorband_del_cb, coba, NULL); - uiDefButS(block, ROW, event, "E", xs+10.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); - uiDefButS(block, ROW, event, "C", xs+11.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); - uiDefButS(block, ROW, event, "L", xs+12.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); - uiDefButS(block, ROW, event, "S", xs+13.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); - + + uiDefButS(block, MENU, event, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", + xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Sets interpolation type"); + uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); uiBlockEndAlign(block); From ca80578e4ee67280764aeaf4f562afe2bbc7519c Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 4 Nov 2008 01:05:44 +0000 Subject: [PATCH 41/51] Simple warning fixes --- source/blender/blenkernel/BKE_lattice.h | 4 ++-- source/blender/blenkernel/BKE_shrinkwrap.h | 4 ++-- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/src/reeb.c | 2 -- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 131c8cb5aaf..dc7c9dcd5e5 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -35,7 +35,7 @@ struct Lattice; struct Object; struct DerivedMesh; struct BPoint; -struct MDeform; +struct MDeformVert; extern struct Lattice *editLatt; @@ -68,7 +68,7 @@ float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]; void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]); void lattice_calc_modifiers(struct Object *ob); -struct MDeform* lattice_get_deform_verts(struct Object *lattice); +struct MDeformVert* lattice_get_deform_verts(struct Object *lattice); #endif diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index d016348da3e..eed22ff9d8e 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -96,7 +96,7 @@ void space_transform_invert_normal(const SpaceTransform *data, float *no); struct Object; struct DerivedMesh; struct ShrinkwrapModifierData; -struct MDeform; +struct MDeformVert; struct BVHTree; @@ -110,7 +110,7 @@ typedef struct ShrinkwrapCalcData float (*vertexCos)[3]; //vertexs being shrinkwraped int numVerts; - struct MDeform* dvert; //Pointer to mdeform array + struct MDeformVert* dvert; //Pointer to mdeform array int vgroup; //Vertex group num struct DerivedMesh *target; //mesh we are shrinking to diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 2737cac149e..6614c657647 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -929,7 +929,7 @@ void lattice_calc_modifiers(Object *ob) } } -struct MDeform* lattice_get_deform_verts(struct Object *oblatt) +struct MDeformVert* lattice_get_deform_verts(struct Object *oblatt) { if(oblatt->type == OB_LATTICE) { diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c index 5f80a2c7227..b37087064cb 100644 --- a/source/blender/src/reeb.c +++ b/source/blender/src/reeb.c @@ -69,8 +69,6 @@ #include "reeb.h" -/* REPLACE WITH NEW ONE IN UTILDEFINES ONCE PATCH IS APPLIED */ -#define FTOCHAR(val) (val<=0.0f)? 0 : ((val>(1.0f-0.5f/255.0f))? 255 : (char)((255.0f*val)+0.5f)) ReebGraph *GLOBAL_RG = NULL; ReebGraph *FILTERED_RG = NULL; From 6eb3bf53dd753d4b00f0f76f9f7739aecb9af2f8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 4 Nov 2008 09:21:27 +0000 Subject: [PATCH 42/51] VideoTexture: Bug report #17946: add (char*) casting to fix compile error with Python get-set method and module object. --- .../VideoTexture/FilterBlueScreen.cpp | 6 ++--- .../gameengine/VideoTexture/FilterColor.cpp | 10 ++++----- .../gameengine/VideoTexture/FilterNormal.cpp | 6 ++--- source/gameengine/VideoTexture/ImageBuff.cpp | 10 ++++----- source/gameengine/VideoTexture/ImageMix.cpp | 10 ++++----- .../gameengine/VideoTexture/ImageRender.cpp | 12 +++++----- .../gameengine/VideoTexture/ImageViewport.cpp | 16 +++++++------- source/gameengine/VideoTexture/PyTypeList.cpp | 2 +- source/gameengine/VideoTexture/Texture.cpp | 4 ++-- .../gameengine/VideoTexture/VideoFFmpeg.cpp | 22 +++++++++---------- .../gameengine/VideoTexture/blendVideoTex.cpp | 2 +- 11 files changed, 50 insertions(+), 50 deletions(-) diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index 50c3a87ffc4..43d7566102a 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -125,10 +125,10 @@ static int setLimits (PyFilter * self, PyObject * value, void * closure) // attributes structure static PyGetSetDef filterBSGetSets[] = { - {"color", (getter)getColor, (setter)setColor, "blue screen color", NULL}, - {"limits", (getter)getLimits, (setter)setLimits, "blue screen color limits", NULL}, + {(char*)"color", (getter)getColor, (setter)setColor, (char*)"blue screen color", NULL}, + {(char*)"limits", (getter)getLimits, (setter)setLimits, (char*)"blue screen color limits", NULL}, // attributes from FilterBase class - {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL}, + {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index a1ddf581aef..eaf6e955003 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -34,7 +34,7 @@ http://www.gnu.org/copyleft/lesser.txt. // attributes structure static PyGetSetDef filterGrayGetSets[] = { // attributes from FilterBase class - {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL}, + {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL}, {NULL} }; @@ -164,9 +164,9 @@ static int setMatrix (PyFilter * self, PyObject * value, void * closure) // attributes structure static PyGetSetDef filterColorGetSets[] = { - {"matrix", (getter)getMatrix, (setter)setMatrix, "matrix [4][5] for color calculation", NULL}, + {(char*)"matrix", (getter)getMatrix, (setter)setMatrix, (char*)"matrix [4][5] for color calculation", NULL}, // attributes from FilterBase class - {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL}, + {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL}, {NULL} }; @@ -298,9 +298,9 @@ static int setLevels (PyFilter * self, PyObject * value, void * closure) // attributes structure static PyGetSetDef filterLevelGetSets[] = { - {"levels", (getter)getLevels, (setter)setLevels, "levels matrix [4] (min, max)", NULL}, + {(char*)"levels", (getter)getLevels, (setter)setLevels, (char*)"levels matrix [4] (min, max)", NULL}, // attributes from FilterBase class - {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL}, + {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 514214bec8b..736b9e3b958 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -109,10 +109,10 @@ static int setDepth (PyFilter * self, PyObject * value, void * closure) // 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}, + {(char*)"colorIdx", (getter)getColor, (setter)setColor, (char*)"index of color used to calculate normal (0 - red, 1 - green, 2 - blue)", NULL}, + {(char*)"depth", (getter)getDepth, (setter)setDepth, (char*)"depth of relief", NULL}, // attributes from FilterBase class - {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL}, + {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index a0c6e1f6f74..a22757dca39 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -111,11 +111,11 @@ static PyMethodDef imageBuffMethods[] = // 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}, + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index 8532249f7d8..b07b362818c 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -150,11 +150,11 @@ static PyMethodDef imageMixMethods[] = // 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}, + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index fb284261d70..2f2d9debd48 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -207,13 +207,13 @@ static PyMethodDef imageRenderMethods[] = // attributes structure static PyGetSetDef imageRenderGetSets[] = { - {"background", (getter)getBackground, (setter)setBackground, "background color", NULL}, + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"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}, + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 4ed1cd9e801..6bee9fd6624 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -239,15 +239,15 @@ static PyMethodDef imageViewportMethods[] = // 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}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to capture", NULL}, + {(char*)"position", (getter)ImageViewport_getPosition, (setter)ImageViewport_setPosition, (char*)"upper left corner of captured area", NULL}, + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"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}, + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp index 0451d74c8ad..6d2676dce09 100644 --- a/source/gameengine/VideoTexture/PyTypeList.cpp +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -78,6 +78,6 @@ void PyTypeList::reg (PyObject * module) // increase ref count Py_INCREF((*it)->getType()); // add type to module - PyModule_AddObject(module, (*it)->getName(), (PyObject*)(*it)->getType()); + PyModule_AddObject(module, (char*)(*it)->getName(), (PyObject*)(*it)->getType()); } } diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index ceda39aeff4..e922bbd768d 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -412,8 +412,8 @@ static PyMethodDef textureMethods[] = // 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}, + {(char*)"source", (getter)Texture_getSource, (setter)Texture_setSource, (char*)"source of texture", NULL}, + {(char*)"mipmap", (getter)Texture_getMipmap, (setter)Texture_setMipmap, (char*)"mipmap texture", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 2af7228a192..b97c4d670c4 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -692,18 +692,18 @@ static PyMethodDef videoMethods[] = // attributes structure static PyGetSetDef videoGetSets[] = { // methods from VideoBase class - {"status", (getter)Video_getStatus, NULL, "video status", NULL}, - {"range", (getter)Video_getRange, (setter)Video_setRange, "replay range", NULL}, - {"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, "repeat count, -1 for infinite repeat", NULL}, - {"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, "frame rate", NULL}, + {(char*)"status", (getter)Video_getStatus, NULL, (char*)"video status", NULL}, + {(char*)"range", (getter)Video_getRange, (setter)Video_setRange, (char*)"replay range", NULL}, + {(char*)"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, (char*)"repeat count, -1 for infinite repeat", NULL}, + {(char*)"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, (char*)"frame rate", NULL}, // attributes from ImageBase class - {"image", (getter)Image_getImage, NULL, "image data", NULL}, - {"size", (getter)Image_getSize, NULL, "image size", NULL}, - {"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)", NULL}, - {"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL}, - {"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL}, - {"preseek", (getter)VideoFFmpeg_getPreseek, (setter)VideoFFmpeg_setPreseek, "nb of frames of preseek", NULL}, - {"deinterlace", (getter)VideoFFmpeg_getDeinterlace, (setter)VideoFFmpeg_setDeinterlace, "deinterlace image", NULL}, + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {(char*)"preseek", (getter)VideoFFmpeg_getPreseek, (setter)VideoFFmpeg_setPreseek, (char*)"nb of frames of preseek", NULL}, + {(char*)"deinterlace", (getter)VideoFFmpeg_getDeinterlace, (setter)VideoFFmpeg_setDeinterlace, (char*)"deinterlace image", NULL}, {NULL} }; diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 629b589c0e6..f206e2f71b4 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -180,7 +180,7 @@ PyObject* initVideoTexture(void) pyFilterTypes.reg(m); Py_INCREF(&TextureType); - PyModule_AddObject(m, "Texture", (PyObject*)&TextureType); + PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType); // init last error description Exception::m_lastError[0] = '\0'; From 1886b7bf52f73f03d60967504b474cdde7a4e1e7 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 4 Nov 2008 12:04:59 +0000 Subject: [PATCH 43/51] VideoTexture: fix RGB/BGR confusion, make code compatible with big endian CPU, add RGBA source filter. --- source/gameengine/VideoTexture/FilterBase.h | 6 +++ .../VideoTexture/FilterBlueScreen.h | 15 +++--- .../gameengine/VideoTexture/FilterColor.cpp | 12 ++--- source/gameengine/VideoTexture/FilterColor.h | 36 ++++++++------- .../gameengine/VideoTexture/FilterNormal.cpp | 4 +- source/gameengine/VideoTexture/FilterNormal.h | 27 +++++++---- .../gameengine/VideoTexture/FilterSource.cpp | 46 +++++++++++++++++++ source/gameengine/VideoTexture/FilterSource.h | 43 +++++++++++++---- source/gameengine/VideoTexture/ImageBuff.cpp | 2 +- .../gameengine/VideoTexture/ImageViewport.cpp | 2 +- .../gameengine/VideoTexture/VideoFFmpeg.cpp | 32 ++++++------- source/gameengine/VideoTexture/VideoFFmpeg.h | 4 +- .../gameengine/VideoTexture/blendVideoTex.cpp | 2 + 13 files changed, 162 insertions(+), 69 deletions(-) diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h index c530e385ada..b6080f018d5 100644 --- a/source/gameengine/VideoTexture/FilterBase.h +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -29,6 +29,12 @@ http://www.gnu.org/copyleft/lesser.txt. #include "PyTypeList.h" +#define VT_C(v,idx) ((unsigned char*)&v)[idx] +#define VT_R(v) ((unsigned char*)&v)[0] +#define VT_G(v) ((unsigned char*)&v)[1] +#define VT_B(v) ((unsigned char*)&v)[2] +#define VT_A(v) ((unsigned char*)&v)[3] +#define VT_RGBA(v,r,g,b,a) VT_R(v)=(unsigned char)r, VT_G(v)=(unsigned char)g, VT_B(v)=(unsigned char)b, VT_A(v)=(unsigned char)a // forward declaration class FilterBase; diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h index 20660804f78..820e4a44501 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.h +++ b/source/gameengine/VideoTexture/FilterBlueScreen.h @@ -63,25 +63,24 @@ protected: 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]); + int difRed = int(VT_R(val)) - int(m_color[0]); + int difGreen = int(VT_G(val)) - int(m_color[1]); + int difBlue = int(VT_B(val)) - 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; + VT_A(val) = 0; // condition for fully opaque color else if (m_squareLimits[1] <= dist) // return normal colour - return val | 0xFF000000; + VT_A(val) = 0xFF; // otherwise calc alpha else - return (val & 0x00FFFFFF) | ((((dist - m_squareLimits[0]) << 8) - / m_limitDist) << 24); + VT_A(val) = (((dist - m_squareLimits[0]) << 8) / m_limitDist); + return val; } /// virtual filtering function for byte source diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index eaf6e955003..22ee729b200 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -223,7 +223,7 @@ FilterLevel::FilterLevel (void) for (int r = 0; r < 4; ++r) { levels[r][0] = 0; - levels[r][1] = 0xFF << (r << 3); + levels[r][1] = 0xFF; levels[r][2] = 0xFF; } } @@ -235,7 +235,7 @@ void FilterLevel::setLevels (ColorLevel & lev) for (int r = 0; r < 4; ++r) { for (int c = 0; c < 2; ++c) - levels[r][c] = lev[r][c] << (r << 3); + levels[r][c] = lev[r][c]; levels[r][2] = lev[r][0] < lev[r][1] ? lev[r][1] - lev[r][0] : 1; } } @@ -252,9 +252,9 @@ inline FilterLevel * getFilterLevel (PyFilter * self) 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); + return Py_BuildValue("((HH)(HH)(HH)(HH))", + lev[0][0], lev[0][1], lev[1][0], lev[1][1], + lev[2][0], lev[2][1], lev[3][0], lev[3][1]); } // set color levels @@ -279,7 +279,7 @@ static int setLevels (PyFilter * self, PyObject * value, void * closure) 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))); + lev[r][c] = (unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c))); } } // if parameter is not valid, report error diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h index ae2e98fa942..b7e52c4521c 100644 --- a/source/gameengine/VideoTexture/FilterColor.h +++ b/source/gameengine/VideoTexture/FilterColor.h @@ -43,10 +43,13 @@ protected: 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; + unsigned int gray = (28 * (VT_B(val)) + 151 * (VT_G(val)) + + 77 * (VT_R(val))) >> 8; // return gray scale value - return (val & 0xFF000000) | gray << 8 | gray | gray >> 8; + VT_R(val) = gray; + VT_G(val) = gray; + VT_B(val) = gray; + return val; } /// virtual filtering function for byte source @@ -82,11 +85,11 @@ protected: ColorMatrix m_matrix; /// calculate one color component - unsigned int calcColor (unsigned int val, short idx) + unsigned char 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); + return (((m_matrix[idx][0] * (VT_R(val)) + m_matrix[idx][1] * (VT_G(val)) + + m_matrix[idx][2] * (VT_B(val)) + m_matrix[idx][3] * (VT_A(val)) + + m_matrix[idx][4]) >> 8) & 0xFF); } /// filter pixel template, source int buffer @@ -94,8 +97,9 @@ protected: short * size, unsigned int pixSize, unsigned int val) { // return calculated color - return calcColor(val, 0) | calcColor(val, 1) | calcColor(val, 2) - | calcColor(val, 3); + int color; + VT_RGBA(color, calcColor(val, 0), calcColor(val, 1), calcColor(val, 2), calcColor(val, 3)); + return color; } /// virtual filtering function for byte source @@ -110,7 +114,7 @@ protected: /// type for color levels -typedef unsigned long ColorLevel[4][3]; +typedef unsigned short ColorLevel[4][3]; /// pixel filter for color calculation class FilterLevel : public FilterBase @@ -133,11 +137,10 @@ protected: /// calculate one color component unsigned int calcColor (unsigned int val, short idx) { - unsigned int col = val & (0xFF << (idx << 3)); + unsigned int col = VT_C(val,idx);; 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)); + else if (col >= levels[idx][1]) col = 0xFF; + else col = (((col - levels[idx][0]) << 8) / levels[idx][2]) & 0xFF; return col; } @@ -146,8 +149,9 @@ protected: short * size, unsigned int pixSize, unsigned int val) { // return calculated color - return calcColor(val, 0) | calcColor(val, 1) | calcColor(val, 2) - | calcColor(val, 3); + int color; + VT_RGBA(color, calcColor(val, 0), calcColor(val, 1), calcColor(val, 2), calcColor(val, 3)); + return color; } /// virtual filtering function for byte source diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 736b9e3b958..03a79c1c8ce 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -32,7 +32,7 @@ http://www.gnu.org/copyleft/lesser.txt. // implementation FilterNormal // constructor -FilterNormal::FilterNormal (void) : m_colShift(0) +FilterNormal::FilterNormal (void) : m_colIdx(0) { // set default depth setDepth(4); @@ -44,7 +44,7 @@ void FilterNormal::setColor (unsigned short colIdx) // check validity of index if (colIdx < 3) // set color shift - m_colShift = colIdx << 3; + m_colIdx = colIdx; } // set depth diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h index ec51ca39db9..840043be9a1 100644 --- a/source/gameengine/VideoTexture/FilterNormal.h +++ b/source/gameengine/VideoTexture/FilterNormal.h @@ -43,7 +43,7 @@ public: virtual ~FilterNormal (void) {} /// get index of color used to calculate normals - unsigned short getColor (void) { return m_colShift >> 3; } + unsigned short getColor (void) { return m_colIdx; } /// set index of color used to calculate normals void setColor (unsigned short colIdx); @@ -58,20 +58,28 @@ protected: /// scale to calculate normals float m_depthScale; - /// shift to used color component - unsigned short m_colShift; + /// color index, 0=red, 1=green, 2=blue, 3=alpha + unsigned short m_colIdx; /// filter pixel, source int buffer template 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); + int actPix = int(VT_C(val,m_colIdx)); + int upPix = actPix; + int leftPix = actPix; // 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; + if (y > 0) + { + val = convertPrevious(src - pixSize * size[0], x, y - 1, size, pixSize); + upPix = VT_C(val,m_colIdx); + } + if (x > 0) + { + val = convertPrevious(src - pixSize, x - 1, y, size, pixSize); + leftPix = VT_C(val,m_colIdx); + } // height differences (from blue color) float dx = (actPix - leftPix) * m_depthScale; float dy = (actPix - upPix) * m_depthScale; @@ -81,7 +89,8 @@ protected: dy = dy * dz + normScaleKoef; dz += normScaleKoef; // return normal vector converted to color - return 0xFF000000 | int(dz) << 16 | int(dy) << 8 | int(dx); + VT_RGBA(val, dx, dy, dz, 0xFF); + return val; } /// filter pixel, source byte buffer diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp index 8d8749dbc8f..f3676e93a6d 100644 --- a/source/gameengine/VideoTexture/FilterSource.cpp +++ b/source/gameengine/VideoTexture/FilterSource.cpp @@ -77,6 +77,52 @@ PyTypeObject FilterRGB24Type = Filter_allocNew, /* tp_new */ }; +// FilterRGBA32 + +// define python type +PyTypeObject FilterRGBA32Type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "VideoTexture.FilterRGBA32", /*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 RGBA32 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, /* tp_init */ + 0, /* tp_alloc */ + Filter_allocNew, /* tp_new */ +}; + // FilterBGR24 // define python type diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index c3d4e0079f9..7e90747d252 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -44,7 +44,34 @@ 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]; } + { VT_RGBA(val,src[0],src[1],src[2],0xFF); return val; } +}; + +/// class for RGBA32 conversion +class FilterRGBA32 : public FilterBase +{ +public: + /// constructor + FilterRGBA32 (void) {} + /// destructor + virtual ~FilterRGBA32 (void) {} + + /// get source pixel size + virtual unsigned int getPixelSize (void) { return 4; } + +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) + { + if ((intptr_t(src)&0x3) == 0) + return *(unsigned int*)src; + else + { + VT_RGBA(val,src[0],src[1],src[2],src[3]); + return val; + } + } }; /// class for BGR24 conversion @@ -63,7 +90,7 @@ 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]; } + { VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; } }; /// class for YV12 conversion @@ -215,15 +242,15 @@ protected: 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; + int green = (298 * c - 100 * d - 208 * e) >> 8; + if (green >= 0x100) green = 0xFF; else if (green < 0) green = 0; - int blue = (298 * c + 516 * d + 128) << 8; - if (blue > 0x1000000) blue = 0xFF0000; + int blue = (298 * c + 516 * d + 128) >> 8; + if (blue >= 0x100) blue = 0xFF; else if (blue < 0) blue = 0; // return result - return 0xFF000000 | blue & 0xFF0000 | green & 0xFF00 - | red & 0xFF; + VT_RGBA(val, red, green, blue, 0xFF); + return val; } }; diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index a22757dca39..19ad17ac643 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -32,7 +32,7 @@ http://www.gnu.org/copyleft/lesser.txt. // default filter -FilterBGR24 defFilter; +FilterRGB24 defFilter; // load image from buffer diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 6bee9fd6624..deb66ffb6ba 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -135,7 +135,7 @@ void ImageViewport::calcImage (unsigned int texId) 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; + FilterRGB24 filt; filterImage(filt, m_viewportImage, m_capSize); } } diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index b97c4d670c4..91b8a54dd86 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -51,7 +51,7 @@ extern "C" void do_init_ffmpeg(); // constructor VideoFFmpeg::VideoFFmpeg (HRESULT * hRslt) : VideoBase(), m_codec(NULL), m_formatCtx(NULL), m_codecCtx(NULL), -m_frame(NULL), m_frameDeinterlaced(NULL), m_frameBGR(NULL), m_imgConvertCtx(NULL), +m_frame(NULL), m_frameDeinterlaced(NULL), m_frameRGB(NULL), m_imgConvertCtx(NULL), m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0), m_lastFrame(-1), m_curPosition(-1), m_startTime(0), m_captWidth(0), m_captHeight(0), m_captRate(0.f) @@ -91,10 +91,10 @@ bool VideoFFmpeg::release() MEM_freeN(m_frameDeinterlaced->data[0]); av_free(m_frameDeinterlaced); } - if (m_frameBGR) + if (m_frameRGB) { - MEM_freeN(m_frameBGR->data[0]); - av_free(m_frameBGR); + MEM_freeN(m_frameRGB->data[0]); + av_free(m_frameRGB); } if (m_imgConvertCtx) { @@ -106,7 +106,7 @@ bool VideoFFmpeg::release() m_formatCtx = NULL; m_frame = NULL; m_frame = NULL; - m_frameBGR = NULL; + m_frameRGB = NULL; m_imgConvertCtx = NULL; // object will be deleted after that @@ -189,7 +189,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV m_videoStream = videoStream; m_frame = avcodec_alloc_frame(); m_frameDeinterlaced = avcodec_alloc_frame(); - m_frameBGR = avcodec_alloc_frame(); + m_frameRGB = avcodec_alloc_frame(); // allocate buffer if deinterlacing is required @@ -201,12 +201,12 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height); // allocate buffer to store final decoded frame - avpicture_fill((AVPicture*)m_frameBGR, + avpicture_fill((AVPicture*)m_frameRGB, (uint8_t*)MEM_callocN(avpicture_get_size( - PIX_FMT_BGR24, + PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height), - "ffmpeg bgr"), - PIX_FMT_BGR24, m_codecCtx->width, m_codecCtx->height); + "ffmpeg rgb"), + PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height); // allocate sws context m_imgConvertCtx = sws_getContext( m_codecCtx->width, @@ -214,7 +214,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height, - PIX_FMT_BGR24, + PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); @@ -224,8 +224,8 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV av_free(m_frame); MEM_freeN(m_frameDeinterlaced->data[0]); av_free(m_frameDeinterlaced); - MEM_freeN(m_frameBGR->data[0]); - av_free(m_frameBGR); + MEM_freeN(m_frameRGB->data[0]); + av_free(m_frameRGB); return -1; } return 0; @@ -565,14 +565,14 @@ bool VideoFFmpeg::grabFrame(long position) input = m_frameDeinterlaced; } } - // convert to BGR24 + // convert to RGB24 sws_scale(m_imgConvertCtx, input->data, input->linesize, 0, m_codecCtx->height, - m_frameBGR->data, - m_frameBGR->linesize); + m_frameRGB->data, + m_frameRGB->linesize); av_free_packet(&packet); frameLoaded = true; break; diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 4720bef1841..3903116c82c 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -100,7 +100,7 @@ protected: // deinterlaced frame if codec requires it AVFrame *m_frameDeinterlaced; // decoded RGB24 frame if codec requires it - AVFrame *m_frameBGR; + AVFrame *m_frameRGB; // conversion from raw to RGB is done with sws_scale struct SwsContext *m_imgConvertCtx; // should the codec be deinterlaced? @@ -150,7 +150,7 @@ protected: bool grabFrame(long frame); /// return the frame in RGB24 format, the image data is found in AVFrame.data[0] - AVFrame* getFrame(void) { return m_frameBGR; } + AVFrame* getFrame(void) { return m_frameRGB; } }; inline VideoFFmpeg * getFFmpeg (PyImage * self) diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index f206e2f71b4..530ec7a85dd 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -126,6 +126,7 @@ extern PyTypeObject FilterColorType; extern PyTypeObject FilterLevelType; extern PyTypeObject FilterNormalType; extern PyTypeObject FilterRGB24Type; +extern PyTypeObject FilterRGBA32Type; extern PyTypeObject FilterBGR24Type; extern PyTypeObject ImageBuffType; extern PyTypeObject ImageMixType; @@ -150,6 +151,7 @@ static void registerAllTypes(void) pyFilterTypes.add(&FilterLevelType, "FilterLevel"); pyFilterTypes.add(&FilterNormalType, "FilterNormal"); pyFilterTypes.add(&FilterRGB24Type, "FilterRGB24"); + pyFilterTypes.add(&FilterRGBA32Type, "FilterRGBA32"); pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24"); } From 91967235810dd02bce311614e9fd49ae415da15f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 4 Nov 2008 21:14:54 +0000 Subject: [PATCH 44/51] * remove redundant comment --- tools/Blender.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/Blender.py b/tools/Blender.py index af2a20eb95a..5d123100e3b 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -416,10 +416,6 @@ class BlenderEnvironment(SConsEnvironment): lenv.Append(CPPDEFINES=['GAMEBLENDER=1']) if lenv['WITH_BF_BULLET']: lenv.Append(CPPDEFINES=['WITH_BULLET=1']) - # debug or not - # CXXFLAGS defaults to CCFLAGS, therefore - # we Replace() rather than Append() to CXXFLAGS the first time - #lenv.Replace(CXXFLAGS = lenv['CCFLAGS']) if lenv['BF_DEBUG'] or (libname in quickdebug): lenv.Append(CFLAGS = Split(lenv['BF_DEBUG_CFLAGS'])) lenv.Append(CCFLAGS = Split(lenv['BF_DEBUG_CCFLAGS'])) From a19366f34a7d619492159d7beb5d459abf583a9d Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 4 Nov 2008 22:16:57 +0000 Subject: [PATCH 45/51] * Changed the constant colorband interpolation to work left->right, rather than right -> left. This is how it works now: http://mke3.net/blender/etc/constant_ss.png --- source/blender/blenkernel/intern/texture.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 183f94c1517..ab9e6f9af41 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -350,10 +350,10 @@ int do_colorband(ColorBand *coba, float in, float out[4]) if (coba->ipotype==4) { /* constant */ - out[0]= cbd1->r; - out[1]= cbd1->g; - out[2]= cbd1->b; - out[3]= cbd1->a; + out[0]= cbd2->r; + out[1]= cbd2->g; + out[2]= cbd2->b; + out[3]= cbd2->a; return 1; } From 2d802627596ba51a2ff7ff56f28c0c14aee559ad Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 4 Nov 2008 22:46:43 +0000 Subject: [PATCH 46/51] === SCons === * BlenderLib now expects lists for all compiler related flags (release, profile, debug, warn). I changed the default config files, but do double-check your user-config files, esp. if you did a full copy of an old default platform config --- config/darwin-config.py | 4 ++-- config/linux2-config.py | 2 +- config/linuxcross-config.py | 2 +- config/openbsd3-config.py | 4 ++-- config/sunos5-config.py | 4 ++-- config/win32-mingw-config.py | 2 +- tools/Blender.py | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/config/darwin-config.py b/config/darwin-config.py index 547d655b531..53e45f5233c 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -260,11 +260,11 @@ CC_WARN = ['-Wall', '-Wno-long-double'] ##LOPTS = --dynamic ##DYNLDFLAGS = -shared $(LDFLAGS) -BF_PROFILE_FLAGS = ' -pg -g ' +BF_PROFILE_FLAGS = ['-pg', '-g '] BF_PROFILE = False BF_DEBUG = False -BF_DEBUG_FLAGS = '-g' +BF_DEBUG_FLAGS = ['-g'] BF_BUILDDIR='../build/darwin' BF_INSTALLDIR='../install/darwin' diff --git a/config/linux2-config.py b/config/linux2-config.py index ca07bf10ab8..e890d264682 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -201,7 +201,7 @@ BF_PROFILE_FLAGS = ['-pg','-g'] BF_PROFILE = False BF_DEBUG = False -BF_DEBUG_FLAGS = '-g' +BF_DEBUG_FLAGS = ['-g'] BF_BUILDDIR = '../build/linux2' BF_INSTALLDIR='../install/linux2' diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index c10e9d76cb5..251f53a90e2 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -144,7 +144,7 @@ CC_WARN = [ '-Wall' ] LLIBS = [ '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread' ] BF_DEBUG = False -BF_DEBUG_FLAGS= '' +BF_DEBUG_FLAGS= [] BF_BUILDDIR = '../build/linuxcross' BF_INSTALLDIR='../install/linuxcross' diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index 0a4f75e3bcc..9313cbc211f 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -155,11 +155,11 @@ LLIBS = 'm stdc++ pthread util' ##LOPTS = --dynamic ##DYNLDFLAGS = -shared $(LDFLAGS) -BF_PROFILE_FLAGS = ' -pg -g ' +BF_PROFILE_FLAGS = ['-pg', '-g'] BF_PROFILE = False BF_DEBUG = False -BF_DEBUG_FLAGS = '-g' +BF_DEBUG_FLAGS = ['-g'] BF_BUILDDIR='../build/openbsd3' BF_INSTALLDIR='../install/openbsd3' diff --git a/config/sunos5-config.py b/config/sunos5-config.py index 2343ce69060..7b1295da941 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -173,11 +173,11 @@ BF_PROFILE_FLAGS = ['-pg','-g'] BF_PROFILE = False BF_DEBUG = False -BF_DEBUG_FLAGS = '' +BF_DEBUG_FLAGS = [] BF_BUILDDIR = '../build/sunos5' BF_INSTALLDIR='../install/sunos5' BF_DOCDIR='../install/doc' -PLATFORM_LINKFLAGS = [''] +PLATFORM_LINKFLAGS = [] diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index bdeca1ddc91..19e9d1918c6 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -160,7 +160,7 @@ CC_WARN = [ '-Wall' ] LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++'] BF_DEBUG = False -BF_DEBUG_FLAGS= '-g' +BF_DEBUG_FLAGS= ['-g'] BF_PROFILE_FLAGS = ['-pg','-g'] BF_PROFILE = False diff --git a/tools/Blender.py b/tools/Blender.py index 5d123100e3b..857d5c4d780 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -417,9 +417,9 @@ class BlenderEnvironment(SConsEnvironment): if lenv['WITH_BF_BULLET']: lenv.Append(CPPDEFINES=['WITH_BULLET=1']) if lenv['BF_DEBUG'] or (libname in quickdebug): - lenv.Append(CFLAGS = Split(lenv['BF_DEBUG_CFLAGS'])) - lenv.Append(CCFLAGS = Split(lenv['BF_DEBUG_CCFLAGS'])) - lenv.Append(CXXFLAGS = Split(lenv['BF_DEBUG_CXXFLAGS'])) + lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS']) + lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS']) + lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS']) else: lenv.Append(CFLAGS = lenv['REL_CFLAGS']) lenv.Append(CCFLAGS = lenv['REL_CCFLAGS']) From beea73b110a7b3ad983a09c7e41b503cee590ebd Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 4 Nov 2008 23:04:15 +0000 Subject: [PATCH 47/51] * enable openjpeg building for win32/msvc * add support for building redcode on win32/msvc, but disabled for now, as there are linking problems - I cleaned the redcode sconscript - the copying of headers within the source tree is not a clean solution This needs to be fixed later on. For now, lets use redcode from extern/ until a better way is found. --- config/win32-vc-config.py | 5 +++++ extern/libopenjpeg/SConscript | 14 +++++++++----- extern/libredcode/SConscript | 14 +------------- extern/libredcode/format.c | 5 +++++ source/blender/imbuf/intern/IMB_anim.h | 6 +++++- source/blender/imbuf/intern/anim.c | 9 +++++++-- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index a5aa76c2868..9a41f7ee557 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -150,6 +150,11 @@ BF_QUICKTIME_INC = '${BF_QUICKTIME}/CIncludes' BF_QUICKTIME_LIB = 'qtmlClient' BF_QUICKTIME_LIBPATH = '${BF_QUICKTIME}/Libraries' +WITH_BF_OPENJPEG = True + +WITH_BF_REDCODE = False +BF_REDCODE_INC = '#extern' + WITH_BF_STATICOPENGL = False BF_OPENGL_INC = '${BF_OPENGL}/include' BF_OPENGL_LIBINC = '${BF_OPENGL}/lib' diff --git a/extern/libopenjpeg/SConscript b/extern/libopenjpeg/SConscript index f0a93f6e2d9..7100ecb37fd 100644 --- a/extern/libopenjpeg/SConscript +++ b/extern/libopenjpeg/SConscript @@ -7,14 +7,18 @@ Import('env') sources = env.Glob('*.c') incs = '.' -flags = "-Wall -O3 -ffast-math -std=c99" +if env['OURPLATFORM'] == 'win32-vc': + flags = [] +else: + flags = ['-Wall', '-O3', '-ffast-math', '-std=c99'] -oj_env = env.Copy(); -oj_env.Replace(CCFLAGS = '') -oj_env.Replace(BF_DEBUG_FLAGS = '') +oj_env = env.Clone() +if not env['OURPLATFORM'] == 'win32-vc': + oj_env.Replace(CCFLAGS = '') + oj_env.Replace(BF_DEBUG_FLAGS = '') oj_env.BlenderLib ( libname='extern_openjpeg', sources=sources, includes=Split(incs), defines=[], libtype=['core','intern','player'], - priority=[10, 10, 300], compileflags = Split(flags)) + priority=[5, 10, 200], compileflags = flags) diff --git a/extern/libredcode/SConscript b/extern/libredcode/SConscript index 4e83ba5cbb4..b58e6d5fe25 100644 --- a/extern/libredcode/SConscript +++ b/extern/libredcode/SConscript @@ -9,20 +9,8 @@ Import('env') sources = env.Glob('*.c') incs = '. ../libopenjpeg' -root = "extern/libredcode" - -if not os.path.isdir(root + "/include"): - os.mkdir(root + "/include"); -if not os.path.isdir(root + "/include/redcode"): - os.mkdir(root + "/include/redcode"); - -for h in env.Glob('*.h'): - shutil.copyfile(root + "/" + h, - root + "/include/redcode/" + h) - - env.BlenderLib ( libname='extern_redcode', sources=sources, includes=Split(incs), defines=[], libtype=['core','intern','player'], - priority=[5, 5, 200], compileflags = []) + priority=[10, 5, 300], compileflags = []) diff --git a/extern/libredcode/format.c b/extern/libredcode/format.c index 35410e9e269..4677c49b8a5 100644 --- a/extern/libredcode/format.c +++ b/extern/libredcode/format.c @@ -1,4 +1,9 @@ +#ifdef _WIN32 +#include +#else #include +#endif + #include #include #include diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index 7dc1f966b71..745248d3218 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -82,7 +82,11 @@ #endif #ifdef WITH_REDCODE -#include +#ifdef _WIN32 /* on windows we use the one in extern instead */ +#include "libredcode/format.h" +#else +#include "libredcode/format.h" +#endif #endif #include "IMB_imbuf_types.h" diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index c0e84b73e47..80bf401bec0 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -97,8 +97,13 @@ #endif #ifdef WITH_REDCODE -#include -#include +#ifdef _WIN32 /* on windows we use the ones in extern instead */ +#include "libredcode/format.h" +#include "libredcode/codec.h" +#else +#include "libredcode/format.h" +#include "libredcode/codec.h" +#endif #endif /****/ From f59f5e67a54b272c62c7a2e30277b78abef44ca8 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 4 Nov 2008 23:46:01 +0000 Subject: [PATCH 48/51] * doing some warning cleaning * accidently left priority tests around. --- extern/libopenjpeg/SConscript | 2 +- extern/libredcode/SConscript | 2 +- source/blender/blenkernel/intern/blender.c | 12 ++++++++---- source/blender/blenkernel/intern/exotic.c | 6 +++++- source/blender/imbuf/intern/amiga.c | 6 +++++- source/blender/imbuf/intern/readimage.c | 5 ++++- source/blender/imbuf/intern/util.c | 10 +++++++++- 7 files changed, 33 insertions(+), 10 deletions(-) diff --git a/extern/libopenjpeg/SConscript b/extern/libopenjpeg/SConscript index 7100ecb37fd..837701eeae0 100644 --- a/extern/libopenjpeg/SConscript +++ b/extern/libopenjpeg/SConscript @@ -21,4 +21,4 @@ oj_env.BlenderLib ( libname='extern_openjpeg', sources=sources, includes=Split(incs), defines=[], libtype=['core','intern','player'], - priority=[5, 10, 200], compileflags = flags) + priority=[10, 10, 300], compileflags = flags) diff --git a/extern/libredcode/SConscript b/extern/libredcode/SConscript index b58e6d5fe25..9fd25ad63c7 100644 --- a/extern/libredcode/SConscript +++ b/extern/libredcode/SConscript @@ -13,4 +13,4 @@ env.BlenderLib ( libname='extern_redcode', sources=sources, includes=Split(incs), defines=[], libtype=['core','intern','player'], - priority=[10, 5, 300], compileflags = []) + priority=[5, 5, 200], compileflags = []) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 1fe6447752e..5dcccc56d06 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -30,11 +30,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef WIN32 - #include // for read close - #include // for MAXPATHLEN +#ifndef _WIN32 + #include // for read close + #include // for MAXPATHLEN #else - #include // for open close read + #include // for open close read + #define open _open + #define read _read + #define close _close + #define write _write #endif #include diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 9fb8d17d730..ee3fd59fe9f 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -76,10 +76,14 @@ #include #include -#ifndef WIN32 +#ifndef _WIN32 #include #else #include +#define open _open +#define read _read +#define close _close +#define write _write #endif #include "MEM_guardedalloc.h" diff --git a/source/blender/imbuf/intern/amiga.c b/source/blender/imbuf/intern/amiga.c index 3d52a287a31..534e4945aa3 100644 --- a/source/blender/imbuf/intern/amiga.c +++ b/source/blender/imbuf/intern/amiga.c @@ -29,8 +29,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifdef WIN32 +#ifdef _WIN32 #include +#define open _open +#define read _read +#define close _close +#define write _write #endif #include "imbuf.h" #include "imbuf_patch.h" diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 566df53a25e..05e7921665b 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -29,11 +29,14 @@ * $Id$ */ -#ifdef WIN32 +#ifdef _WIN32 #include #include #include #include "mmap_win.h" +#define open _open +#define read _read +#define close _close #endif #include "BLI_blenlib.h" diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 231d7254224..c86f9b017bf 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -29,6 +29,13 @@ * $Id$ */ +#ifdef _WIN32 +#include +#define open _open +#define read _read +#define close _close +#endif + #include "BLI_blenlib.h" #include "DNA_userdef_types.h" @@ -275,7 +282,8 @@ static AVCodecContext* get_codec_from_stream(AVStream* stream) static int isffmpeg (char *filename) { AVFormatContext *pFormatCtx; - int i, videoStream; + unsigned int i; + int videoStream; AVCodec *pCodec; AVCodecContext *pCodecCtx; From 633e3e13235c06c58f7d36ff04fb6630161917fb Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 5 Nov 2008 04:48:08 +0000 Subject: [PATCH 49/51] * Updated the 'Consolidate into one image' script to support alpha --- release/scripts/image_auto_layout.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/release/scripts/image_auto_layout.py b/release/scripts/image_auto_layout.py index 19ee396c3b1..c6f97a25434 100644 --- a/release/scripts/image_auto_layout.py +++ b/release/scripts/image_auto_layout.py @@ -265,8 +265,8 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR render_context.setRenderWinSize(100) render_context.setImageType(Render.PNG) render_context.enableExtensions(True) - render_context.enableSky() # No alpha needed. - render_context.enableRGBColor() + render_context.enablePremultiply() # No alpha needed. + render_context.enableRGBAColor() render_context.threads = 2 #Render.EnableDispView() # Broken?? @@ -275,8 +275,9 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR render_mat= B.Material.New() render_mat.mode |= B.Material.Modes.SHADELESS render_mat.mode |= B.Material.Modes.TEXFACE - - + render_mat.mode |= B.Material.Modes.ZTRANSP + render_mat.setAlpha(0.0) + render_me= B.Mesh.New() render_me.verts.extend([Vector(0,0,0)]) # Stupid, dummy vert, preverts errors. when assigning UV's/ render_ob= B.Object.New('Mesh') From 3b2a07a8665be4c10b22e2ff84d45d67d86ffc79 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Wed, 5 Nov 2008 11:42:34 +0000 Subject: [PATCH 50/51] uniform end-of-line format and set svn:eol-style property to "native" for all scripts --- release/scripts/export_m3g.py | 2 +- release/scripts/import_lightwave_motion.py | 2 +- release/scripts/scripttemplate_gamelogic.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/release/scripts/export_m3g.py b/release/scripts/export_m3g.py index 86ac03cc407..c74e7acbcd3 100644 --- a/release/scripts/export_m3g.py +++ b/release/scripts/export_m3g.py @@ -11,7 +11,7 @@ Tooltip: 'Export to M3G' # # Source: http://www.nelson-games.de/bl2m3g/source # -# $Id: m3g_export.py,v 0.1 2005/04/19 12:25 gerhardv Exp gerhardv $ +# $Id$ # # Author: Gerhard Völkl # diff --git a/release/scripts/import_lightwave_motion.py b/release/scripts/import_lightwave_motion.py index c242a9f6bd3..20c87dfd5c6 100644 --- a/release/scripts/import_lightwave_motion.py +++ b/release/scripts/import_lightwave_motion.py @@ -22,7 +22,7 @@ Be sure to set the framerate correctly """ -# $Id: export_lightwave_motion.py 9924 2007-01-27 02:15:14Z campbellbarton $ +# $Id$ # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/release/scripts/scripttemplate_gamelogic.py b/release/scripts/scripttemplate_gamelogic.py index 17095251155..7184d7e424f 100644 --- a/release/scripts/scripttemplate_gamelogic.py +++ b/release/scripts/scripttemplate_gamelogic.py @@ -83,7 +83,8 @@ def main(): own.life += ob.life ob.life = 0 print own.life - """ + """ + main() ''' From 8916f84622ccadbbb4111b03117cc6cc9ad9fe0a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 5 Nov 2008 13:22:10 +0000 Subject: [PATCH 51/51] VideoTexture: Add support for GLSL. FIx small printout bug in Exception printout --- source/gameengine/Ketsji/KX_BlenderMaterial.h | 3 +++ source/gameengine/VideoTexture/Exception.cpp | 6 +++--- source/gameengine/VideoTexture/Texture.cpp | 18 +++++++++++------- source/gameengine/VideoTexture/Texture.h | 7 +++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index b858fa3754c..6e5db1b56c1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -70,6 +70,9 @@ public: BL_Texture * getTex (unsigned int idx) { return (idx < MAXTEX) ? mTextures + idx : NULL; } + Image * getImage (unsigned int idx) { + return (idx < MAXTEX && mMaterial) ? mMaterial->img[idx] : NULL; + } // for ipos void UpdateIPO( diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index 3ac8b8e321d..3f939de6bc2 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -168,15 +168,15 @@ void Exception::setXptDesc (void) } // add result code // length of result code - const size_t rsltSize = 10; + const size_t rsltSize = 11; // delimit description const char delimRslt[] = ": "; // set text of description char rsltTxt[rsltSize]; std::ostrstream os(rsltTxt, rsltSize); - os << std::hex << m_hRslt << delimRslt; + os << std::hex << m_hRslt << delimRslt << '\0'; // copy result to description - m_desc.insert(0, rsltTxt, rsltSize); + m_desc.insert(0, rsltTxt); // copy exception description to last exception string m_lastError = m_desc; } diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index e922bbd768d..88a26e3c088 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -54,9 +54,6 @@ http://www.gnu.org/copyleft/lesser.txt. { exp.report(); } -// are Blender materials used -bool blendMats = false; - // Blender GameObject type BlendType gameObjectType ("KX_GameObject"); @@ -198,15 +195,22 @@ int Texture_init (Texture *self, PyObject *args, PyObject *kwds) if (mat != NULL) { // is it blender material or polygon material - blendMats = (mat->GetFlag() & RAS_BLENDERMAT) != 0; - if (blendMats) + if (mat->GetFlag() & RAS_BLENDERGLSL) + { + self->m_imgTexture = static_cast(mat)->getImage(texID); + self->m_useMatTexture = false; + } else if (mat->GetFlag() & RAS_BLENDERMAT) + { // get blender material texture self->m_matTexture = static_cast(mat)->getTex(texID); + self->m_useMatTexture = true; + } else { // get texture pointer from polygon material MTFace * tface = static_cast(mat)->GetMTFace(); self->m_imgTexture = (Image*)tface->tpage; + self->m_useMatTexture = false; } } // check if texture is available, if not, initialization failed @@ -246,7 +250,7 @@ PyObject * Texture_close(Texture * self) { self->m_orgSaved = false; // restore original texture code - if (blendMats) + if (self->m_useMatTexture) self->m_matTexture->swapTexture(self->m_orgTex); else self->m_imgTexture->bindcode = self->m_orgTex; @@ -292,7 +296,7 @@ PyObject * Texture_refresh (Texture * self, PyObject * args) { self->m_orgSaved = true; // save original image code - if (blendMats) + if (self->m_useMatTexture) self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex); else { diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index 569e34da121..3c371e51537 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -39,9 +39,11 @@ struct Texture { PyObject_HEAD + // texture is using blender material + bool m_useMatTexture; + // video texture bind code unsigned int m_actTex; - // original texture bind code unsigned int m_orgTex; // original texture saved @@ -70,9 +72,6 @@ struct Texture // 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);