Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2018-04-16 15:07:42 +0300
committerDalai Felinto <dfelinto@gmail.com>2018-04-17 18:51:28 +0300
commit159806140fd33e6ddab951c0f6f180cfbf927d38 (patch)
treeda076be3baa4d987fb5935e220a3d901c926e0e7 /source/gameengine/VideoTexture
parent28b996a9d2090efdd74115a653629ef9d7d871f7 (diff)
Removing Blender Game Engine from Blender 2.8
Folders removed entirely: * //extern/recastnavigation * //intern/decklink * //intern/moto * //source/blender/editors/space_logic * //source/blenderplayer * //source/gameengine This includes DNA data and any reference to the BGE code in Blender itself. We are bumping the subversion. Pending tasks: * Tile/clamp code in image editor draw code. * Viewport drawing code (so much of this will go away because of BI removal that we can wait until then to remove this.
Diffstat (limited to 'source/gameengine/VideoTexture')
-rw-r--r--source/gameengine/VideoTexture/BlendType.h86
-rw-r--r--source/gameengine/VideoTexture/CMakeLists.txt119
-rw-r--r--source/gameengine/VideoTexture/Common.h64
-rw-r--r--source/gameengine/VideoTexture/DeckLink.cpp813
-rw-r--r--source/gameengine/VideoTexture/DeckLink.h86
-rw-r--r--source/gameengine/VideoTexture/Exception.cpp241
-rw-r--r--source/gameengine/VideoTexture/Exception.h239
-rw-r--r--source/gameengine/VideoTexture/FilterBase.cpp160
-rw-r--r--source/gameengine/VideoTexture/FilterBase.h161
-rw-r--r--source/gameengine/VideoTexture/FilterBlueScreen.cpp190
-rw-r--r--source/gameengine/VideoTexture/FilterBlueScreen.h105
-rw-r--r--source/gameengine/VideoTexture/FilterColor.cpp354
-rw-r--r--source/gameengine/VideoTexture/FilterColor.h176
-rw-r--r--source/gameengine/VideoTexture/FilterNormal.cpp173
-rw-r--r--source/gameengine/VideoTexture/FilterNormal.h115
-rw-r--r--source/gameengine/VideoTexture/FilterSource.cpp176
-rw-r--r--source/gameengine/VideoTexture/FilterSource.h352
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp834
-rw-r--r--source/gameengine/VideoTexture/ImageBase.h392
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.cpp424
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.h69
-rw-r--r--source/gameengine/VideoTexture/ImageMix.cpp216
-rw-r--r--source/gameengine/VideoTexture/ImageMix.h131
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp946
-rw-r--r--source/gameengine/VideoTexture/ImageRender.h125
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.cpp467
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.h113
-rw-r--r--source/gameengine/VideoTexture/PyTypeList.cpp97
-rw-r--r--source/gameengine/VideoTexture/PyTypeList.h100
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp533
-rw-r--r--source/gameengine/VideoTexture/Texture.h99
-rw-r--r--source/gameengine/VideoTexture/VideoBase.cpp254
-rw-r--r--source/gameengine/VideoTexture/VideoBase.h207
-rw-r--r--source/gameengine/VideoTexture/VideoDeckLink.cpp1228
-rw-r--r--source/gameengine/VideoTexture/VideoDeckLink.h256
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp1392
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h219
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp266
38 files changed, 0 insertions, 11978 deletions
diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h
deleted file mode 100644
index 561c6e8768f..00000000000
--- a/source/gameengine/VideoTexture/BlendType.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file BlendType.h
- * \ingroup bgevideotex
- */
-
-#ifndef __BLENDTYPE_H__
-#define __BLENDTYPE_H__
-
-
-/// class allows check type of blender python object and access its contained object
-/// MUST ONLY BE USED FOR KX classes that are descendent of PyObjectPlus
-template <class PyObj> class BlendType
-{
-public:
- /// constructor
- BlendType (const char * name) : m_name(name), m_objType(NULL) {}
-
- /// 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(Py_TYPE(obj)->tp_name, m_name) == 0)
- // if name of type match, save pointer to type
- m_objType = Py_TYPE(obj);
- 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 (Py_TYPE(obj) != m_objType)
- return NULL;
- // return pointer to object, this class can only be used for KX object =>
- // the Py object is actually a proxy
- return (PyObj *)BGE_PROXY_REF(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
- const 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
deleted file mode 100644
index 1eb09b02e05..00000000000
--- a/source/gameengine/VideoTexture/CMakeLists.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-# ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 *****
-
-set(INC
- .
- ../BlenderRoutines
- ../Expressions
- ../GameLogic
- ../Ketsji
- ../Rasterizer
- ../Rasterizer/RAS_OpenGLRasterizer
- ../SceneGraph
- ../../blender/blenkernel
- ../../blender/blenlib
- ../../blender/editors/include
- ../../blender/gpu
- ../../blender/imbuf
- ../../blender/makesdna
- ../../blender/python
- ../../blender/python/generic
- ../../../intern/container
- ../../../intern/ffmpeg
- ../../../intern/glew-mx
- ../../../intern/guardedalloc
- ../../../intern/string
- ../../../intern/decklink
- ../../../intern/gpudirect
- ../../../intern/atomic
-)
-
-set(INC_SYS
- ../../../intern/moto/include
- ${GLEW_INCLUDE_PATH}
-)
-
-add_definitions(${GL_DEFINITIONS})
-
-set(SRC
- Exception.cpp
- FilterBase.cpp
- FilterBlueScreen.cpp
- FilterColor.cpp
- FilterNormal.cpp
- FilterSource.cpp
- ImageBase.cpp
- ImageBuff.cpp
- ImageMix.cpp
- ImageRender.cpp
- ImageViewport.cpp
- PyTypeList.cpp
- Texture.cpp
- DeckLink.cpp
- VideoBase.cpp
- VideoFFmpeg.cpp
- VideoDeckLink.cpp
- blendVideoTex.cpp
-
- BlendType.h
- Common.h
- Exception.h
- FilterBase.h
- FilterBlueScreen.h
- FilterColor.h
- FilterNormal.h
- FilterSource.h
- ImageBase.h
- ImageBuff.h
- ImageMix.h
- ImageRender.h
- ImageViewport.h
- PyTypeList.h
- Texture.h
- DeckLink.h
- VideoBase.h
- VideoFFmpeg.h
- VideoDeckLink.h
-)
-
-if(WITH_CODEC_FFMPEG)
- list(APPEND INC_SYS
- ${FFMPEG_INCLUDE_DIRS}
- ${PTHREADS_INCLUDE_DIRS}
- )
- add_definitions(-DWITH_FFMPEG)
-
- remove_strict_flags_file(
- VideoFFmpeg.cpp
- VideoDeckLink
- DeckLink
- )
-endif()
-
-if(WITH_GAMEENGINE_DECKLINK)
- add_definitions(-DWITH_GAMEENGINE_DECKLINK)
-endif()
-
-blender_add_lib(ge_videotex "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/VideoTexture/Common.h b/source/gameengine/VideoTexture/Common.h
deleted file mode 100644
index 22ea177addc..00000000000
--- a/source/gameengine/VideoTexture/Common.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoTexture/Common.h
- * \ingroup bgevideotex
- */
-
-#if defined WIN32
-#define WINDOWS_LEAN_AND_MEAN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _HRESULT_DEFINED
-#define _HRESULT_DEFINED
-#define HRESULT long
-#endif
-
-#ifndef DWORD
-#define DWORD unsigned long
-#endif
-
-#ifndef S_OK
-#define S_OK ((HRESULT)0L)
-#endif
-
-#ifndef BYTE
-#define BYTE unsigned char
-#endif
-
-#ifndef WIN32
-#define Sleep(time) sleep(time)
-#endif
-
-#ifndef FAILED
-#define FAILED(Status) ((HRESULT)(Status)<0)
-#endif
-
-#include <iostream>
diff --git a/source/gameengine/VideoTexture/DeckLink.cpp b/source/gameengine/VideoTexture/DeckLink.cpp
deleted file mode 100644
index fa8ab8c641c..00000000000
--- a/source/gameengine/VideoTexture/DeckLink.cpp
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2015, Blender Foundation
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Blender Foundation.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/Texture.cpp
- * \ingroup bgevideotex
- */
-
-#ifdef WITH_GAMEENGINE_DECKLINK
-
-// implementation
-
-// FFmpeg defines its own version of stdint.h on Windows.
-// Decklink needs FFmpeg, so it uses its version of stdint.h
-// this is necessary for INT64_C macro
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-// this is necessary for UINTPTR_MAX (used by atomic-ops)
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-
-#include "atomic_ops.h"
-
-#include "EXP_PyObjectPlus.h"
-#include "KX_KetsjiEngine.h"
-#include "KX_PythonInit.h"
-#include "DeckLink.h"
-
-#include <memory.h>
-
-// macro for exception handling and logging
-#define CATCH_EXCP catch (Exception & exp) \
-{ exp.report(); return NULL; }
-
-static struct
-{
- const char *name;
- BMDDisplayMode mode;
-} sModeStringTab[] = {
- { "NTSC", bmdModeNTSC },
- { "NTSC2398", bmdModeNTSC2398 },
- { "PAL", bmdModePAL },
- { "NTSCp", bmdModeNTSCp },
- { "PALp", bmdModePALp },
-
- /* HD 1080 Modes */
-
- { "HD1080p2398", bmdModeHD1080p2398 },
- { "HD1080p24", bmdModeHD1080p24 },
- { "HD1080p25", bmdModeHD1080p25 },
- { "HD1080p2997", bmdModeHD1080p2997 },
- { "HD1080p30", bmdModeHD1080p30 },
- { "HD1080i50", bmdModeHD1080i50 },
- { "HD1080i5994", bmdModeHD1080i5994 },
- { "HD1080i6000", bmdModeHD1080i6000 },
- { "HD1080p50", bmdModeHD1080p50 },
- { "HD1080p5994", bmdModeHD1080p5994 },
- { "HD1080p6000", bmdModeHD1080p6000 },
-
- /* HD 720 Modes */
-
- { "HD720p50", bmdModeHD720p50 },
- { "HD720p5994", bmdModeHD720p5994 },
- { "HD720p60", bmdModeHD720p60 },
-
- /* 2k Modes */
-
- { "2k2398", bmdMode2k2398 },
- { "2k24", bmdMode2k24 },
- { "2k25", bmdMode2k25 },
-
- /* DCI Modes (output only) */
-
- { "2kDCI2398", bmdMode2kDCI2398 },
- { "2kDCI24", bmdMode2kDCI24 },
- { "2kDCI25", bmdMode2kDCI25 },
-
- /* 4k Modes */
-
- { "4K2160p2398", bmdMode4K2160p2398 },
- { "4K2160p24", bmdMode4K2160p24 },
- { "4K2160p25", bmdMode4K2160p25 },
- { "4K2160p2997", bmdMode4K2160p2997 },
- { "4K2160p30", bmdMode4K2160p30 },
- { "4K2160p50", bmdMode4K2160p50 },
- { "4K2160p5994", bmdMode4K2160p5994 },
- { "4K2160p60", bmdMode4K2160p60 },
- // sentinel
- { NULL }
-};
-
-static struct
-{
- const char *name;
- BMDPixelFormat format;
-} sFormatStringTab[] = {
- { "8BitYUV", bmdFormat8BitYUV },
- { "10BitYUV", bmdFormat10BitYUV },
- { "8BitARGB", bmdFormat8BitARGB },
- { "8BitBGRA", bmdFormat8BitBGRA },
- { "10BitRGB", bmdFormat10BitRGB },
- { "12BitRGB", bmdFormat12BitRGB },
- { "12BitRGBLE", bmdFormat12BitRGBLE },
- { "10BitRGBXLE", bmdFormat10BitRGBXLE },
- { "10BitRGBX", bmdFormat10BitRGBX },
- // sentinel
- { NULL }
-};
-
-ExceptionID DeckLinkBadDisplayMode, DeckLinkBadPixelFormat;
-ExpDesc DeckLinkBadDisplayModeDesc(DeckLinkBadDisplayMode, "Invalid or unsupported display mode");
-ExpDesc DeckLinkBadPixelFormatDesc(DeckLinkBadPixelFormat, "Invalid or unsupported pixel format");
-
-HRESULT decklink_ReadDisplayMode(const char *format, size_t len, BMDDisplayMode *displayMode)
-{
- int i;
-
- if (len == 0)
- len = strlen(format);
- for (i = 0; sModeStringTab[i].name != NULL; i++) {
- if (strlen(sModeStringTab[i].name) == len &&
- !strncmp(sModeStringTab[i].name, format, len))
- {
- *displayMode = sModeStringTab[i].mode;
- return S_OK;
- }
- }
- if (len != 4)
- THRWEXCP(DeckLinkBadDisplayMode, S_OK);
- // assume the user entered directly the mode value as a 4 char string
- *displayMode = (BMDDisplayMode)((((uint32_t)format[0]) << 24) + (((uint32_t)format[1]) << 16) + (((uint32_t)format[2]) << 8) + ((uint32_t)format[3]));
- return S_OK;
-}
-
-HRESULT decklink_ReadPixelFormat(const char *format, size_t len, BMDPixelFormat *pixelFormat)
-{
- int i;
-
- if (!len)
- len = strlen(format);
- for (i = 0; sFormatStringTab[i].name != NULL; i++) {
- if (strlen(sFormatStringTab[i].name) == len &&
- !strncmp(sFormatStringTab[i].name, format, len))
- {
- *pixelFormat = sFormatStringTab[i].format;
- return S_OK;
- }
- }
- if (len != 4)
- THRWEXCP(DeckLinkBadPixelFormat, S_OK);
- // assume the user entered directly the mode value as a 4 char string
- *pixelFormat = (BMDPixelFormat)((((uint32_t)format[0]) << 24) + (((uint32_t)format[1]) << 16) + (((uint32_t)format[2]) << 8) + ((uint32_t)format[3]));
- return S_OK;
-}
-
-class DeckLink3DFrameWrapper : public IDeckLinkVideoFrame, IDeckLinkVideoFrame3DExtensions
-{
-public:
- // IUnknown
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv)
- {
- if (!memcmp(&iid, &IID_IDeckLinkVideoFrame3DExtensions, sizeof(iid))) {
- if (mpRightEye) {
- *ppv = (IDeckLinkVideoFrame3DExtensions*)this;
- return S_OK;
- }
- }
- return E_NOTIMPL;
- }
- virtual ULONG STDMETHODCALLTYPE AddRef(void) { return 1U; }
- virtual ULONG STDMETHODCALLTYPE Release(void) { return 1U; }
- // IDeckLinkVideoFrame
- virtual long STDMETHODCALLTYPE GetWidth(void) { return mpLeftEye->GetWidth(); }
- virtual long STDMETHODCALLTYPE GetHeight(void) { return mpLeftEye->GetHeight(); }
- virtual long STDMETHODCALLTYPE GetRowBytes(void) { return mpLeftEye->GetRowBytes(); }
- virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void) { return mpLeftEye->GetPixelFormat(); }
- virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags(void) { return mpLeftEye->GetFlags(); }
- virtual HRESULT STDMETHODCALLTYPE GetBytes(void **buffer) { return mpLeftEye->GetBytes(buffer); }
- virtual HRESULT STDMETHODCALLTYPE GetTimecode(BMDTimecodeFormat format,IDeckLinkTimecode **timecode)
- { return mpLeftEye->GetTimecode(format, timecode); }
- virtual HRESULT STDMETHODCALLTYPE GetAncillaryData(IDeckLinkVideoFrameAncillary **ancillary)
- { return mpLeftEye->GetAncillaryData(ancillary); }
- // IDeckLinkVideoFrame3DExtensions
- virtual BMDVideo3DPackingFormat STDMETHODCALLTYPE Get3DPackingFormat(void)
- {
- return bmdVideo3DPackingLeftOnly;
- }
- virtual HRESULT STDMETHODCALLTYPE GetFrameForRightEye(
- /* [out] */ IDeckLinkVideoFrame **rightEyeFrame)
- {
- mpRightEye->AddRef();
- *rightEyeFrame = mpRightEye;
- return S_OK;
- }
- // Constructor
- DeckLink3DFrameWrapper(IDeckLinkVideoFrame *leftEye, IDeckLinkVideoFrame *rightEye)
- {
- mpLeftEye = leftEye;
- mpRightEye = rightEye;
- }
- // no need for a destructor, it's just a wrapper
-private:
- IDeckLinkVideoFrame *mpLeftEye;
- IDeckLinkVideoFrame *mpRightEye;
-};
-
-static void decklink_Reset(DeckLink *self)
-{
- self->m_lastClock = 0.0;
- self->mDLOutput = NULL;
- self->mUse3D = false;
- self->mDisplayMode = bmdModeUnknown;
- self->mKeyingSupported = false;
- self->mHDKeyingSupported = false;
- self->mSize[0] = 0;
- self->mSize[1] = 0;
- self->mFrameSize = 0;
- self->mLeftFrame = NULL;
- self->mRightFrame = NULL;
- self->mKeyer = NULL;
- self->mUseKeying = false;
- self->mKeyingLevel = 255;
- self->mUseExtend = false;
-}
-
-#ifdef __BIG_ENDIAN__
-#define CONV_PIXEL(i) ((((i)>>16)&0xFF00)+(((i)&0xFF00)<<16)+((i)&0xFF00FF))
-#else
-#define CONV_PIXEL(i) ((((i)&0xFF)<<16)+(((i)>>16)&0xFF)+((i)&0xFF00FF00))
-#endif
-
-// adapt the pixel format and picture size from VideoTexture (RGBA) to DeckLink (BGRA)
-static void decklink_ConvImage(uint32_t *dest, const short *destSize, const uint32_t *source, const short *srcSize, bool extend)
-{
- short w, h, x, y;
- const uint32_t *s;
- uint32_t *d, p;
- bool sameSize = (destSize[0] == srcSize[0] && destSize[1] == srcSize[1]);
-
- if (sameSize || !extend) {
- // here we convert pixel by pixel
- w = (destSize[0] < srcSize[0]) ? destSize[0] : srcSize[0];
- h = (destSize[1] < srcSize[1]) ? destSize[1] : srcSize[1];
- for (y = 0; y < h; ++y) {
- s = source + y*srcSize[0];
- d = dest + y*destSize[0];
- for (x = 0; x < w; ++x, ++s, ++d) {
- *d = CONV_PIXEL(*s);
- }
- }
- }
- else {
- // here we scale
- // interpolation accumulator
- int accHeight = srcSize[1] >> 1;
- d = dest;
- s = source;
- // process image rows
- for (y = 0; y < srcSize[1]; ++y) {
- // increase height accum
- accHeight += destSize[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 (x = 0; x < srcSize[0]; ++x, ++s) {
- // increase width accum
- accWidth += destSize[0];
- // convert pixel
- p = CONV_PIXEL(*s);
- // if pixel has to be drown one or more times
- while (accWidth >= srcSize[0]) {
- // decrease accum
- accWidth -= srcSize[0];
- *d++ = p;
- }
- }
- // if there should be more identical lines
- while (accHeight >= srcSize[1]) {
- accHeight -= srcSize[1];
- // copy previous line
- memcpy(d, d - destSize[0], 4 * destSize[0]);
- d += destSize[0];
- }
- }
- else {
- // if we skip a source line
- s += srcSize[0];
- }
- }
- }
-}
-
-// DeckLink object allocation
-static PyObject *DeckLink_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- // allocate object
- DeckLink * self = reinterpret_cast<DeckLink*>(type->tp_alloc(type, 0));
- // initialize object structure
- decklink_Reset(self);
- // m_leftEye is a python object, it's handled by python
- self->m_leftEye = NULL;
- self->m_rightEye = NULL;
- // return allocated object
- return reinterpret_cast<PyObject*>(self);
-}
-
-
-// forward declaration
-PyObject *DeckLink_close(DeckLink *self);
-int DeckLink_setSource(DeckLink *self, PyObject *value, void *closure);
-
-
-// DeckLink object deallocation
-static void DeckLink_dealloc(DeckLink *self)
-{
- // release renderer
- Py_XDECREF(self->m_leftEye);
- // close decklink
- PyObject *ret = DeckLink_close(self);
- Py_DECREF(ret);
- // release object
- Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
-}
-
-
-ExceptionID AutoDetectionNotAvail, DeckLinkOpenCard, DeckLinkBadFormat, DeckLinkInternalError;
-ExpDesc AutoDetectionNotAvailDesc(AutoDetectionNotAvail, "Auto detection not yet available");
-ExpDesc DeckLinkOpenCardDesc(DeckLinkOpenCard, "Cannot open card for output");
-ExpDesc DeckLinkBadFormatDesc(DeckLinkBadFormat, "Invalid or unsupported output format, use <mode>[/3D]");
-ExpDesc DeckLinkInternalErrorDesc(DeckLinkInternalError, "DeckLink API internal error, please report");
-
-// DeckLink object initialization
-static int DeckLink_init(DeckLink *self, PyObject *args, PyObject *kwds)
-{
- IDeckLinkIterator* pIterator;
- IDeckLinkAttributes* pAttributes;
- IDeckLinkDisplayModeIterator* pDisplayModeIterator;
- IDeckLinkDisplayMode* pDisplayMode;
- IDeckLink* pDL;
- char* p3D;
- BOOL flag;
- size_t len;
- int i;
- uint32_t displayFlags;
- BMDVideoOutputFlags outputFlags;
- BMDDisplayModeSupport support;
- uint32_t* bytes;
-
-
- // material ID
- short cardIdx = 0;
- // texture ID
- char *format = NULL;
-
- static const char *kwlist[] = {"cardIdx", "format", NULL};
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|hs",
- const_cast<char**>(kwlist), &cardIdx, &format))
- return -1;
-
- try {
- if (format == NULL) {
- THRWEXCP(AutoDetectionNotAvail, S_OK);
- }
-
- if ((p3D = strchr(format, '/')) != NULL && strcmp(p3D, "/3D"))
- THRWEXCP(DeckLinkBadFormat, S_OK);
- self->mUse3D = (p3D) ? true : false;
- // read the mode
- len = (p3D) ? (size_t)(p3D - format) : strlen(format);
- // throws if bad mode
- decklink_ReadDisplayMode(format, len, &self->mDisplayMode);
-
- pIterator = BMD_CreateDeckLinkIterator();
- pDL = NULL;
- if (pIterator) {
- i = 0;
- while (pIterator->Next(&pDL) == S_OK) {
- if (i == cardIdx) {
- break;
- }
- i++;
- pDL->Release();
- pDL = NULL;
- }
- pIterator->Release();
- }
-
- if (!pDL) {
- THRWEXCP(DeckLinkOpenCard, S_OK);
- }
- // detect the capabilities
- if (pDL->QueryInterface(IID_IDeckLinkAttributes, (void**)&pAttributes) == S_OK) {
- if (pAttributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &flag) == S_OK && flag) {
- self->mKeyingSupported = true;
- if (pAttributes->GetFlag(BMDDeckLinkSupportsHDKeying, &flag) == S_OK && flag) {
- self->mHDKeyingSupported = true;
- }
- }
- pAttributes->Release();
- }
-
- if (pDL->QueryInterface(IID_IDeckLinkOutput, (void**)&self->mDLOutput) != S_OK) {
- self->mDLOutput = NULL;
- }
- if (self->mKeyingSupported) {
- pDL->QueryInterface(IID_IDeckLinkKeyer, (void **)&self->mKeyer);
- }
- // we don't need the device anymore, release to avoid leaking
- pDL->Release();
-
- if (!self->mDLOutput)
- THRWEXCP(DeckLinkOpenCard, S_OK);
-
- if (self->mDLOutput->GetDisplayModeIterator(&pDisplayModeIterator) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
-
- displayFlags = (self->mUse3D) ? bmdDisplayModeSupports3D : 0;
- outputFlags = (self->mUse3D) ? bmdVideoOutputDualStream3D : bmdVideoOutputFlagDefault;
- pDisplayMode = NULL;
- i = 0;
- while (pDisplayModeIterator->Next(&pDisplayMode) == S_OK) {
- if (pDisplayMode->GetDisplayMode() == self->mDisplayMode
- && (pDisplayMode->GetFlags() & displayFlags) == displayFlags) {
- if (self->mDLOutput->DoesSupportVideoMode(self->mDisplayMode, bmdFormat8BitBGRA, outputFlags, &support, NULL) != S_OK ||
- support == bmdDisplayModeNotSupported)
- {
- printf("Warning: DeckLink card %d reports no BGRA support, proceed anyway\n", cardIdx);
- }
- break;
- }
- pDisplayMode->Release();
- pDisplayMode = NULL;
- i++;
- }
- pDisplayModeIterator->Release();
-
- if (!pDisplayMode)
- THRWEXCP(DeckLinkBadFormat, S_OK);
- self->mSize[0] = pDisplayMode->GetWidth();
- self->mSize[1] = pDisplayMode->GetHeight();
- self->mFrameSize = 4*self->mSize[0]*self->mSize[1];
- pDisplayMode->Release();
- if (self->mDLOutput->EnableVideoOutput(self->mDisplayMode, outputFlags) != S_OK)
- // this shouldn't fail
- THRWEXCP(DeckLinkOpenCard, S_OK);
-
- if (self->mDLOutput->CreateVideoFrame(self->mSize[0], self->mSize[1], self->mSize[0] * 4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &self->mLeftFrame) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
- // clear alpha channel in the frame buffer
- self->mLeftFrame->GetBytes((void **)&bytes);
- memset(bytes, 0, self->mFrameSize);
- if (self->mUse3D) {
- if (self->mDLOutput->CreateVideoFrame(self->mSize[0], self->mSize[1], self->mSize[0] * 4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &self->mRightFrame) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
- // clear alpha channel in the frame buffer
- self->mRightFrame->GetBytes((void **)&bytes);
- memset(bytes, 0, self->mFrameSize);
- }
- }
- catch (Exception & exp)
- {
- printf("DeckLink: exception when opening card %d: %s\n", cardIdx, exp.what());
- exp.report();
- // normally, the object should be deallocated
- return -1;
- }
- // initialization succeeded
- return 0;
-}
-
-
-// close added decklink
-PyObject *DeckLink_close(DeckLink * self)
-{
- if (self->mLeftFrame)
- self->mLeftFrame->Release();
- if (self->mRightFrame)
- self->mRightFrame->Release();
- if (self->mKeyer)
- self->mKeyer->Release();
- if (self->mDLOutput)
- self->mDLOutput->Release();
- decklink_Reset(self);
- Py_RETURN_NONE;
-}
-
-
-// refresh decklink key frame
-static PyObject *DeckLink_refresh(DeckLink *self, PyObject *args)
-{
- // get parameter - refresh source
- PyObject *param;
- double ts = -1.0;
-
- if (!PyArg_ParseTuple(args, "O|d:refresh", &param, &ts) || !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 key frame in decklink,
- // 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);
- uint32_t *leftEye = NULL;
- uint32_t *rightEye = NULL;
- // try to process key frame from source
- try {
- // check if optimization is possible
- if (self->m_leftEye != NULL) {
- ImageBase *leftImage = self->m_leftEye->m_image;
- short * srcSize = leftImage->getSize();
- self->mLeftFrame->GetBytes((void **)&leftEye);
- if (srcSize[0] == self->mSize[0] && srcSize[1] == self->mSize[1])
- {
- // buffer has same size, can load directly
- if (!leftImage->loadImage(leftEye, self->mFrameSize, GL_BGRA, ts))
- leftEye = NULL;
- }
- else {
- // scaling is required, go the hard way
- unsigned int *src = leftImage->getImage(0, ts);
- if (src != NULL)
- decklink_ConvImage(leftEye, self->mSize, src, srcSize, self->mUseExtend);
- else
- leftEye = NULL;
- }
- }
- if (leftEye) {
- if (self->mUse3D && self->m_rightEye != NULL) {
- ImageBase *rightImage = self->m_rightEye->m_image;
- short * srcSize = rightImage->getSize();
- self->mRightFrame->GetBytes((void **)&rightEye);
- if (srcSize[0] == self->mSize[0] && srcSize[1] == self->mSize[1])
- {
- // buffer has same size, can load directly
- rightImage->loadImage(rightEye, self->mFrameSize, GL_BGRA, ts);
- }
- else {
- // scaling is required, go the hard way
- unsigned int *src = rightImage->getImage(0, ts);
- if (src != NULL)
- decklink_ConvImage(rightEye, self->mSize, src, srcSize, self->mUseExtend);
- }
- }
- if (self->mUse3D) {
- DeckLink3DFrameWrapper frame3D(
- (IDeckLinkVideoFrame*)self->mLeftFrame,
- (IDeckLinkVideoFrame*)self->mRightFrame);
- self->mDLOutput->DisplayVideoFrameSync(&frame3D);
- }
- else {
- self->mDLOutput->DisplayVideoFrameSync((IDeckLinkVideoFrame*)self->mLeftFrame);
- }
- }
- // refresh texture source, if required
- if (refreshSource) {
- if (self->m_leftEye)
- self->m_leftEye->m_image->refresh();
- if (self->m_rightEye)
- self->m_rightEye->m_image->refresh();
- }
- }
- CATCH_EXCP;
- }
- Py_RETURN_NONE;
-}
-
-// get source object
-static PyObject *DeckLink_getSource(DeckLink *self, PyObject *value, void *closure)
-{
- // if source exists
- if (self->m_leftEye != NULL) {
- Py_INCREF(self->m_leftEye);
- return reinterpret_cast<PyObject*>(self->m_leftEye);
- }
- // otherwise return None
- Py_RETURN_NONE;
-}
-
-
-// set source object
-int DeckLink_setSource(DeckLink *self, PyObject *value, void *closure)
-{
- // check new value
- if (value == NULL || !pyImageTypes.in(Py_TYPE(value))) {
- // 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_leftEye);
- // set new value
- self->m_leftEye = reinterpret_cast<PyImage*>(value);
- // return success
- return 0;
-}
-
-// get source object
-static PyObject *DeckLink_getRight(DeckLink *self, PyObject *value, void *closure)
-{
- // if source exists
- if (self->m_rightEye != NULL)
- {
- Py_INCREF(self->m_rightEye);
- return reinterpret_cast<PyObject*>(self->m_rightEye);
- }
- // otherwise return None
- Py_RETURN_NONE;
-}
-
-
-// set source object
-static int DeckLink_setRight(DeckLink *self, PyObject *value, void *closure)
-{
- // check new value
- if (value == NULL || !pyImageTypes.in(Py_TYPE(value)))
- {
- // 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_rightEye);
- // set new value
- self->m_rightEye = reinterpret_cast<PyImage*>(value);
- // return success
- return 0;
-}
-
-
-static PyObject *DeckLink_getKeying(DeckLink *self, PyObject *value, void *closure)
-{
- if (self->mUseKeying) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-static int DeckLink_setKeying(DeckLink *self, PyObject *value, void *closure)
-{
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- if (self->mKeyer != NULL)
- {
- if (value == Py_True)
- {
- if (self->mKeyer->Enable(false) != S_OK)
- {
- PyErr_SetString(PyExc_RuntimeError, "Error enabling keyer");
- return -1;
- }
- self->mUseKeying = true;
- self->mKeyer->SetLevel(self->mKeyingLevel);
- }
- else
- {
- self->mKeyer->Disable();
- self->mUseKeying = false;
- }
- }
- // success
- return 0;
-}
-
-static PyObject *DeckLink_getLevel(DeckLink *self, PyObject *value, void *closure)
-{
- return Py_BuildValue("h", self->mKeyingLevel);
-}
-
-static int DeckLink_setLevel(DeckLink *self, PyObject *value, void *closure)
-{
- long level;
- if (value == NULL || !PyLong_Check(value)) {
- PyErr_SetString(PyExc_TypeError, "The value must be an integer from 0 to 255");
- return -1;
- }
- level = PyLong_AsLong(value);
- if (level > 255)
- level = 255;
- else if (level < 0)
- level = 0;
- self->mKeyingLevel = (uint8_t)level;
- if (self->mUseKeying) {
- if (self->mKeyer->SetLevel(self->mKeyingLevel) != S_OK) {
- PyErr_SetString(PyExc_RuntimeError, "Error changin level of keyer");
- return -1;
- }
- }
- // success
- return 0;
-}
-
-static PyObject *DeckLink_getExtend(DeckLink *self, PyObject *value, void *closure)
-{
- if (self->mUseExtend) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-static int DeckLink_setExtend(DeckLink *self, PyObject *value, void *closure)
-{
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- self->mUseExtend = (value == Py_True);
- return 0;
-}
-
-// class DeckLink methods
-static PyMethodDef decklinkMethods[] =
-{
- { "close", (PyCFunction)DeckLink_close, METH_NOARGS, "Close dynamic decklink and restore original"},
- { "refresh", (PyCFunction)DeckLink_refresh, METH_VARARGS, "Refresh decklink from source"},
- {NULL} /* Sentinel */
-};
-
-// class DeckLink attributes
-static PyGetSetDef decklinkGetSets[] =
-{
- { (char*)"source", (getter)DeckLink_getSource, (setter)DeckLink_setSource, (char*)"source of decklink (left eye)", NULL},
- { (char*)"right", (getter)DeckLink_getRight, (setter)DeckLink_setRight, (char*)"source of decklink (right eye)", NULL },
- { (char*)"keying", (getter)DeckLink_getKeying, (setter)DeckLink_setKeying, (char*)"whether keying is enabled (frame is alpha-composited with passthrough output)", NULL },
- { (char*)"level", (getter)DeckLink_getLevel, (setter)DeckLink_setLevel, (char*)"change the level of keying (overall alpha level of key frame, 0 to 255)", NULL },
- { (char*)"extend", (getter)DeckLink_getExtend, (setter)DeckLink_setExtend, (char*)"whether image should stretched to fit frame", NULL },
- { NULL }
-};
-
-
-// class DeckLink declaration
-PyTypeObject DeckLinkType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.DeckLink", /*tp_name*/
- sizeof(DeckLink), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)DeckLink_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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "DeckLink objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- decklinkMethods, /* tp_methods */
- 0, /* tp_members */
- decklinkGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)DeckLink_init, /* tp_init */
- 0, /* tp_alloc */
- DeckLink_new, /* tp_new */
-};
-
-#endif /* WITH_GAMEENGINE_DECKLINK */
diff --git a/source/gameengine/VideoTexture/DeckLink.h b/source/gameengine/VideoTexture/DeckLink.h
deleted file mode 100644
index 4528fe7cec0..00000000000
--- a/source/gameengine/VideoTexture/DeckLink.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2015, Blender Foundation
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Blender Foundation.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoTexture/DeckLink.h
- * \ingroup bgevideotex
- */
-
-#ifndef __DECKLINK_H__
-#define __DECKLINK_H__
-
-#ifdef WITH_GAMEENGINE_DECKLINK
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "DNA_image_types.h"
-
-#include "DeckLinkAPI.h"
-
-#include "ImageBase.h"
-#include "BlendType.h"
-#include "Exception.h"
-
-
-// type DeckLink declaration
-struct DeckLink
-{
- PyObject_HEAD
-
- // last refresh
- double m_lastClock;
- // decklink card to which we output
- IDeckLinkOutput * mDLOutput;
- IDeckLinkKeyer * mKeyer;
- IDeckLinkMutableVideoFrame *mLeftFrame;
- IDeckLinkMutableVideoFrame *mRightFrame;
- bool mUse3D;
- bool mUseKeying;
- bool mUseExtend;
- bool mKeyingSupported;
- bool mHDKeyingSupported;
- uint8_t mKeyingLevel;
- BMDDisplayMode mDisplayMode;
- short mSize[2];
- uint32_t mFrameSize;
-
- // image source
- PyImage * m_leftEye;
- PyImage * m_rightEye;
-};
-
-
-// DeckLink type description
-extern PyTypeObject DeckLinkType;
-
-// helper function
-HRESULT decklink_ReadDisplayMode(const char *format, size_t len, BMDDisplayMode *displayMode);
-HRESULT decklink_ReadPixelFormat(const char *format, size_t len, BMDPixelFormat *displayMode);
-
-#endif /* WITH_GAMEENGINE_DECKLINK */
-
-#endif /* __DECKLINK_H__ */
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
deleted file mode 100644
index 9f82987ea62..00000000000
--- a/source/gameengine/VideoTexture/Exception.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/Exception.cpp
- * \ingroup bgevideotex
- */
-
-#include <sstream>
-#include <fstream>
-
-#include "EXP_PyObjectPlus.h"
-
-#include "Exception.h"
-
-
-// exception identificators
-ExceptionID ErrGeneral, ErrNotFound;
-
-// exception descriptions
-ExpDesc errGenerDesc(ErrGeneral, "General Error");
-ExpDesc errNFoundDesc(ErrNotFound, "Error description not found");
-
-
-
-// implementation of ExpDesc
-
-// constructor
-ExpDesc::ExpDesc (ExceptionID & exp, const char *desc, RESULT hres)
-: m_expID(exp), m_hRslt(hres), m_description(desc)
-{
-}
-
-// destructor
-ExpDesc::~ExpDesc (void) {}
-
-// list of descriptions
-std::vector<ExpDesc*> ExpDesc::m_expDescs;
-
-
-// class Exception
-
-
-// last exception description
-std::string Exception::m_lastError;
-
-// log file name
-const 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, const char *fil, int lin)
-: m_expID (&expID), m_hRslt (rslt)
-{
- // set file and line
- if (fil[0] != '\0' || lin > 0)
- setFileLine (fil, lin);
- else
- m_line = -1;
-}
-
-
-// set file and line
-void Exception::setFileLine (const char *fil, int lin)
-{
- if (fil != NULL) m_fileName = fil;
- m_line = lin;
-}
-
-
-// report exception
-void Exception::report(void)
-{
- // set exception description
- setXptDesc();
- // set python error
- PyErr_SetString(PyExc_RuntimeError, what());
- // if log file is set
- if (m_logFile != NULL)
- {
- // write description to log
- std::ofstream logf (m_logFile, std::ios_base::app);
- logf << m_fileName << ':' << m_line << ':' << m_desc << std::endl;
- logf.flush();
- logf.close();
- }
-}
-
-
-// set exception description
-void Exception::setXptDesc (void)
-{
- // if description is not set
- if (m_desc.size() == 0)
- {
- // start of search -1
- // found description "NotFound" 0
- // found description without matching result 1
- // found description with matching result 2
- int best = -1;
- // find exception description
- for (std::vector<ExpDesc*>::iterator it = ExpDesc::m_expDescs.begin(); it != ExpDesc::m_expDescs.end(); ++it)
- {
- // use "NotFound", if there is not better
- if (best < 0 && (*it)->isExp(&ErrNotFound) > 0)
- {
- (*it)->loadDesc(m_desc);
- best = 0;
- }
- // match exception
- int nBest = (*it)->isExp(m_expID, m_hRslt);
- // if exception is matching better
- if (nBest > 0 && best < nBest)
- {
- // set description
- (*it)->loadDesc(m_desc);
- best = nBest;
- // if matching exactly, finish search
- if (best == 2) break;
- }
- }
- // add result code
- // length of result code
- const size_t rsltSize = 11;
- // delimit description
- //const char delimRslt[] = ": ";
- // set text of description
- char rsltTxt[rsltSize];
- std::ostringstream os;
- os << std::hex << m_hRslt << ": " << '\0';
- // copy result to description
- m_desc.insert(0, rsltTxt);
- // copy exception description to last exception string
- m_lastError = m_desc;
- }
-}
-
-
-// copy exception data
-void Exception::copy (const Exception & xpt)
-{
- // standard data
- m_expID = xpt.m_expID;
- m_hRslt = xpt.m_hRslt;
- m_desc = xpt.m_desc;
-
- // debug data
- m_fileName = xpt.m_fileName;
- m_line = xpt.m_line;
-}
-
-void registerAllExceptions(void)
-{
- errGenerDesc.registerDesc();
- errNFoundDesc.registerDesc();
- MaterialNotAvailDesc.registerDesc();
- ImageSizesNotMatchDesc.registerDesc();
- ImageHasExportsDesc.registerDesc();
- InvalidColorChannelDesc.registerDesc();
- InvalidImageModeDesc.registerDesc();
- SceneInvalidDesc.registerDesc();
- CameraInvalidDesc.registerDesc();
- ObserverInvalidDesc.registerDesc();
- MirrorInvalidDesc.registerDesc();
- MirrorSizeInvalidDesc.registerDesc();
- MirrorNormalInvalidDesc.registerDesc();
- MirrorHorizontalDesc.registerDesc();
- MirrorTooSmallDesc.registerDesc();
- SourceVideoEmptyDesc.registerDesc();
- SourceVideoCreationDesc.registerDesc();
- OffScreenInvalidDesc.registerDesc();
-#ifdef WITH_GAMEENGINE_DECKLINK
- AutoDetectionNotAvailDesc.registerDesc();
- DeckLinkBadDisplayModeDesc.registerDesc();
- DeckLinkBadPixelFormatDesc.registerDesc();
- DeckLinkOpenCardDesc.registerDesc();
- DeckLinkBadFormatDesc.registerDesc();
- DeckLinkInternalErrorDesc.registerDesc();
- SourceVideoOnlyCaptureDesc.registerDesc();
- VideoDeckLinkBadFormatDesc.registerDesc();
- VideoDeckLinkOpenCardDesc.registerDesc();
- VideoDeckLinkDvpInternalErrorDesc.registerDesc();
- VideoDeckLinkPinMemoryErrorDesc.registerDesc();
-#endif
-}
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
deleted file mode 100644
index c4de85ff34d..00000000000
--- a/source/gameengine/VideoTexture/Exception.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/Exception.h
- * \ingroup bgevideotex
- */
-
-#ifndef __EXCEPTION_H__
-#define __EXCEPTION_H__
-
-#include <exception>
-#include <vector>
-#include <string>
-#include <algorithm>
-
-#include "Common.h"
-
-
-#define CHCKHRSLTV(fnc,val,err) \
-{ \
- HRESULT macroHRslt = (fnc); \
- if (macroHRslt != val) \
- throw Exception (err, macroHRslt, __FILE__, __LINE__); \
-}
-
-#define THRWEXCP(err,hRslt) throw Exception (err, hRslt, __FILE__, __LINE__)
-
-
-#if defined WIN32
-
-#define CHCKHRSLT(fnc,err) \
-{ \
- HRESULT macroHRslt = (fnc); \
- if (FAILED(macroHRslt)) \
- throw Exception (err, macroHRslt, __FILE__, __LINE__); \
-}
-
-#else
-
-#define CHCKHRSLT(fnc,err) CHCKHRSLTV(fnc,S_OK,err)
-
-#endif
-
-
-// forward declarations
-class ExceptionID;
-class Exception;
-
-
-// exception identificators
-extern ExceptionID ErrGeneral, ErrNotFound;
-
-
-// result type
-typedef long RESULT;
-
-
-// class ExceptionID for exception identification
-class ExceptionID
-{
-public:
- // constructor a destructor
- ExceptionID (void) {}
- ~ExceptionID (void) {}
-
-private:
- // not allowed
- ExceptionID (const ExceptionID & obj) throw() {}
- ExceptionID & operator= (const ExceptionID & obj) throw() { return *this; }
-};
-
-
-// class ExpDesc for exception description
-class ExpDesc
-{
-public:
- // constructor a destructor
- ExpDesc (ExceptionID & exp, const char * desc, RESULT hres = S_OK);
- ~ExpDesc (void);
-
- // comparision function
- // returns 0, if exception identification don't match at all
- // returns 1, if only exception identification is matching
- // returns 2, if both exception identification and result are matching
- int isExp (ExceptionID *exp, RESULT hres = S_OK) throw()
- {
- // check exception identification
- if (&m_expID == exp)
- {
- // check result value
- if (m_hRslt == hres) return 2;
- // only identification match
- if (m_hRslt == S_OK) return 1;
- }
- // no match
- return 0;
- }
-
- // get exception description
- void loadDesc (std::string & desc) throw()
- {
- desc = m_description;
- }
-
- void registerDesc(void)
- {
- if (std::find(m_expDescs.begin(), m_expDescs.end(), this) == m_expDescs.end())
- m_expDescs.push_back(this);
- }
- // list of exception descriptions
- static std::vector<ExpDesc*> m_expDescs;
-
-private:
- // exception ID
- ExceptionID & m_expID;
- // result
- RESULT m_hRslt;
- // description
- const 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, const char * fil, int lin);
- // set source file and line of exception
- void setFileLine (const 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 const char * m_logFile;
-
-protected:
- // exception identification
- ExceptionID * m_expID;
- // RESULT code
- RESULT m_hRslt;
-
- // exception description
- std::string m_desc;
-
- // set exception description
- virtual void setXptDesc (void);
-
- // copy exception
- void copy (const Exception & xpt);
-
- // file name where exception was thrown
- std::string m_fileName;
- // line number in file
- int m_line;
-
-};
-
-extern ExpDesc MaterialNotAvailDesc;
-extern ExpDesc ImageSizesNotMatchDesc;
-extern ExpDesc ImageHasExportsDesc;
-extern ExpDesc InvalidColorChannelDesc;
-extern ExpDesc InvalidImageModeDesc;
-extern ExpDesc SceneInvalidDesc;
-extern ExpDesc CameraInvalidDesc;
-extern ExpDesc ObserverInvalidDesc;
-extern ExpDesc OffScreenInvalidDesc;
-extern ExpDesc MirrorInvalidDesc;
-extern ExpDesc MirrorSizeInvalidDesc;
-extern ExpDesc MirrorNormalInvalidDesc;
-extern ExpDesc MirrorHorizontalDesc;
-extern ExpDesc MirrorTooSmallDesc;
-extern ExpDesc SourceVideoEmptyDesc;
-extern ExpDesc SourceVideoCreationDesc;
-extern ExpDesc DeckLinkBadDisplayModeDesc;
-extern ExpDesc DeckLinkBadPixelFormatDesc;
-extern ExpDesc AutoDetectionNotAvailDesc;
-extern ExpDesc DeckLinkOpenCardDesc;
-extern ExpDesc DeckLinkBadFormatDesc;
-extern ExpDesc DeckLinkInternalErrorDesc;
-extern ExpDesc SourceVideoOnlyCaptureDesc;
-extern ExpDesc VideoDeckLinkBadFormatDesc;
-extern ExpDesc VideoDeckLinkOpenCardDesc;
-extern ExpDesc VideoDeckLinkDvpInternalErrorDesc;
-extern ExpDesc VideoDeckLinkPinMemoryErrorDesc;
-
-extern ExceptionID InvalidImageMode;
-
-void registerAllExceptions(void);
-#endif
diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp
deleted file mode 100644
index b41a2095890..00000000000
--- a/source/gameengine/VideoTexture/FilterBase.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/FilterBase.cpp
- * \ingroup bgevideotex
- */
-
-
-#include "FilterBase.h"
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-
-// FilterBase class implementation
-
-// constructor
-FilterBase::FilterBase (void) : m_previous(NULL) {}
-
-
-// destructor
-FilterBase::~FilterBase (void)
-{
- // release Python objects, if not released yet
- release();
-}
-
-
-// release python objects
-void FilterBase::release (void)
-{
- // release previous filter object
- setPrevious(NULL);
-}
-
-
-// set new previous filter
-void FilterBase::setPrevious(PyFilter *filt, bool useRefCnt)
-{
- // if reference counting has to be used
- if (useRefCnt)
- {
- // reference new filter
- if (filt != NULL) Py_INCREF(filt);
- // release old filter
- Py_XDECREF(m_previous);
- }
- // set new previous filter
- m_previous = filt;
-}
-
-
-// find first filter
-FilterBase * FilterBase::findFirst (void)
-{
- // find first filter in chain
- FilterBase * frst;
- for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter) {};
- // set first filter
- return frst;
-}
-
-
-
-// list offilter types
-PyTypeList pyFilterTypes;
-
-
-
-// functions for python interface
-
-
-// object allocation
-PyObject *Filter_allocNew (PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- // allocate object
- PyFilter *self = reinterpret_cast<PyFilter*>(type->tp_alloc(type, 0));
- // initialize object structure
- self->m_filter = NULL;
- // return allocated object
- return reinterpret_cast<PyObject*>(self);
-}
-
-// object deallocation
-void Filter_dealloc(PyFilter *self)
-{
- // release object attributes
- if (self->m_filter != NULL)
- {
- self->m_filter->release();
- delete self->m_filter;
- self->m_filter = NULL;
- }
- Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
-}
-
-
-// get previous pixel filter object
-PyObject *Filter_getPrevious (PyFilter *self, void *closure)
-{
- // if filter object is available
- if (self->m_filter != NULL)
- {
- // pixel filter object
- PyObject *filt = reinterpret_cast<PyObject*>(self->m_filter->getPrevious());
- // if filter is present
- if (filt != NULL)
- {
- // return it
- Py_INCREF(filt);
- return filt;
- }
- }
- // otherwise return none
- Py_RETURN_NONE;
-}
-
-
-// set previous pixel filter object
-int Filter_setPrevious(PyFilter *self, PyObject *value, void *closure)
-{
- // if filter object is available
- if (self->m_filter != NULL)
- {
- // check new value
- if (value == NULL || !pyFilterTypes.in(Py_TYPE(value)))
- {
- // report value error
- PyErr_SetString(PyExc_TypeError, "Invalid type of value");
- return -1;
- }
- // set new value
- self->m_filter->setPrevious(reinterpret_cast<PyFilter*>(value));
- }
- // return success
- return 0;
-}
diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h
deleted file mode 100644
index db688d551d0..00000000000
--- a/source/gameengine/VideoTexture/FilterBase.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file FilterBase.h
- * \ingroup bgevideotex
- */
-
-#ifndef __FILTERBASE_H__
-#define __FILTERBASE_H__
-
-#include "Common.h"
-
-#include "EXP_PyObjectPlus.h"
-
-#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
-
-#ifdef __BIG_ENDIAN__
-# define VT_SWAPBR(i) ((((i) >> 16) & 0xFF00) + (((i) & 0xFF00) << 16) + ((i) & 0xFF00FF))
-#else
-# define VT_SWAPBR(i) ((((i) & 0xFF) << 16) + (((i) >> 16) & 0xFF) + ((i) & 0xFF00FF00))
-#endif
-
-
-// forward declaration
-class FilterBase;
-
-
-// python structure for filter
-struct PyFilter
-{
- PyObject_HEAD
- // source object
- FilterBase * m_filter;
-};
-
-
-/// base class for pixel filters
-class FilterBase
-{
-public:
- /// constructor
- FilterBase (void);
- /// destructor
- virtual ~FilterBase (void);
- // release python objects
- virtual void release (void);
-
- /// convert pixel
- template <class SRC> unsigned int convert (SRC src, short x, short y,
- short * size, unsigned int pixSize)
- {
- return filter(src, x, y, size, pixSize,
- convertPrevious(src, x, y, size, pixSize));
- }
-
- /// get previous filter
- PyFilter * getPrevious (void) { return m_previous; }
- /// set previous filter
- void setPrevious (PyFilter *filt, bool useRefCnt = true);
-
- /// find first filter in chain
- FilterBase * findFirst (void);
-
- /// get first filter's source pixel size
- unsigned int firstPixelSize (void) { return findFirst()->getPixelSize(); }
-
-protected:
- /// previous pixel filter
- PyFilter * m_previous;
-
- /// filter pixel, source byte buffer
- virtual unsigned int filter(unsigned char *src, short x, short y,
- short *size, unsigned int pixSize, unsigned int val = 0)
- { return val; }
- /// filter pixel, source int buffer
- virtual unsigned int filter(unsigned int *src, short x, short y,
- short *size, unsigned int pixSize, unsigned int val = 0)
- { return val; }
- /// filter pixel, source float buffer
- virtual unsigned int filter(float *src, short x, short y,
- short *size, unsigned int pixSize, unsigned int val = 0)
- { return val; }
-
- /// get source pixel size
- virtual unsigned int getPixelSize(void) { return 1; }
-
- /// get converted pixel from previous filters
- template <class SRC> unsigned int convertPrevious (SRC src, short x, short y,
- short * size, unsigned int pixSize)
- {
- // if previous filter doesn't exists, return source pixel
- if (m_previous == NULL) return *src;
- // otherwise return converted pixel
- return m_previous->m_filter->convert(src, x, y, size, pixSize);
- }
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:FilterBase")
-#endif
-};
-
-
-// list of python filter types
-extern PyTypeList pyFilterTypes;
-
-
-// functions for python interface
-
-// object initialization
-template <class T> static int Filter_init (PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- PyFilter *self = reinterpret_cast<PyFilter*>(pySelf);
- // create filter object
- if (self->m_filter != NULL) delete self->m_filter;
- self->m_filter = new T();
- // initialization succeded
- return 0;
-}
-
-// object allocation
-PyObject *Filter_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds);
-// object deallocation
-void Filter_dealloc(PyFilter *self);
-
-// get previous pixel filter object
-PyObject *Filter_getPrevious(PyFilter *self, void *closure);
-// set previous pixel filter object
-int Filter_setPrevious(PyFilter *self, PyObject *value, void *closure);
-
-
-#endif
diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp
deleted file mode 100644
index a25d09e1eee..00000000000
--- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/FilterBlueScreen.cpp
- * \ingroup bgevideotex
- */
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterBlueScreen.h"
-
-#include "FilterBase.h"
-#include "PyTypeList.h"
-
-// implementation FilterBlueScreen
-
-// constructor
-FilterBlueScreen::FilterBlueScreen (void)
-{
- // set color to blue
- setColor(0, 0, 255);
- // set limits
- setLimits(64, 64);
-}
-
-// set color
-void FilterBlueScreen::setColor (unsigned char red, unsigned char green, unsigned char blue)
-{
- m_color[0] = red;
- m_color[1] = green;
- m_color[2] = blue;
-}
-
-// set limits for color variation
-void FilterBlueScreen::setLimits (unsigned short minLimit, unsigned short maxLimit)
-{
- m_limits[0] = minLimit;
- m_limits[1] = maxLimit > minLimit ? maxLimit : minLimit;
- // calculate square values
- for (short idx = 0; idx < 2; ++idx)
- m_squareLimits[idx] = m_limits[idx] * m_limits[idx];
- // limits distance
- m_limitDist = m_squareLimits[1] - m_squareLimits[0];
-}
-
-
-
-// cast Filter pointer to FilterBlueScreen
-inline FilterBlueScreen * getFilter (PyFilter *self)
-{ return static_cast<FilterBlueScreen*>(self->m_filter); }
-
-
-// python methods and get/sets
-
-// get color
-static PyObject *getColor (PyFilter *self, void *closure)
-{
- return Py_BuildValue("[BBB]", getFilter(self)->getColor()[0],
- getFilter(self)->getColor()[1], getFilter(self)->getColor()[2]);
-}
-
-// set color
-static int setColor(PyFilter *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL ||
- !(PyTuple_Check(value) || PyList_Check(value)) ||
- PySequence_Fast_GET_SIZE(value) != 3 ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)) ||
- !PyLong_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)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
- (unsigned char)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
- (unsigned char)(PyLong_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 ||
- !(PyTuple_Check(value) || PyList_Check(value)) ||
- PySequence_Fast_GET_SIZE(value) != 2 ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) ||
- !PyLong_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)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
- (unsigned short)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 1))));
- // success
- return 0;
-}
-
-
-// attributes structure
-static PyGetSetDef filterBSGetSets[] =
-{
- {(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
- {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
- {NULL}
-};
-
-// define python type
-PyTypeObject FilterBlueScreenType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterBlueScreen", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Filter for Blue Screen objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- filterBSGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterBlueScreen>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h
deleted file mode 100644
index cf74a6705b7..00000000000
--- a/source/gameengine/VideoTexture/FilterBlueScreen.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file FilterBlueScreen.h
- * \ingroup bgevideotex
- */
-
-#ifndef __FILTERBLUESCREEN_H__
-#define __FILTERBLUESCREEN_H__
-
-#include "Common.h"
-
-#include "FilterBase.h"
-
-
-/// pixel filter for blue screen
-class FilterBlueScreen : public FilterBase
-{
-public:
- /// constructor
- FilterBlueScreen (void);
- /// destructor
- virtual ~FilterBlueScreen (void) {}
-
- /// get color
- unsigned char * getColor (void) { return m_color; }
- /// set color
- void setColor (unsigned char red, unsigned char green, unsigned char blue);
-
- /// get limits for color variation
- unsigned short * getLimits (void) { return m_limits; }
- /// set limits for color variation
- void setLimits (unsigned short minLimit, unsigned short maxLimit);
-
-protected:
- /// blue screen color (red component first)
- unsigned char m_color[3];
- /// limits for color variation - first defines, where ends fully transparent
- /// color, second defines, where begins fully opaque color
- unsigned short m_limits[2];
- /// squared limits for color variation
- unsigned int m_squareLimits[2];
- /// distance between squared limits
- unsigned int m_limitDist;
-
- /// filter pixel template, source int buffer
- template <class SRC> unsigned int tFilter (SRC src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val)
- {
- // calculate differences
- int difRed = int(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
- VT_A(val) = 0;
- // condition for fully opaque color
- else if (m_squareLimits[1] <= dist)
- // return normal color
- VT_A(val) = 0xFF;
- // otherwise calc alpha
- else
- VT_A(val) = (((dist - m_squareLimits[0]) << 8) / m_limitDist);
- return val;
- }
-
- /// virtual filtering function for byte source
- virtual unsigned int filter (unsigned char *src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
- /// virtual filtering function for unsigned int source
- virtual unsigned int filter (unsigned int *src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
-};
-
-
-#endif
diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp
deleted file mode 100644
index 15a7e9e4cd1..00000000000
--- a/source/gameengine/VideoTexture/FilterColor.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/FilterColor.cpp
- * \ingroup bgevideotex
- */
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterColor.h"
-
-#include "FilterBase.h"
-#include "PyTypeList.h"
-
-// implementation FilterGray
-
-// attributes structure
-static PyGetSetDef filterGrayGetSets[] =
-{ // attributes from FilterBase class
- {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
- {NULL}
-};
-
-// define python type
-PyTypeObject FilterGrayType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "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 grayscale effect", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- filterGrayGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterGray>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
-
-// implementation FilterColor
-
-// constructor
-FilterColor::FilterColor (void)
-{
- // reset color matrix to identity
- for (int r = 0; r < 4; ++r)
- for (int c = 0; c < 5; ++c)
- m_matrix[r][c] = (r == c) ? 256 : 0;
-}
-
-// set color matrix
-void FilterColor::setMatrix (ColorMatrix & mat)
-{
- // copy matrix
- for (int r = 0; r < 4; ++r)
- for (int c = 0; c < 5; ++c)
- m_matrix[r][c] = mat[r][c];
-}
-
-
-
-// cast Filter pointer to FilterColor
-inline FilterColor * getFilterColor (PyFilter *self)
-{ return static_cast<FilterColor*>(self->m_filter); }
-
-
-// python methods and get/sets
-
-// get color matrix
-static PyObject *getMatrix (PyFilter *self, void *closure)
-{
- ColorMatrix & mat = getFilterColor(self)->getMatrix();
- return Py_BuildValue("((hhhhh)(hhhhh)(hhhhh)(hhhhh))",
- mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat[0][4],
- mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat[1][4],
- mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat[2][4],
- mat[3][0], mat[3][1], mat[3][2], mat[3][3], mat[3][4]);
-}
-
-// set color matrix
-static int setMatrix(PyFilter *self, PyObject *value, void *closure)
-{
- // matrix to store items
- ColorMatrix mat;
- // check validity of parameter
- bool valid = value != NULL && PySequence_Check(value)
- && PySequence_Size(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_Size(row) == 5;
- // check items
- for (int c = 0; valid && c < 5; ++c)
- {
- // item must be int
- valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c));
- // if it is valid, save it in matrix
- if (valid)
- mat[r][c] = short(PyLong_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[] =
-{
- {(char*)"matrix", (getter)getMatrix, (setter)setMatrix, (char*)"matrix [4][5] for color calculation", NULL},
- // attributes from FilterBase class
- {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
- {NULL}
-};
-
-// define python type
-PyTypeObject FilterColorType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterColor", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Filter for color calculations", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- filterColorGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterColor>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
-// implementation FilterLevel
-
-// constructor
-FilterLevel::FilterLevel (void)
-{
- // reset color levels
- for (int r = 0; r < 4; ++r)
- {
- levels[r][0] = 0;
- levels[r][1] = 0xFF;
- 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];
- levels[r][2] = lev[r][0] < lev[r][1] ? lev[r][1] - lev[r][0] : 1;
- }
-}
-
-
-// cast Filter pointer to FilterLevel
-inline FilterLevel * getFilterLevel (PyFilter *self)
-{ return static_cast<FilterLevel*>(self->m_filter); }
-
-
-// python methods and get/sets
-
-// get color levels
-static PyObject *getLevels (PyFilter *self, void *closure)
-{
- ColorLevel & lev = getFilterLevel(self)->getLevels();
- return Py_BuildValue("((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
-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_Size(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_Size(row) == 2;
- // check items
- for (int c = 0; valid && c < 2; ++c)
- {
- // item must be int
- valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c));
- // if it is valid, save it in matrix
- if (valid)
- lev[r][c] = (unsigned short)(PyLong_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[] =
-{
- {(char*)"levels", (getter)getLevels, (setter)setLevels, (char*)"levels matrix [4] (min, max)", NULL},
- // attributes from FilterBase class
- {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
- {NULL}
-};
-
-// define python type
-PyTypeObject FilterLevelType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterLevel", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Filter for levels calculations", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- filterLevelGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterLevel>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h
deleted file mode 100644
index d042863d7e8..00000000000
--- a/source/gameengine/VideoTexture/FilterColor.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file FilterColor.h
- * \ingroup bgevideotex
- */
-
-#ifndef __FILTERCOLOR_H__
-#define __FILTERCOLOR_H__
-
-#include "Common.h"
-
-#include "FilterBase.h"
-
-
-/// pixel filter for grayscale
-class FilterGray : public FilterBase
-{
-public:
- /// constructor
- FilterGray (void) {}
- /// destructor
- virtual ~FilterGray (void) {}
-
-protected:
- /// filter pixel template, source int buffer
- template <class SRC> unsigned int tFilter (SRC src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val)
- {
- // calculate gray value
- unsigned int gray = (28 * (VT_B(val)) + 151 * (VT_G(val))
- + 77 * (VT_R(val))) >> 8;
- // return grayscale value
- VT_R(val) = gray;
- VT_G(val) = gray;
- VT_B(val) = gray;
- return val;
- }
-
- /// 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 char calcColor (unsigned int val, short idx)
- {
- 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
- template <class SRC> unsigned int tFilter (SRC src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val)
- {
- // return calculated color
- 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
- 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 short 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 = VT_C(val,idx);
- if (col <= levels[idx][0]) col = 0;
- else if (col >= levels[idx][1]) col = 0xFF;
- else col = (((col - levels[idx][0]) << 8) / levels[idx][2]) & 0xFF;
- return col;
- }
-
- /// filter pixel template, source int buffer
- template <class SRC> unsigned int tFilter (SRC src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val)
- {
- // return calculated color
- 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
- virtual unsigned int filter (unsigned char * src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
- /// virtual filtering function for unsigned int source
- virtual unsigned int filter (unsigned int * src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
-};
-
-
-#endif
diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp
deleted file mode 100644
index 3a5333710fd..00000000000
--- a/source/gameengine/VideoTexture/FilterNormal.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/FilterNormal.cpp
- * \ingroup bgevideotex
- */
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterNormal.h"
-
-#include "FilterBase.h"
-#include "PyTypeList.h"
-
-// implementation FilterNormal
-
-// constructor
-FilterNormal::FilterNormal (void) : m_colIdx(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_colIdx = colIdx;
-}
-
-// set depth
-void FilterNormal::setDepth (float depth)
-{
- m_depth = depth;
- m_depthScale = depth / depthScaleKoef;
-}
-
-
-// cast Filter pointer to FilterNormal
-inline FilterNormal * getFilter (PyFilter *self)
-{ return static_cast<FilterNormal*>(self->m_filter); }
-
-
-// python methods and get/sets
-
-// get index of color used to calculate normal
-static PyObject *getColor (PyFilter *self, void *closure)
-{
- return Py_BuildValue("H", getFilter(self)->getColor());
-}
-
-// set index of color used to calculate normal
-static int setColor(PyFilter *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL || !PyLong_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "filt.colorIdx = int: VideoTexture.FilterNormal, expected the value must be a int");
- return -1;
- }
- // set color index
- getFilter(self)->setColor((unsigned short)(PyLong_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)
- {
- float depth= (float)PyFloat_AsDouble(value);
- if ((depth==-1 && PyErr_Occurred()) == 0) /* no error converting to a float? */
- {
- // set depth
- getFilter(self)->setDepth(depth);
- // success
- return 0;
- }
- }
-
- PyErr_SetString(PyExc_TypeError, "filt.depth = float: VideoTexture.FilterNormal, expected the value must be a float");
- return -1;
-}
-
-
-// attributes structure
-static PyGetSetDef filterNormalGetSets[] =
-{
- {(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
- {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
- {NULL}
-};
-
-// define python type
-PyTypeObject FilterNormalType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterNormal", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Filter for Blue Screen objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- filterNormalGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterNormal>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h
deleted file mode 100644
index 951ecb84d9d..00000000000
--- a/source/gameengine/VideoTexture/FilterNormal.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file FilterNormal.h
- * \ingroup bgevideotex
- */
-
-#ifndef __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_colIdx; }
- /// 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;
-
- /// color index, 0=red, 1=green, 2=blue, 3=alpha
- unsigned short m_colIdx;
-
- /// filter pixel, source int buffer
- template <class SRC> unsigned int tFilter (SRC *src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- {
- // get value of required color
- int actPix = int(VT_C(val,m_colIdx));
- int upPix = actPix;
- int leftPix = actPix;
- // get upper and left pixel from actual pixel
- 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;
- // 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
- VT_RGBA(val, dx, dy, dz, 0xFF);
- return val;
- }
-
- /// filter pixel, source byte buffer
- virtual unsigned int filter (unsigned char * src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
- /// filter pixel, source int buffer
- virtual unsigned int filter (unsigned int * src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- { return tFilter(src, x, y, size, pixSize, val); }
-};
-
-
-#endif
diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp
deleted file mode 100644
index c8faa1f9f07..00000000000
--- a/source/gameengine/VideoTexture/FilterSource.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/FilterSource.cpp
- * \ingroup bgevideotex
- */
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterSource.h"
-
-#include "FilterBase.h"
-#include "PyTypeList.h"
-
-
-// FilterRGB24
-
-// define python type
-PyTypeObject FilterRGB24Type =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterRGB24", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Source filter RGB24 objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- NULL, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterRGB24>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
-// FilterRGBA32
-
-// define python type
-PyTypeObject FilterRGBA32Type =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "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<FilterRGBA32>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
-// FilterBGR24
-
-// define python type
-PyTypeObject FilterBGR24Type =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.FilterBGR24", /*tp_name*/
- sizeof(PyFilter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Filter_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Source filter BGR24 objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NULL, /* tp_methods */
- 0, /* tp_members */
- NULL, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Filter_init<FilterBGR24>, /* tp_init */
- 0, /* tp_alloc */
- Filter_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h
deleted file mode 100644
index 820576dfff9..00000000000
--- a/source/gameengine/VideoTexture/FilterSource.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file FilterSource.h
- * \ingroup bgevideotex
- */
-
-#ifndef __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)
- { 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 BGRA32 conversion
-class FilterBGRA32 : public FilterBase
-{
-public:
- /// constructor
- FilterBGRA32 (void) {}
- /// destructor
- virtual ~FilterBGRA32 (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)
- {
- VT_RGBA(val,src[2],src[1],src[0],src[3]);
- return val;
- }
-};
-
-
-/// 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)
- { VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; }
-};
-
-/// class for Z_buffer conversion
-class FilterZZZA : public FilterBase
-{
-public:
- /// constructor
- FilterZZZA (void) {}
- /// destructor
- virtual ~FilterZZZA (void) {}
-
- /// get source pixel size
- virtual unsigned int getPixelSize (void) { return 1; }
-
-protected:
- /// filter pixel, source float buffer
- virtual unsigned int filter (float *src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val)
- {
- // calculate gray value
- // convert float to unsigned char
- unsigned int depth = int(src[0] * 255);
- // return depth scale value
- VT_R(val) = depth;
- VT_G(val) = depth;
- VT_B(val) = depth;
- VT_A(val) = 0xFF;
-
- return val;
- }
-};
-
-
-/// class for Z_buffer conversion
-class FilterDEPTH : public FilterBase
-{
-public:
- /// constructor
- FilterDEPTH (void) {}
- /// destructor
- virtual ~FilterDEPTH (void) {}
-
- /// get source pixel size
- virtual unsigned int getPixelSize (void) { return 1; }
-
-protected:
- /// filter pixel, source float buffer
- virtual unsigned int filter (float *src, short x, short y,
- short *size, unsigned int pixSize, unsigned int val)
- {
- /* Copy the float value straight away
- * The user can retrieve the original float value by using
- * 'F' mode in BGL buffer */
- memcpy(&val, src, sizeof (unsigned int));
- return val;
- }
-};
-
-
-
-
-/// class for YV12 conversion
-class FilterYV12 : public FilterBase
-{
-public:
- /// constructor
- FilterYV12 (void): m_buffV(NULL), m_buffU(NULL), m_pitchUV(0) {}
- /// 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, const short size[2])
- { 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) >> 8;
- if (green >= 0x100) green = 0xFF;
- else if (green < 0) green = 0;
- int blue = (298 * c + 516 * d + 128) >> 8;
- if (blue >= 0x100) blue = 0xFF;
- else if (blue < 0) blue = 0;
- // return result
- VT_RGBA(val, red, green, blue, 0xFF);
- return val;
- }
-};
-
-#endif /* __FILTERSOURCE_H__ */
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
deleted file mode 100644
index a547d2a7a85..00000000000
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageBase.cpp
- * \ingroup bgevideotex
- */
-
-#include "ImageBase.h"
-extern "C" {
-#include "bgl.h"
-}
-
-#include <vector>
-#include <string.h>
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterBase.h"
-
-#include "Exception.h"
-
-#if (defined(WIN32) || defined(WIN64))
-#define strcasecmp _stricmp
-#endif
-
-// ImageBase class implementation
-
-ExceptionID ImageHasExports;
-ExceptionID InvalidColorChannel;
-ExceptionID InvalidImageMode;
-
-ExpDesc ImageHasExportsDesc(ImageHasExports, "Image has exported buffers, cannot resize");
-ExpDesc InvalidColorChannelDesc(InvalidColorChannel, "Invalid or too many color channels specified. At most 4 values within R, G, B, A, 0, 1");
-ExpDesc InvalidImageModeDesc(InvalidImageMode, "Invalid image mode, only RGBA and BGRA are supported");
-
-// constructor
-ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0),
-m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
-m_zbuff(false),
-m_depth(false),
-m_staticSources(staticSrc), m_pyfilter(NULL)
-{
- m_size[0] = m_size[1] = 0;
- m_exports = 0;
-}
-
-
-// destructor
-ImageBase::~ImageBase (void)
-{
- // release image
- if (m_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, double ts)
-{
- // 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(ts);
- // init image
- init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
- }
- // calculate new image
- calcImage(texId, ts);
- }
- // if image is available, return it, otherwise NULL
- return m_avail ? m_image : NULL;
-}
-
-bool ImageBase::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
-{
- unsigned int *d, *s, v, len;
- if (getImage(0, ts) != NULL && size >= getBuffSize()) {
- switch (format) {
- case GL_RGBA:
- memcpy(buffer, m_image, getBuffSize());
- break;
- case GL_BGRA:
- len = (unsigned int)m_size[0] * m_size[1];
- for (s=m_image, d=buffer; len; len--) {
- v = *s++;
- *d++ = VT_SWAPBR(v);
- }
- break;
- default:
- THRWEXCP(InvalidImageMode,S_OK);
- }
- return true;
- }
- return false;
-}
-
-// 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;
-}
-
-void ImageBase::swapImageBR()
-{
- unsigned int size, v, *s;
-
- if (m_avail) {
- size = 1 * m_size[0] * m_size[1];
- for (s=m_image; size; size--) {
- v = *s;
- *s++ = VT_SWAPBR(v);
- }
- }
-}
-
-// 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])
- {
- if (m_exports > 0)
- THRWEXCP(ImageHasExports,S_OK);
-
- // 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
- if (m_image)
- 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 (double ts)
-{
- // if source is available
- if (m_source != NULL)
- // get image from source
- m_image = m_source->m_image->getImage(0, ts);
- // otherwise reset buffer
- else
- m_image = NULL;
- // return image
- return m_image;
-}
-
-
-// refresh source
-void ImageSource::refresh (void)
-{
- // if source is available, refresh it
- if (m_source != NULL) m_source->m_image->refresh();
-}
-
-
-
-// list of image types
-PyTypeList pyImageTypes;
-
-
-
-// functions for python interface
-
-// object allocation
-PyObject *Image_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- // allocate object
- PyImage *self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0));
- // initialize object structure
- self->m_image = NULL;
- // return allocated object
- return reinterpret_cast<PyObject*>(self);
-}
-
-// object deallocation
-void Image_dealloc(PyImage *self)
-{
- // release object attributes
- if (self->m_image != NULL)
- {
- if (self->m_image->m_exports > 0)
- {
- PyErr_SetString(PyExc_SystemError,
- "deallocated Image object has exported buffers");
- PyErr_Print();
- }
- // if release requires deleting of object, do it
- if (self->m_image->release())
- delete self->m_image;
- self->m_image = NULL;
- }
- Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
-}
-
-// get image data
-PyObject *Image_getImage(PyImage *self, char *mode)
-{
- try
- {
- unsigned int * image = self->m_image->getImage();
- if (image)
- {
- // build BGL buffer
- int dimensions = self->m_image->getBuffSize();
- Buffer * buffer;
- if (mode == NULL || !strcasecmp(mode, "RGBA"))
- {
- buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, image);
- }
- else if (!strcasecmp(mode, "F"))
- {
- // this mode returns the image as an array of float.
- // This makes sense ONLY for the depth buffer:
- // source = VideoTexture.ImageViewport()
- // source.depth = True
- // depth = VideoTexture.imageToArray(source, 'F')
-
- // adapt dimension from byte to float
- dimensions /= sizeof(float);
- buffer = BGL_MakeBuffer( GL_FLOAT, 1, &dimensions, image);
- }
- else
- {
- int i, c, ncolor, pixels;
- int offset[4];
- unsigned char *s, *d;
- // scan the mode to get the channels requested, no more than 4
- for (i=ncolor=0; mode[i] != 0 && ncolor < 4; i++)
- {
- switch (toupper(mode[i]))
- {
- case 'R':
- offset[ncolor++] = 0;
- break;
- case 'G':
- offset[ncolor++] = 1;
- break;
- case 'B':
- offset[ncolor++] = 2;
- break;
- case 'A':
- offset[ncolor++] = 3;
- break;
- case '0':
- offset[ncolor++] = -1;
- break;
- case '1':
- offset[ncolor++] = -2;
- break;
- // if you add more color code, change the switch further down
- default:
- THRWEXCP(InvalidColorChannel,S_OK);
- }
- }
- if (mode[i] != 0) {
- THRWEXCP(InvalidColorChannel,S_OK);
- }
- // first get the number of pixels
- pixels = dimensions / 4;
- // multiple by the number of channels, each is one byte
- dimensions = pixels * ncolor;
- // get an empty buffer
- buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL);
- // and fill it
- for (i = 0, d = (unsigned char *)buffer->buf.asbyte, s = (unsigned char *)image;
- i < pixels;
- i++, d += ncolor, s += 4)
- {
- for (c=0; c<ncolor; c++)
- {
- switch (offset[c])
- {
- case 0: d[c] = s[0]; break;
- case 1: d[c] = s[1]; break;
- case 2: d[c] = s[2]; break;
- case 3: d[c] = s[3]; break;
- case -1: d[c] = 0; break;
- case -2: d[c] = 0xFF; break;
- }
- }
- }
- }
- return (PyObject *)buffer;
- }
- }
- catch (Exception & exp)
- {
- exp.report();
- return NULL;
- }
- 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, PyObject *args)
-{
- Py_buffer buffer;
- bool done = true;
- char *mode = NULL;
- double ts = -1.0;
- unsigned int format;
-
- memset(&buffer, 0, sizeof(buffer));
- if (PyArg_ParseTuple(args, "|s*sd:refresh", &buffer, &mode, &ts)) {
- if (buffer.buf) {
- // a target buffer is provided, verify its format
- if (buffer.readonly) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be writable");
- }
- else if (!PyBuffer_IsContiguous(&buffer, 'C')) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be contiguous in memory");
- }
- else if (((intptr_t)buffer.buf & 3) != 0) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be aligned to 4 bytes boundary");
- }
- else {
- // ready to get the image into our buffer
- try {
- if (mode == NULL || !strcmp(mode, "RGBA"))
- format = GL_RGBA;
- else if (!strcmp(mode, "BGRA"))
- format = GL_BGRA;
- else
- THRWEXCP(InvalidImageMode,S_OK);
-
- done = self->m_image->loadImage((unsigned int *)buffer.buf, buffer.len, format, ts);
- }
- catch (Exception & exp) {
- exp.report();
- }
- }
- PyBuffer_Release(&buffer);
- if (PyErr_Occurred()) {
- return NULL;
- }
- }
- }
- else {
- return NULL;
- }
-
- self->m_image->refresh();
- if (done)
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
-}
-
-// 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 zbuff
-PyObject *Image_getZbuff(PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getZbuff()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set zbuff
-int Image_setZbuff(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->setZbuff(value == Py_True);
- // success
- return 0;
-}
-
-// get depth
-PyObject *Image_getDepth(PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getDepth()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set depth
-int Image_setDepth(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->setDepth(value == Py_True);
- // success
- return 0;
-}
-
-
-
-
-// get filter source object
-PyObject *Image_getSource(PyImage *self, PyObject *args)
-{
- // get arguments
- char *id;
- if (!PyArg_ParseTuple(args, "s:getSource", &id))
- return NULL;
- if (self->m_image != NULL)
- {
- // get source object
- PyObject *src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
- // if source is available
- if (src != NULL)
- {
- // return source
- Py_INCREF(src);
- return src;
- }
- }
- // source was not found
- Py_RETURN_NONE;
-}
-
-
-// set filter source object
-PyObject *Image_setSource(PyImage *self, PyObject *args)
-{
- // get arguments
- char *id;
- PyObject *obj;
- if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
- return NULL;
- if (self->m_image != NULL)
- {
- // check type of object
- if (pyImageTypes.in(Py_TYPE(obj)))
- {
- // convert to image struct
- PyImage * img = reinterpret_cast<PyImage*>(obj);
- // set source
- if (!self->m_image->setSource(id, img))
- {
- // if not set, retport error
- PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
- return NULL;
- }
- }
- // else report error
- else
- {
- PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
- return NULL;
- }
- }
- // return none
- Py_RETURN_NONE;
-}
-
-
-// get pixel filter object
-PyObject *Image_getFilter(PyImage *self, void *closure)
-{
- // if image object is available
- if (self->m_image != NULL)
- {
- // pixel filter object
- PyObject *filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
- // if filter is present
- if (filt != NULL)
- {
- // return it
- Py_INCREF(filt);
- return filt;
- }
- }
- // otherwise return none
- Py_RETURN_NONE;
-}
-
-
-// set pixel filter object
-int Image_setFilter(PyImage *self, PyObject *value, void *closure)
-{
- // if image object is available
- if (self->m_image != NULL)
- {
- // check new value
- if (value == NULL || !pyFilterTypes.in(Py_TYPE(value)))
- {
- // report value error
- PyErr_SetString(PyExc_TypeError, "Invalid type of value");
- return -1;
- }
- // set new value
- self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));
- }
- // return success
- return 0;
-}
-PyObject *Image_valid(PyImage *self, void *closure)
-{
- if (self->m_image->isImageAvailable())
- {
- Py_RETURN_TRUE;
- }
- else
- {
- Py_RETURN_FALSE;
- }
-}
-
-static int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
-{
- unsigned int * image;
- int ret;
-
- try {
- // can throw in case of resize
- image = self->m_image->getImage();
- }
- catch (Exception & exp) {
- exp.report();
- return -1;
- }
-
- if (!image) {
- PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
- return -1;
- }
- if (view == NULL)
- {
- self->m_image->m_exports++;
- return 0;
- }
- ret = PyBuffer_FillInfo(view, (PyObject *)self, image, self->m_image->getBuffSize(), 0, flags);
- if (ret >= 0)
- self->m_image->m_exports++;
- return ret;
-}
-
-static void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
-{
- self->m_image->m_exports--;
-}
-
-PyBufferProcs imageBufferProcs =
-{
- (getbufferproc)Image_getbuffer,
- (releasebufferproc)Image_releaseBuffer
-};
-
diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h
deleted file mode 100644
index 5a09c9a67b3..00000000000
--- a/source/gameengine/VideoTexture/ImageBase.h
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file ImageBase.h
- * \ingroup bgevideotex
- */
-
-#ifndef __IMAGEBASE_H__
-#define __IMAGEBASE_H__
-
-#include "Common.h"
-
-#include <vector>
-#include "EXP_PyObjectPlus.h"
-
-#include "PyTypeList.h"
-
-#include "FilterBase.h"
-
-#include "GPU_glew.h"
-
-// forward declarations
-struct PyImage;
-class ImageSource;
-
-
-/// type for list of image sources
-typedef std::vector<ImageSource*> ImageSourceList;
-
-
-/// base class for image filters
-class ImageBase
-{
-public:
- /// constructor
- ImageBase (bool staticSrc = false);
- /// destructor
- virtual ~ImageBase(void);
- /// release contained objects, if returns true, object should be deleted
- virtual bool release(void);
-
- /// is an image available
- bool isImageAvailable(void)
- { return m_avail; }
- /// get image
- unsigned int *getImage(unsigned int texId = 0, double timestamp=-1.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 Z buffer
- bool getZbuff(void) { return m_zbuff; }
- /// set Z buffer
- void setZbuff(bool zbuff) { m_zbuff = zbuff; }
- /// get depth
- bool getDepth(void) { return m_depth; }
- /// set depth
- void setDepth(bool depth) { m_depth = depth; }
-
- /// 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);
-
- /// calculate image from sources and send it to a target buffer instead of a texture
- /// format is GL_RGBA or GL_BGRA
- virtual bool loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts);
-
- /// swap the B and R channel in-place in the image buffer
- void swapImageBR();
-
- /// number of buffer pointing to m_image, public because not handled by this class
- int m_exports;
-
-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;
- /// use the Z buffer as a texture
- bool m_zbuff;
- /// extract the Z buffer with unisgned int precision
- bool m_depth;
-
- /// 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, double ts) {}
-
- /// perform loop detection
- bool loopDetect(ImageBase * img);
-
- /// template for image conversion
- template<class FLT, class SRC> void convImage(FLT & filter, SRC srcBuff,
- short * srcSize)
- {
- // destination buffer
- unsigned int * dstBuff = m_image;
- // pixel size from filter
- unsigned int pixSize = filter.firstPixelSize();
- // if no scaling is needed
- if (srcSize[0] == m_size[0] && srcSize[1] == m_size[1])
- // if flipping isn't required
- if (!m_flip)
- // copy bitmap
- for (short y = 0; y < m_size[1]; ++y)
- for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
- // copy pixel
- *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
- // otherwise flip image top to bottom
- else
- {
- // go to last row of image
- srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
- // copy bitmap
- for (short y = m_size[1] - 1; y >= 0; --y, srcBuff -= 2 * srcSize[0] * pixSize)
- for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
- // copy pixel
- *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
- }
- // else scale picture (nearest neighbor)
- else
- {
- // interpolation accumulator
- int accHeight = srcSize[1] >> 1;
- // if flipping is required
- if (m_flip)
- // go to last row of image
- srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
- // process image rows
- for (int y = 0; y < srcSize[1]; ++y)
- {
- // increase height accum
- accHeight += m_size[1];
- // if pixel row has to be drawn
- if (accHeight >= srcSize[1])
- {
- // decrease accum
- accHeight -= srcSize[1];
- // width accum
- int accWidth = srcSize[0] >> 1;
- // process row
- for (int x = 0; x < srcSize[0]; ++x)
- {
- // increase width accum
- accWidth += m_size[0];
- // if pixel has to be drawn
- if (accWidth >= srcSize[0])
- {
- // decrease accum
- accWidth -= srcSize[0];
- // convert pixel
- *dstBuff = filter.convert(srcBuff, x, m_flip ? srcSize[1] - y - 1 : y,
- srcSize, pixSize);
- // next pixel
- ++dstBuff;
- }
- // shift source pointer
- srcBuff += pixSize;
- }
- }
- // if pixel row will not be drawn
- else
- // move source pointer to next row
- srcBuff += pixSize * srcSize[0];
- // if y flipping is required
- if (m_flip)
- // go to previous row of image
- srcBuff -= 2 * pixSize * srcSize[0];
- }
- }
- }
-
- // template for specific filter preprocessing
- template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short *srcSize)
- {
- // find first filter in chain
- FilterBase * firstFilter = NULL;
- if (m_pyfilter != NULL) firstFilter = m_pyfilter->m_filter->findFirst();
- // if first filter is available
- if (firstFilter != NULL)
- {
- // python wrapper for filter
- PyFilter pyFilt;
- pyFilt.m_filter = &filt;
- // set specified filter as first in chain
- firstFilter->setPrevious(&pyFilt, false);
- // convert video image
- convImage(*(m_pyfilter->m_filter), srcBuff, srcSize);
- // delete added filter
- firstFilter->setPrevious(NULL, false);
- }
- // otherwise use given filter for conversion
- else convImage(filt, srcBuff, srcSize);
- // source was processed
- m_avail = true;
- }
-};
-
-
-// python structure for image filter
-struct PyImage
-{
- PyObject_HEAD
- // source object
- ImageBase * m_image;
-};
-
-
-// size of id
-const int SourceIdSize = 32;
-
-
-/// class for source of image
-class ImageSource
-{
-public:
- /// constructor
- ImageSource (const char *id);
- /// destructor
- virtual ~ImageSource (void);
-
- /// get id
- const char * getId (void) { return m_id; }
- /// compare id to argument
- bool is (const char *id);
-
- /// get source object
- PyImage * getSource (void) { return m_source; }
- /// set source object
- void setSource (PyImage *source);
-
- /// get image from source
- unsigned int * getImage (double ts=-1.0);
- /// get buffered image
- unsigned int * getImageBuf (void) { return m_image; }
- /// refresh source
- void refresh (void);
-
- /// get image size
- short * getSize (void)
- {
- static short defSize [] = {0, 0};
- return m_source != NULL ? m_source->m_image->getSize() : defSize;
- }
-
-protected:
- /// id of source
- char m_id [SourceIdSize];
- /// pointer to source structure
- PyImage * m_source;
- /// buffered image from source
- unsigned int * m_image;
-
-private:
- /// default constructor is forbidden
- ImageSource (void) {}
-};
-
-// list of python image types
-extern PyTypeList pyImageTypes;
-
-
-// functions for python interface
-
-// object initialization
-template <class T> static int Image_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- PyImage *self = reinterpret_cast<PyImage *>(pySelf);
- // create source object
- if (self->m_image != NULL) delete self->m_image;
- self->m_image = new T();
- // initialization succeded
- return 0;
-}
-
-// object allocation
-PyObject *Image_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds);
-// object deallocation
-void Image_dealloc(PyImage *self);
-
-// get image data
-PyObject *Image_getImage(PyImage *self, char *mode);
-// get image size
-PyObject *Image_getSize(PyImage *self, void *closure);
-// refresh image - invalidate current content
-PyObject *Image_refresh(PyImage *self, PyObject *args);
-
-// 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 Z buffer
-PyObject *Image_getZbuff(PyImage *self, void *closure);
-// set Z buffer
-int Image_setZbuff(PyImage *self, PyObject *value, void *closure);
-// get depth
-PyObject *Image_getDepth(PyImage *self, void *closure);
-// set depth
-int Image_setDepth(PyImage *self, PyObject *value, void *closure);
-
-// get pixel filter object
-PyObject *Image_getFilter(PyImage *self, void *closure);
-// set pixel filter object
-int Image_setFilter(PyImage *self, PyObject *value, void *closure);
-// check if a buffer can be extracted
-PyObject *Image_valid(PyImage *self, void *closure);
-// for buffer access to PyImage objects
-extern PyBufferProcs imageBufferProcs;
-
-#endif
diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp
deleted file mode 100644
index 77270865b17..00000000000
--- a/source/gameengine/VideoTexture/ImageBuff.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageBuff.cpp
- * \ingroup bgevideotex
- */
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "ImageBuff.h"
-#include "Exception.h"
-#include "ImageBase.h"
-#include "FilterSource.h"
-
-// use ImBuf API for image manipulation
-extern "C" {
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-#include "bgl.h"
-};
-
-// default filter
-FilterRGB24 defFilter;
-
-// forward declaration;
-extern PyTypeObject ImageBuffType;
-
-static int ImageBuff_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- short width = -1;
- short height = -1;
- unsigned char color = 0;
- PyObject *py_scale = Py_False;
- ImageBuff *image;
-
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
- // create source object
- if (self->m_image != NULL)
- delete self->m_image;
- image = new ImageBuff();
- self->m_image = image;
-
- if (PyArg_ParseTuple(args, "hh|bO!:ImageBuff", &width, &height, &color, &PyBool_Type, &py_scale))
- {
- // initialize image buffer
- image->setScale(py_scale == Py_True);
- image->clear(width, height, color);
- }
- else
- {
- // check if at least one argument was passed
- if (width != -1 || height != -1)
- // yes and they didn't match => it's an error
- return -1;
- // empty argument list is okay
- PyErr_Clear();
- }
- // initialization succeded
- return 0;
-
-}
-
-ImageBuff::~ImageBuff (void)
-{
- if (m_imbuf)
- IMB_freeImBuf(m_imbuf);
-}
-
-
-// load image from buffer
-void ImageBuff::load(unsigned char *img, short width, short height)
-{
- // loading a new buffer implies to reset the imbuf if any, because the size may change
- if (m_imbuf)
- {
- IMB_freeImBuf(m_imbuf);
- m_imbuf = NULL;
- }
- // 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;
-}
-
-void ImageBuff::clear(short width, short height, unsigned char color)
-{
- unsigned char *p;
- int size;
-
- // loading a new buffer implies to reset the imbuf if any, because the size may change
- if (m_imbuf)
- {
- IMB_freeImBuf(m_imbuf);
- m_imbuf = NULL;
- }
- // initialize image buffer
- init(width, height);
- // the width/height may be different due to scaling
- size = (m_size[0] * m_size[1]);
- // initialize memory with color for all channels
- memset(m_image, color, size*4);
- // and change the alpha channel
- p = &((unsigned char*)m_image)[3];
- for (; size>0; size--)
- {
- *p = 0xFF;
- p += 4;
- }
- // image is available
- m_avail = true;
-}
-
-// img must point to a array of RGBA data of size width*height
-void ImageBuff::plot(unsigned char *img, short width, short height, short x, short y, short mode)
-{
- struct ImBuf *tmpbuf;
-
- if (m_size[0] == 0 || m_size[1] == 0 || width <= 0 || height <= 0)
- return;
-
- if (!m_imbuf) {
- // allocate most basic imbuf, we will assign the rect buffer on the fly
- m_imbuf = IMB_allocImBuf(m_size[0], m_size[1], 0, 0);
- }
-
- tmpbuf = IMB_allocImBuf(width, height, 0, 0);
-
- // assign temporarily our buffer to the ImBuf buffer, we use the same format
- tmpbuf->rect = (unsigned int*)img;
- m_imbuf->rect = m_image;
- IMB_rectblend(m_imbuf, m_imbuf, tmpbuf, NULL, NULL, NULL, 0, x, y, x, y, 0, 0, width, height, (IMB_BlendMode)mode, false);
- // remove so that MB_freeImBuf will free our buffer
- m_imbuf->rect = NULL;
- tmpbuf->rect = NULL;
- IMB_freeImBuf(tmpbuf);
-}
-
-void ImageBuff::plot(ImageBuff *img, short x, short y, short mode)
-{
- if (m_size[0] == 0 || m_size[1] == 0 || img->m_size[0] == 0 || img->m_size[1] == 0)
- return;
-
- if (!m_imbuf) {
- // allocate most basic imbuf, we will assign the rect buffer on the fly
- m_imbuf = IMB_allocImBuf(m_size[0], m_size[1], 0, 0);
- }
- if (!img->m_imbuf) {
- // allocate most basic imbuf, we will assign the rect buffer on the fly
- img->m_imbuf = IMB_allocImBuf(img->m_size[0], img->m_size[1], 0, 0);
- }
- // assign temporarily our buffer to the ImBuf buffer, we use the same format
- img->m_imbuf->rect = img->m_image;
- m_imbuf->rect = m_image;
- IMB_rectblend(m_imbuf, m_imbuf, img->m_imbuf, NULL, NULL, NULL, 0, x, y, x, y, 0, 0, img->m_imbuf->x, img->m_imbuf->y, (IMB_BlendMode)mode, false);
- // remove so that MB_freeImBuf will free our buffer
- m_imbuf->rect = NULL;
- img->m_imbuf->rect = NULL;
-}
-
-
-// cast Image pointer to ImageBuff
-inline ImageBuff *getImageBuff(PyImage *self)
-{ return static_cast<ImageBuff *>(self->m_image); }
-
-
-// python methods
-
-static bool testPyBuffer(Py_buffer *buffer, int width, int height, unsigned int pixsize)
-{
- if (buffer->itemsize != 1)
- {
- PyErr_SetString(PyExc_ValueError, "Buffer must be an array of bytes");
- return false;
- }
- if (buffer->len != width*height*pixsize)
- {
- PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
- return false;
- }
- // multi dimension are ok as long as there is no hole in the memory
- Py_ssize_t size = buffer->itemsize;
- for (int i=buffer->ndim-1; i>=0 ; i--)
- {
- if (buffer->suboffsets != NULL && buffer->suboffsets[i] >= 0)
- {
- PyErr_SetString(PyExc_ValueError, "Buffer must be of one block");
- return false;
- }
- if (buffer->strides != NULL && buffer->strides[i] != size)
- {
- PyErr_SetString(PyExc_ValueError, "Buffer must be of one block");
- return false;
- }
- if (i > 0)
- size *= buffer->shape[i];
- }
- return true;
-}
-
-static bool testBGLBuffer(Buffer *buffer, int width, int height, unsigned int pixsize)
-{
- unsigned int size = BGL_typeSize(buffer->type);
- for (int i=0; i<buffer->ndimensions; i++)
- {
- size *= buffer->dimensions[i];
- }
- if (size != width*height*pixsize)
- {
- PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
- return false;
- }
- return true;
-}
-
-
-// load image
-static PyObject *load(PyImage *self, PyObject *args)
-{
- // parameters: string image buffer, its size, width, height
- Py_buffer buffer;
- Buffer *bglBuffer;
- short width;
- short height;
- unsigned int pixSize;
-
- // calc proper buffer size
- // use pixel size from filter
- if (self->m_image->getFilter() != NULL)
- pixSize = self->m_image->getFilter()->m_filter->firstPixelSize();
- else
- pixSize = defFilter.firstPixelSize();
-
- // parse parameters
- if (!PyArg_ParseTuple(args, "s*hh:load", &buffer, &width, &height))
- {
- PyErr_Clear();
- // check if it is BGL buffer
- if (!PyArg_ParseTuple(args, "O!hh:load", &BGL_bufferType, &bglBuffer, &width, &height))
- {
- // report error
- return NULL;
- }
- else
- {
- if (testBGLBuffer(bglBuffer, width, height, pixSize))
- {
- try
- {
- // if correct, load image
- getImageBuff(self)->load((unsigned char*)bglBuffer->buf.asvoid, width, height);
- }
- catch (Exception & exp)
- {
- exp.report();
- }
- }
- }
- }
- else
- {
- // check if buffer size is correct
- if (testPyBuffer(&buffer, width, height, pixSize))
- {
- try
- {
- // if correct, load image
- getImageBuff(self)->load((unsigned char*)buffer.buf, width, height);
- }
- catch (Exception & exp)
- {
- exp.report();
- }
- }
- PyBuffer_Release(&buffer);
- }
- if (PyErr_Occurred())
- return NULL;
- Py_RETURN_NONE;
-}
-
-static PyObject *plot(PyImage *self, PyObject *args)
-{
- PyImage * other;
- Buffer* bglBuffer;
- Py_buffer buffer;
- //unsigned char * buff;
- //unsigned int buffSize;
- short width;
- short height;
- short x, y;
- short mode = IMB_BLEND_COPY;
-
- if (PyArg_ParseTuple(args, "s*hhhh|h:plot", &buffer, &width, &height, &x, &y, &mode))
- {
- // correct decoding, verify that buffer size is correct
- // we need a continuous memory buffer
- if (testPyBuffer(&buffer, width, height, 4))
- {
- getImageBuff(self)->plot((unsigned char*)buffer.buf, width, height, x, y, mode);
- }
- PyBuffer_Release(&buffer);
- if (PyErr_Occurred())
- return NULL;
- Py_RETURN_NONE;
- }
- PyErr_Clear();
- // try the other format
- if (PyArg_ParseTuple(args, "O!hh|h:plot", &ImageBuffType, &other, &x, &y, &mode))
- {
- getImageBuff(self)->plot(getImageBuff(other), x, y, mode);
- Py_RETURN_NONE;
- }
- PyErr_Clear();
- // try the last format (BGL buffer)
- if (!PyArg_ParseTuple(args, "O!hhhh|h:plot", &BGL_bufferType, &bglBuffer, &width, &height, &x, &y, &mode))
- {
- PyErr_SetString(PyExc_TypeError, "Expecting ImageBuff or Py buffer or BGL buffer as first argument; width, height next; postion x, y and mode as last arguments");
- return NULL;
- }
- if (testBGLBuffer(bglBuffer, width, height, 4))
- {
- getImageBuff(self)->plot((unsigned char*)bglBuffer->buf.asvoid, width, height, x, y, mode);
- }
- if (PyErr_Occurred())
- return NULL;
- Py_RETURN_NONE;
-}
-
-// methods structure
-static PyMethodDef imageBuffMethods[] = {
- {"load", (PyCFunction)load, METH_VARARGS, "Load image from buffer"},
- {"plot", (PyCFunction)plot, METH_VARARGS, "update image buffer"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef imageBuffGetSets[] = {
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", 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}
-};
-
-
-// define python type
-PyTypeObject ImageBuffType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*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)ImageBuff_init, /* tp_init */
- 0, /* tp_alloc */
- Image_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/ImageBuff.h b/source/gameengine/VideoTexture/ImageBuff.h
deleted file mode 100644
index 19299506747..00000000000
--- a/source/gameengine/VideoTexture/ImageBuff.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file ImageBuff.h
- * \ingroup bgevideotex
- */
-
-#ifndef __IMAGEBUFF_H__
-#define __IMAGEBUFF_H__
-
-
-#include "Common.h"
-
-#include "ImageBase.h"
-
-struct ImBuf;
-
-/// class for image buffer
-class ImageBuff : public ImageBase
-{
-private:
- struct ImBuf *m_imbuf; // temporary structure for buffer manipulation
-public:
- /// constructor
- ImageBuff (void) : ImageBase(true), m_imbuf(NULL) {}
-
- /// destructor
- virtual ~ImageBuff (void);
-
- /// load image from buffer
- void load (unsigned char * img, short width, short height);
- /// clear image with color set on RGB channels and 0xFF on alpha channel
- void clear (short width, short height, unsigned char color);
-
- /// plot image from extern RGBA buffer to image at position x,y using one of IMB_BlendMode
- void plot (unsigned char * img, short width, short height, short x, short y, short mode);
- /// plot image from other ImageBuf to image at position x,y using one of IMB_BlendMode
- void plot (ImageBuff* img, short x, short y, short mode);
-
- /// refresh image - do nothing
- virtual void refresh (void) {}
-};
-
-
-#endif
-
diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp
deleted file mode 100644
index 2de00f5ba05..00000000000
--- a/source/gameengine/VideoTexture/ImageMix.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageMix.cpp
- * \ingroup bgevideotex
- */
-
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "ImageMix.h"
-
-#include "ImageBase.h"
-
-#include "Exception.h"
-
-
-// cast ImageSource pointer to ImageSourceMix
-inline ImageSourceMix *getImageSourceMix(ImageSource *src)
-{ return static_cast<ImageSourceMix*>(src); }
-
-
-// get weight
-short ImageMix::getWeight(const char *id)
-{
- // find source
- ImageSourceList::iterator src = findSource(id);
- // if found, return its weight
- return src != m_sources.end() ? getImageSourceMix(*src)->getWeight() : 0;
-}
-
-// set weight
-bool ImageMix::setWeight(const char *id, short weight)
-{
- // find source
- ImageSourceList::iterator src = findSource(id);
- // if source isn't found, report it
- if (src == m_sources.end()) return false;
- // set its weight
- getImageSourceMix(*src)->setWeight(weight);
- return true;
-}
-
-ExceptionID ImageSizesNotMatch;
-
-ExpDesc ImageSizesNotMatchDesc(ImageSizesNotMatch, "Image sizes of sources are different");
-
-// calculate image from sources and set its availability
-void ImageMix::calcImage(unsigned int texId, double ts)
-{
- // check source sizes
- if (!checkSourceSizes()) THRWEXCP(ImageSizesNotMatch, S_OK);
- // set offsets to image buffers
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- // if image buffer is available
- if ((*it)->getImageBuf() != NULL)
- // set its offset
- getImageSourceMix(*it)->setOffset(m_sources[0]->getImageBuf());
- // otherwise don't calculate image
- else
- return;
- // if there is only single source
- if (m_sources.size() == 1)
- {
- // use single filter
- FilterBase mixFilt;
- // fiter and convert image
- filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
- }
- // otherwise use mix filter to merge source images
- else
- {
- FilterImageMix mixFilt (m_sources);
- // fiter and convert image
- filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
- }
-}
-
-
-
-// cast Image pointer to ImageMix
-inline ImageMix * getImageMix(PyImage *self)
-{ return static_cast<ImageMix*>(self->m_image); }
-
-
-// python methods
-
-// get source weight
-static PyObject *getWeight(PyImage *self, PyObject *args)
-{
- // weight
- short weight = 0;
- // get arguments
- char *id;
- if (!PyArg_ParseTuple(args, "s:getWeight", &id))
- return NULL;
- if (self->m_image != NULL)
- // get weight
- weight = getImageMix(self)->getWeight(id);
- // return weight
- return Py_BuildValue("h", weight);
-}
-
-
-// set source weight
-static PyObject *setWeight(PyImage *self, PyObject *args)
-{
- // get arguments
- char *id;
- short weight = 0;
- if (!PyArg_ParseTuple(args, "sh:setWeight", &id, &weight))
- return NULL;
- if (self->m_image != NULL)
- // 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_VARARGS, "Refresh image - invalidate its current content"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef imageMixGetSets[] = {
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", 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}
-};
-
-
-// define python type
-PyTypeObject ImageMixType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Image mixer", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- imageMixMethods, /* tp_methods */
- 0, /* tp_members */
- imageMixGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Image_init<ImageMix>, /* tp_init */
- 0, /* tp_alloc */
- Image_allocNew, /* tp_new */
-};
-
diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h
deleted file mode 100644
index 161a8b375ea..00000000000
--- a/source/gameengine/VideoTexture/ImageMix.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file ImageMix.h
- * \ingroup bgevideotex
- */
-
-#ifndef __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_offset(0), 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, double ts);
-};
-
-
-/// pixel filter for image mixer
-class FilterImageMix : public FilterBase
-{
-public:
- /// constructor
- FilterImageMix (ImageSourceList & sources) : m_sources(sources) {}
- /// destructor
- virtual ~FilterImageMix (void) {}
-
-protected:
- /// source list
- ImageSourceList & m_sources;
-
- /// filter pixel, source int buffer
- virtual unsigned int filter (unsigned int * src, short x, short y,
- short * size, unsigned int pixSize, unsigned int val = 0)
- {
- // resulting pixel color
- int color[] = {0, 0, 0, 0};
- // iterate sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- {
- // get pointer to mixer source
- ImageSourceMix * mixSrc = static_cast<ImageSourceMix*>(*it);
- // add weighted source pixel to result
- color[0] += mixSrc->getWeight() * (src[mixSrc->getOffset()] & 0xFF);
- color[1] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 8) & 0xFF);
- color[2] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 16) & 0xFF);
- color[3] += mixSrc->getWeight() * ((src[mixSrc->getOffset()] >> 24) & 0xFF);
- }
- // return resulting color
- return ((color[0] >> 8) & 0xFF) | (color[1] & 0xFF00)
- | ((color[2] << 8) & 0xFF0000) | ((color[3] << 16) & 0xFF000000);
- }
-};
-
-
-#endif
-
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
deleted file mode 100644
index 57062343b67..00000000000
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageRender.cpp
- * \ingroup bgevideotex
- */
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-#include <float.h>
-#include <math.h>
-
-
-#include "GPU_glew.h"
-
-#include "KX_PythonInit.h"
-#include "DNA_scene_types.h"
-#include "RAS_CameraData.h"
-#include "RAS_MeshObject.h"
-#include "RAS_Polygon.h"
-#include "RAS_IOffScreen.h"
-#include "RAS_ISync.h"
-#include "BLI_math.h"
-
-#include "ImageRender.h"
-#include "ImageBase.h"
-#include "BlendType.h"
-#include "Exception.h"
-#include "Texture.h"
-
-ExceptionID SceneInvalid, CameraInvalid, ObserverInvalid, OffScreenInvalid;
-ExceptionID MirrorInvalid, MirrorSizeInvalid, MirrorNormalInvalid, MirrorHorizontal, MirrorTooSmall;
-ExpDesc SceneInvalidDesc(SceneInvalid, "Scene object is invalid");
-ExpDesc CameraInvalidDesc(CameraInvalid, "Camera object is invalid");
-ExpDesc ObserverInvalidDesc(ObserverInvalid, "Observer object is invalid");
-ExpDesc OffScreenInvalidDesc(OffScreenInvalid, "Offscreen object is invalid");
-ExpDesc MirrorInvalidDesc(MirrorInvalid, "Mirror object is invalid");
-ExpDesc MirrorSizeInvalidDesc(MirrorSizeInvalid, "Mirror has no vertex or no size");
-ExpDesc MirrorNormalInvalidDesc(MirrorNormalInvalid, "Cannot determine mirror plane");
-ExpDesc MirrorHorizontalDesc(MirrorHorizontal, "Mirror is horizontal in local space");
-ExpDesc MirrorTooSmallDesc(MirrorTooSmall, "Mirror is too small");
-
-// constructor
-ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera, PyRASOffScreen * offscreen) :
- ImageViewport(offscreen),
- m_render(true),
- m_done(false),
- m_scene(scene),
- m_camera(camera),
- m_owncamera(false),
- m_offscreen(offscreen),
- m_sync(NULL),
- m_observer(NULL),
- m_mirror(NULL),
- m_clip(100.f),
- m_mirrorHalfWidth(0.f),
- m_mirrorHalfHeight(0.f)
-{
- // initialize background color to scene background color as default
- setBackgroundFromScene(m_scene);
- // retrieve rendering objects
- m_engine = KX_GetActiveEngine();
- m_rasterizer = m_engine->GetRasterizer();
- m_canvas = m_engine->GetCanvas();
- // keep a reference to the offscreen buffer
- if (m_offscreen) {
- Py_INCREF(m_offscreen);
- }
-}
-
-// destructor
-ImageRender::~ImageRender (void)
-{
- if (m_owncamera)
- m_camera->Release();
- if (m_sync)
- delete m_sync;
- Py_XDECREF(m_offscreen);
-}
-
-// get background color
-float ImageRender::getBackground (int idx)
-{
- return (idx < 0 || idx > 3) ? 0.0f : m_background[idx] * 255.0f;
-}
-
-// set background color
-void ImageRender::setBackground (float red, float green, float blue, float alpha)
-{
- m_background[0] = (red < 0.0f) ? 0.0f : (red > 255.0f) ? 1.0f : red / 255.0f;
- m_background[1] = (green < 0.0f) ? 0.0f : (green > 255.0f) ? 1.0f : green / 255.0f;
- m_background[2] = (blue < 0.0f) ? 0.0f : (blue > 255.0f) ? 1.0f : blue / 255.0f;
- m_background[3] = (alpha < 0.0f) ? 0.0f : (alpha > 255.0f) ? 1.0f : alpha / 255.0f;
-}
-
-// set background color from scene
-void ImageRender::setBackgroundFromScene (KX_Scene *scene)
-{
- if (scene) {
- const float *background_color = scene->GetWorldInfo()->getBackColorConverted();
- copy_v3_v3(m_background, background_color);
- m_background[3] = 1.0f;
- }
- else {
- const float blue_color[] = {0.0f, 0.0f, 1.0f, 1.0f};
- copy_v4_v4(m_background, blue_color);
- }
-}
-
-
-// capture image from viewport
-void ImageRender::calcViewport (unsigned int texId, double ts, unsigned int format)
-{
- // render the scene from the camera
- if (!m_done) {
- if (!Render()) {
- return;
- }
- }
- else if (m_offscreen) {
- m_offscreen->ofs->Bind(RAS_IOffScreen::RAS_OFS_BIND_READ);
- }
- // wait until all render operations are completed
- WaitSync();
- // get image from viewport (or FBO)
- ImageViewport::calcViewport(texId, ts, format);
- if (m_offscreen) {
- m_offscreen->ofs->Unbind();
- }
-}
-
-bool ImageRender::Render()
-{
- RAS_FrameFrustum frustum;
-
- if (!m_render ||
- m_rasterizer->GetDrawingMode() != RAS_IRasterizer::KX_TEXTURED || // no need for texture
- m_camera->GetViewport() || // camera must be inactive
- m_camera == m_scene->GetActiveCamera())
- {
- // no need to compute texture in non texture rendering
- return false;
- }
-
- if (!m_scene->IsShadowDone())
- m_engine->RenderShadowBuffers(m_scene);
-
- if (m_mirror)
- {
- // mirror mode, compute camera frustum, position and orientation
- // convert mirror position and normal in world space
- const MT_Matrix3x3 & mirrorObjWorldOri = m_mirror->GetSGNode()->GetWorldOrientation();
- const MT_Point3 & mirrorObjWorldPos = m_mirror->GetSGNode()->GetWorldPosition();
- const MT_Vector3 & mirrorObjWorldScale = m_mirror->GetSGNode()->GetWorldScaling();
- MT_Point3 mirrorWorldPos =
- mirrorObjWorldPos + mirrorObjWorldScale * (mirrorObjWorldOri * m_mirrorPos);
- MT_Vector3 mirrorWorldZ = mirrorObjWorldOri * m_mirrorZ;
- // get observer world position
- const MT_Point3 & observerWorldPos = m_observer->GetSGNode()->GetWorldPosition();
- // get plane D term = mirrorPos . normal
- MT_Scalar mirrorPlaneDTerm = mirrorWorldPos.dot(mirrorWorldZ);
- // compute distance of observer to mirror = D - observerPos . normal
- MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ);
- // if distance < 0.01 => observer is on wrong side of mirror, don't render
- if (observerDistance < 0.01)
- return false;
- // set camera world position = observerPos + normal * 2 * distance
- MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ;
- m_camera->GetSGNode()->SetLocalPosition(cameraWorldPos);
- // set camera orientation: z=normal, y=mirror_up in world space, x= y x z
- MT_Vector3 mirrorWorldY = mirrorObjWorldOri * m_mirrorY;
- MT_Vector3 mirrorWorldX = mirrorObjWorldOri * m_mirrorX;
- MT_Matrix3x3 cameraWorldOri(
- mirrorWorldX[0], mirrorWorldY[0], mirrorWorldZ[0],
- mirrorWorldX[1], mirrorWorldY[1], mirrorWorldZ[1],
- mirrorWorldX[2], mirrorWorldY[2], mirrorWorldZ[2]);
- m_camera->GetSGNode()->SetLocalOrientation(cameraWorldOri);
- m_camera->GetSGNode()->UpdateWorldData(0.0);
- // compute camera frustum:
- // get position of mirror relative to camera: offset = mirrorPos-cameraPos
- MT_Vector3 mirrorOffset = mirrorWorldPos - cameraWorldPos;
- // convert to camera orientation
- mirrorOffset = mirrorOffset * cameraWorldOri;
- // scale mirror size to world scale:
- // get closest local axis for mirror Y and X axis and scale height and width by local axis scale
- MT_Scalar x, y;
- x = fabs(m_mirrorY[0]);
- y = fabs(m_mirrorY[1]);
- float height = (x > y) ?
- ((x > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]):
- ((y > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]);
- x = fabs(m_mirrorX[0]);
- y = fabs(m_mirrorX[1]);
- float width = (x > y) ?
- ((x > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]):
- ((y > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]);
- width *= m_mirrorHalfWidth;
- height *= m_mirrorHalfHeight;
- // left = offsetx-width
- // right = offsetx+width
- // top = offsety+height
- // bottom = offsety-height
- // near = -offsetz
- // far = near+100
- frustum.x1 = mirrorOffset[0]-width;
- frustum.x2 = mirrorOffset[0]+width;
- frustum.y1 = mirrorOffset[1]-height;
- frustum.y2 = mirrorOffset[1]+height;
- frustum.camnear = -mirrorOffset[2];
- frustum.camfar = -mirrorOffset[2]+m_clip;
- }
- // Store settings to be restored later
- const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
- RAS_Rect area = m_canvas->GetWindowArea();
-
- // The screen area that ImageViewport will copy is also the rendering zone
- if (m_offscreen) {
- // bind the fbo and set the viewport to full size
- m_offscreen->ofs->Bind(RAS_IOffScreen::RAS_OFS_BIND_RENDER);
- // this is needed to stop crashing in canvas check
- m_canvas->UpdateViewPort(0, 0, m_offscreen->ofs->GetWidth(), m_offscreen->ofs->GetHeight());
- }
- else {
- m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1);
- }
- m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
- m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
- m_rasterizer->BeginFrame(m_engine->GetClockTime());
- m_scene->GetWorldInfo()->UpdateWorldSettings();
- m_rasterizer->SetAuxilaryClientInfo(m_scene);
- m_rasterizer->DisplayFog();
- // matrix calculation, don't apply any of the stereo mode
- m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO);
- if (m_mirror)
- {
- // frustum was computed above
- // get frustum matrix and set projection matrix
- MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
- frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar);
-
- m_camera->SetProjectionMatrix(projmat);
- }
- else if (m_camera->hasValidProjectionMatrix()) {
- m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix());
- }
- else {
- float lens = m_camera->GetLens();
- float sensor_x = m_camera->GetSensorWidth();
- float sensor_y = m_camera->GetSensorHeight();
- float shift_x = m_camera->GetShiftHorizontal();
- float shift_y = m_camera->GetShiftVertical();
- bool orthographic = !m_camera->GetCameraData()->m_perspective;
- float nearfrust = m_camera->GetCameraNear();
- float farfrust = m_camera->GetCameraFar();
- float aspect_ratio = 1.0f;
- Scene *blenderScene = m_scene->GetBlenderScene();
- MT_Matrix4x4 projmat;
-
- // compute the aspect ratio from frame blender scene settings so that render to texture
- // works the same in Blender and in Blender player
- if (blenderScene->r.ysch != 0)
- aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp);
-
- if (orthographic) {
-
- RAS_FramingManager::ComputeDefaultOrtho(
- nearfrust,
- farfrust,
- m_camera->GetScale(),
- aspect_ratio,
- m_camera->GetSensorFit(),
- shift_x,
- shift_y,
- frustum
- );
-
- projmat = m_rasterizer->GetOrthoMatrix(
- frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar);
- }
- else {
- RAS_FramingManager::ComputeDefaultFrustum(
- nearfrust,
- farfrust,
- lens,
- sensor_x,
- sensor_y,
- RAS_SENSORFIT_AUTO,
- shift_x,
- shift_y,
- aspect_ratio,
- frustum);
-
- projmat = m_rasterizer->GetFrustumMatrix(
- frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar);
- }
- m_camera->SetProjectionMatrix(projmat);
- }
-
- MT_Transform camtrans(m_camera->GetWorldToCamera());
- MT_Matrix4x4 viewmat(camtrans);
-
- m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->NodeGetLocalScaling(), m_camera->GetCameraData()->m_perspective);
- m_camera->SetModelviewMatrix(viewmat);
- // restore the stereo mode now that the matrix is computed
- m_rasterizer->SetStereoMode(stereomode);
-
- if (m_rasterizer->Stereo()) {
- // stereo mode change render settings that disturb this render, cancel them all
- // we don't need to restore them as they are set before each frame render.
- glDrawBuffer(GL_BACK_LEFT);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDisable(GL_POLYGON_STIPPLE);
- }
-
- m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
-
- m_engine->UpdateAnimations(m_scene);
-
- m_scene->RenderBuckets(camtrans, m_rasterizer);
-
- m_scene->RenderFonts();
-
- // restore the canvas area now that the render is completed
- m_canvas->GetWindowArea() = area;
- m_canvas->EndFrame();
-
- // In case multisample is active, blit the FBO
- if (m_offscreen)
- m_offscreen->ofs->Blit();
- // end of all render operations, let's create a sync object just in case
- if (m_sync) {
- // a sync from a previous render, should not happen
- delete m_sync;
- m_sync = NULL;
- }
- m_sync = m_rasterizer->CreateSync(RAS_ISync::RAS_SYNC_TYPE_FENCE);
- // remember that we have done render
- m_done = true;
- // the image is not available at this stage
- m_avail = false;
- return true;
-}
-
-void ImageRender::Unbind()
-{
- if (m_offscreen)
- {
- m_offscreen->ofs->Unbind();
- }
-}
-
-void ImageRender::WaitSync()
-{
- if (m_sync) {
- m_sync->Wait();
- // done with it, deleted it
- delete m_sync;
- m_sync = NULL;
- }
- if (m_offscreen) {
- // this is needed to finalize the image if the target is a texture
- m_offscreen->ofs->MipMap();
- }
- // all rendered operation done and complete, invalidate render for next time
- m_done = false;
-}
-
-// cast Image pointer to ImageRender
-inline ImageRender * getImageRender (PyImage *self)
-{ return static_cast<ImageRender*>(self->m_image); }
-
-
-// python methods
-
-// Blender Scene type
-static BlendType<KX_Scene> sceneType ("KX_Scene");
-// Blender Camera type
-static BlendType<KX_Camera> cameraType ("KX_Camera");
-
-
-// object initialization
-static int ImageRender_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- // parameters - scene object
- PyObject *scene;
- // camera object
- PyObject *camera;
- // offscreen buffer object
- PyRASOffScreen *offscreen = NULL;
- // parameter keywords
- static const char *kwlist[] = {"sceneObj", "cameraObj", "ofsObj", NULL};
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O",
- const_cast<char**>(kwlist), &scene, &camera, &offscreen))
- 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);
-
- if (offscreen) {
- if (Py_TYPE(offscreen) != &PyRASOffScreen_Type) {
- THRWEXCP(OffScreenInvalid, S_OK);
- }
- }
- // get pointer to image structure
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
- // create source object
- if (self->m_image != NULL) delete self->m_image;
- self->m_image = new ImageRender(scenePtr, cameraPtr, offscreen);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // initialization succeded
- return 0;
-}
-
-static PyObject *ImageRender_refresh(PyImage *self, PyObject *args)
-{
- ImageRender *imageRender = getImageRender(self);
-
- if (!imageRender) {
- PyErr_SetString(PyExc_TypeError, "Incomplete ImageRender() object");
- return NULL;
- }
- if (PyArg_ParseTuple(args, "")) {
- // refresh called with no argument.
- // For other image objects it simply invalidates the image buffer
- // For ImageRender it triggers a render+sync
- // Note that this only makes sense when doing offscreen render on texture
- if (!imageRender->isDone()) {
- if (!imageRender->Render()) {
- Py_RETURN_FALSE;
- }
- // as we are not trying to read the pixels, just unbind
- imageRender->Unbind();
- }
- // wait until all render operations are completed
- // this will also finalize the texture
- imageRender->WaitSync();
- Py_RETURN_TRUE;
- }
- else {
- // fallback on standard processing
- PyErr_Clear();
- return Image_refresh(self, args);
- }
-}
-
-// refresh image
-static PyObject *ImageRender_render(PyImage *self)
-{
- ImageRender *imageRender = getImageRender(self);
-
- if (!imageRender) {
- PyErr_SetString(PyExc_TypeError, "Incomplete ImageRender() object");
- return NULL;
- }
- if (!imageRender->Render()) {
- Py_RETURN_FALSE;
- }
- // we are not reading the pixels now, unbind
- imageRender->Unbind();
- Py_RETURN_TRUE;
-}
-
-
-// get background color
-static PyObject *getBackground (PyImage *self, void *closure)
-{
- return Py_BuildValue("[ffff]",
- getImageRender(self)->getBackground(0),
- getImageRender(self)->getBackground(1),
- getImageRender(self)->getBackground(2),
- getImageRender(self)->getBackground(3));
-}
-
-// set color
-static int setBackground(PyImage *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL || !PySequence_Check(value) || PySequence_Size(value) != 4
- || (!PyFloat_Check(PySequence_Fast_GET_ITEM(value, 0)) && !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)))
- || (!PyFloat_Check(PySequence_Fast_GET_ITEM(value, 1)) && !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)))
- || (!PyFloat_Check(PySequence_Fast_GET_ITEM(value, 2)) && !PyLong_Check(PySequence_Fast_GET_ITEM(value, 2)))
- || (!PyFloat_Check(PySequence_Fast_GET_ITEM(value, 3)) && !PyLong_Check(PySequence_Fast_GET_ITEM(value, 3)))) {
-
- PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 floats or ints between 0.0 and 255.0");
- return -1;
- }
- // set background color
- getImageRender(self)->setBackground(
- PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)),
- PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)),
- PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 2)),
- PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 3)));
- // success
- return 0;
-}
-
-
-// methods structure
-static PyMethodDef imageRenderMethods[] =
-{ // methods from ImageBase class
- {"refresh", (PyCFunction)ImageRender_refresh, METH_VARARGS, "Refresh image - invalidate its current content after optionally transferring its content to a target buffer"},
- {"render", (PyCFunction)ImageRender_render, METH_NOARGS, "Render scene - run before refresh() to performs asynchronous render"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef imageRenderGetSets[] =
-{
- {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL},
- // attribute from ImageViewport
- {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL},
- {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
- {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", NULL},
- {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
- {(char*)"zbuff", (getter)Image_getZbuff, (setter)Image_setZbuff, (char*)"use depth buffer as texture", NULL},
- {(char*)"depth", (getter)Image_getDepth, (setter)Image_setDepth, (char*)"get depth information from z-buffer using unsigned int precision", NULL},
- {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
- {NULL}
-};
-
-
-// define python type
-PyTypeObject ImageRenderType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*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 */
-};
-
-// object initialization
-static int ImageMirror_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- // parameters - scene object
- PyObject *scene;
- // reference object for mirror
- PyObject *observer;
- // object holding the mirror
- PyObject *mirror;
- // material of the mirror
- short materialID = 0;
- // parameter keywords
- static const char *kwlist[] = {"scene", "observer", "mirror", "material", NULL};
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h",
- const_cast<char**>(kwlist), &scene, &observer, &mirror, &materialID))
- return -1;
- try
- {
- // get scene pointer
- KX_Scene * scenePtr (NULL);
- if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type))
- scenePtr = static_cast<KX_Scene*>BGE_PROXY_REF(scene);
- else
- THRWEXCP(SceneInvalid, S_OK);
-
- if (scenePtr==NULL) /* in case the python proxy reference is invalid */
- THRWEXCP(SceneInvalid, S_OK);
-
- // get observer pointer
- KX_GameObject * observerPtr (NULL);
- if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type))
- observerPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(observer);
- else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type))
- observerPtr = static_cast<KX_Camera*>BGE_PROXY_REF(observer);
- else
- THRWEXCP(ObserverInvalid, S_OK);
-
- if (observerPtr==NULL) /* in case the python proxy reference is invalid */
- THRWEXCP(ObserverInvalid, S_OK);
-
- // get mirror pointer
- KX_GameObject * mirrorPtr (NULL);
- if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type))
- mirrorPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(mirror);
- else
- THRWEXCP(MirrorInvalid, S_OK);
-
- if (mirrorPtr==NULL) /* in case the python proxy reference is invalid */
- THRWEXCP(MirrorInvalid, S_OK);
-
- // locate the material in the mirror
- RAS_IPolyMaterial * material = getMaterial(mirror, materialID);
- if (material == NULL)
- THRWEXCP(MaterialNotAvail, S_OK);
-
- // get pointer to image structure
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
-
- // create source object
- if (self->m_image != NULL)
- {
- delete self->m_image;
- self->m_image = NULL;
- }
- self->m_image = new ImageRender(scenePtr, observerPtr, mirrorPtr, material);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // initialization succeeded
- return 0;
-}
-
-// get background color
-static PyObject *getClip (PyImage *self, void *closure)
-{
- return PyFloat_FromDouble(getImageRender(self)->getClip());
-}
-
-// set clip
-static int setClip(PyImage *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- double clip;
- if (value == NULL || !PyFloat_Check(value) || (clip = PyFloat_AsDouble(value)) < 0.01 || clip > 5000.0)
- {
- PyErr_SetString(PyExc_TypeError, "The value must be an float between 0.01 and 5000");
- return -1;
- }
- // set background color
- getImageRender(self)->setClip(float(clip));
- // success
- return 0;
-}
-
-// attributes structure
-static PyGetSetDef imageMirrorGetSets[] =
-{
- {(char*)"clip", (getter)getClip, (setter)setClip, (char*)"clipping distance", NULL},
- // attribute from ImageRender
- {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL},
- // attribute from ImageViewport
- {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL},
- {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
- {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", NULL},
- {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
- {(char*)"zbuff", (getter)Image_getZbuff, (setter)Image_setZbuff, (char*)"use depth buffer as texture", NULL},
- {(char*)"depth", (getter)Image_getDepth, (setter)Image_setDepth, (char*)"get depth information from z-buffer using unsigned int precision", NULL},
- {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
- {NULL}
-};
-
-
-// constructor
-ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial *mat) :
- ImageViewport(),
- m_render(false),
- m_done(false),
- m_scene(scene),
- m_offscreen(NULL),
- m_sync(NULL),
- m_observer(observer),
- m_mirror(mirror),
- m_clip(100.f)
-{
- // this constructor is used for automatic planar mirror
- // create a camera, take all data by default, in any case we will recompute the frustum on each frame
- RAS_CameraData camdata;
- vector<RAS_TexVert*> mirrorVerts;
- vector<RAS_TexVert*>::iterator it;
- float mirrorArea = 0.f;
- float mirrorNormal[3] = {0.f, 0.f, 0.f};
- float mirrorUp[3];
- float dist, vec[3], axis[3];
- float zaxis[3] = {0.f, 0.f, 1.f};
- float yaxis[3] = {0.f, 1.f, 0.f};
- float mirrorMat[3][3];
- float left, right, top, bottom, back;
- // make sure this camera will delete its node
- m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata, true, true);
- m_camera->SetName("__mirror__cam__");
- // don't add the camera to the scene object list, it doesn't need to be accessible
- m_owncamera = true;
- // retrieve rendering objects
- m_engine = KX_GetActiveEngine();
- m_rasterizer = m_engine->GetRasterizer();
- m_canvas = m_engine->GetCanvas();
- // locate the vertex assigned to mat and do following calculation in mesh coordinates
- for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++)
- {
- RAS_MeshObject* mesh = mirror->GetMesh(meshIndex);
- int numPolygons = mesh->NumPolygons();
- for (int polygonIndex=0; polygonIndex < numPolygons; polygonIndex++)
- {
- RAS_Polygon* polygon = mesh->GetPolygon(polygonIndex);
- if (polygon->GetMaterial()->GetPolyMaterial() == mat)
- {
- RAS_TexVert *v1, *v2, *v3, *v4;
- float normal[3];
- float area;
- // this polygon is part of the mirror
- v1 = polygon->GetVertex(0);
- v2 = polygon->GetVertex(1);
- v3 = polygon->GetVertex(2);
- mirrorVerts.push_back(v1);
- mirrorVerts.push_back(v2);
- mirrorVerts.push_back(v3);
- if (polygon->VertexCount() == 4) {
- v4 = polygon->GetVertex(3);
- mirrorVerts.push_back(v4);
- area = normal_quad_v3(normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ());
- }
- else {
- area = normal_tri_v3(normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ());
- }
- area = fabs(area);
- mirrorArea += area;
- mul_v3_fl(normal, area);
- add_v3_v3v3(mirrorNormal, mirrorNormal, normal);
- }
- }
- }
- if (mirrorVerts.size() == 0 || mirrorArea < FLT_EPSILON)
- {
- // no vertex or zero size mirror
- THRWEXCP(MirrorSizeInvalid, S_OK);
- }
- // compute average normal of mirror faces
- mul_v3_fl(mirrorNormal, 1.0f/mirrorArea);
- if (normalize_v3(mirrorNormal) == 0.f)
- {
- // no normal
- THRWEXCP(MirrorNormalInvalid, S_OK);
- }
- // the mirror plane has an equation of the type ax+by+cz = d where (a,b,c) is the normal vector
- // if the mirror is more vertical then horizontal, the Z axis is the up direction.
- // otherwise the Y axis is the up direction.
- // If the mirror is not perfectly vertical(horizontal), the Z(Y) axis projection on the mirror
- // plan by the normal will be the up direction.
- if (fabsf(mirrorNormal[2]) > fabsf(mirrorNormal[1]) &&
- fabsf(mirrorNormal[2]) > fabsf(mirrorNormal[0]))
- {
- // the mirror is more horizontal than vertical
- copy_v3_v3(axis, yaxis);
- }
- else
- {
- // the mirror is more vertical than horizontal
- copy_v3_v3(axis, zaxis);
- }
- dist = dot_v3v3(mirrorNormal, axis);
- if (fabsf(dist) < FLT_EPSILON)
- {
- // the mirror is already fully aligned with up axis
- copy_v3_v3(mirrorUp, axis);
- }
- else
- {
- // projection of axis to mirror plane through normal
- copy_v3_v3(vec, mirrorNormal);
- mul_v3_fl(vec, dist);
- sub_v3_v3v3(mirrorUp, axis, vec);
- if (normalize_v3(mirrorUp) == 0.f)
- {
- // should not happen
- THRWEXCP(MirrorHorizontal, S_OK);
- return;
- }
- }
- // compute rotation matrix between local coord and mirror coord
- // to match camera orientation, we select mirror z = -normal, y = up, x = y x z
- negate_v3_v3(mirrorMat[2], mirrorNormal);
- copy_v3_v3(mirrorMat[1], mirrorUp);
- cross_v3_v3v3(mirrorMat[0], mirrorMat[1], mirrorMat[2]);
- // transpose to make it a orientation matrix from local space to mirror space
- transpose_m3(mirrorMat);
- // transform all vertex to plane coordinates and determine mirror position
- left = FLT_MAX;
- right = -FLT_MAX;
- bottom = FLT_MAX;
- top = -FLT_MAX;
- back = -FLT_MAX; // most backward vertex (=highest Z coord in mirror space)
- for (it = mirrorVerts.begin(); it != mirrorVerts.end(); it++)
- {
- copy_v3_v3(vec, (float*)(*it)->getXYZ());
- mul_m3_v3(mirrorMat, vec);
- if (vec[0] < left)
- left = vec[0];
- if (vec[0] > right)
- right = vec[0];
- if (vec[1] < bottom)
- bottom = vec[1];
- if (vec[1] > top)
- top = vec[1];
- if (vec[2] > back)
- back = vec[2];
- }
- // now store this information in the object for later rendering
- m_mirrorHalfWidth = (right-left)*0.5f;
- m_mirrorHalfHeight = (top-bottom)*0.5f;
- if (m_mirrorHalfWidth < 0.01f || m_mirrorHalfHeight < 0.01f)
- {
- // mirror too small
- THRWEXCP(MirrorTooSmall, S_OK);
- }
- // mirror position in mirror coord
- vec[0] = (left+right)*0.5f;
- vec[1] = (top+bottom)*0.5f;
- vec[2] = back;
- // convert it in local space: transpose again the matrix to get back to mirror to local transform
- transpose_m3(mirrorMat);
- mul_m3_v3(mirrorMat, vec);
- // mirror position in local space
- m_mirrorPos.setValue(vec[0], vec[1], vec[2]);
- // mirror normal vector (pointed towards the back of the mirror) in local space
- m_mirrorZ.setValue(-mirrorNormal[0], -mirrorNormal[1], -mirrorNormal[2]);
- m_mirrorY.setValue(mirrorUp[0], mirrorUp[1], mirrorUp[2]);
- m_mirrorX = m_mirrorY.cross(m_mirrorZ);
- m_render = true;
-
- // set mirror background color to scene background color as default
- setBackgroundFromScene(m_scene);
-}
-
-
-
-
-// define python type
-PyTypeObject ImageMirrorType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.ImageMirror", /*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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Image source from mirror", /* 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 */
- imageMirrorGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ImageMirror_init, /* tp_init */
- 0, /* tp_alloc */
- Image_allocNew, /* tp_new */
-};
-
-
diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h
deleted file mode 100644
index d062db44348..00000000000
--- a/source/gameengine/VideoTexture/ImageRender.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file ImageRender.h
- * \ingroup bgevideotex
- */
-
-#ifndef __IMAGERENDER_H__
-#define __IMAGERENDER_H__
-
-
-#include "Common.h"
-
-#include "KX_Scene.h"
-#include "KX_Camera.h"
-#include "DNA_screen_types.h"
-#include "RAS_ICanvas.h"
-#include "RAS_IRasterizer.h"
-#include "RAS_IOffScreen.h"
-#include "RAS_ISync.h"
-
-#include "ImageViewport.h"
-
-
-/// class for render 3d scene
-class ImageRender : public ImageViewport
-{
-public:
- /// constructor
- ImageRender(KX_Scene *scene, KX_Camera *camera, PyRASOffScreen *offscreen);
- ImageRender(KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial * mat);
-
- /// destructor
- virtual ~ImageRender (void);
-
- /// get background color
- float getBackground (int idx);
- /// set background color
- void setBackground (float red, float green, float blue, float alpha);
-
- /// clipping distance
- float getClip (void) { return m_clip; }
- /// set whole buffer use
- void setClip (float clip) { m_clip = clip; }
- /// render status
- bool isDone() { return m_done; }
- /// render frame (public so that it is accessible from python)
- bool Render();
- /// in case fbo is used, method to unbind
- void Unbind();
- /// wait for render to complete
- void WaitSync();
-
-protected:
- /// true if ready to render
- bool m_render;
- /// is render done already?
- bool m_done;
- /// rendered scene
- KX_Scene * m_scene;
- /// camera for render
- KX_Camera * m_camera;
- /// do we own the camera?
- bool m_owncamera;
- /// if offscreen render
- PyRASOffScreen *m_offscreen;
- /// object to synchronize render even if no buffer transfer
- RAS_ISync *m_sync;
- /// for mirror operation
- KX_GameObject * m_observer;
- KX_GameObject * m_mirror;
- float m_clip; // clipping distance
- float m_mirrorHalfWidth; // mirror width in mirror space
- float m_mirrorHalfHeight; // mirror height in mirror space
- MT_Point3 m_mirrorPos; // mirror center position in local space
- MT_Vector3 m_mirrorZ; // mirror Z axis in local space
- MT_Vector3 m_mirrorY; // mirror Y axis in local space
- MT_Vector3 m_mirrorX; // mirror X axis in local space
- /// canvas
- RAS_ICanvas* m_canvas;
- /// rasterizer
- RAS_IRasterizer* m_rasterizer;
- /// engine
- KX_KetsjiEngine* m_engine;
-
- /// background color
- float m_background[4];
-
-
- /// render 3d scene to image
- virtual void calcImage (unsigned int texId, double ts) { calcViewport(texId, ts, GL_RGBA); }
-
- /// render 3d scene to image
- virtual void calcViewport (unsigned int texId, double ts, unsigned int format);
-
- void setBackgroundFromScene(KX_Scene *scene);
- void SetWorldSettings(KX_WorldInfo* wi);
-};
-
-
-#endif
-
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
deleted file mode 100644
index ad3d8875e28..00000000000
--- a/source/gameengine/VideoTexture/ImageViewport.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageViewport.cpp
- * \ingroup bgevideotex
- */
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "GPU_glew.h"
-
-#include "KX_PythonInit.h"
-#include "RAS_ICanvas.h"
-#include "Texture.h"
-#include "ImageBase.h"
-#include "VideoBase.h"
-#include "FilterSource.h"
-#include "ImageViewport.h"
-
-
-// constructor
-ImageViewport::ImageViewport (PyRASOffScreen *offscreen) : m_alpha(false), m_texInit(false)
-{
- // get viewport rectangle
- if (offscreen) {
- m_viewport[0] = 0;
- m_viewport[1] = 0;
- m_viewport[2] = offscreen->ofs->GetWidth();
- m_viewport[3] = offscreen->ofs->GetHeight();
- }
- else {
- RAS_Rect rect = KX_GetActiveEngine()->GetCanvas()->GetWindowArea();
- m_viewport[0] = rect.GetLeft();
- m_viewport[1] = rect.GetBottom();
- m_viewport[2] = rect.GetWidth();
- m_viewport[3] = rect.GetHeight();
- }
-
- //glGetIntegerv(GL_VIEWPORT, m_viewport);
- // create buffer for viewport image
- // Warning: this buffer is also used to get the depth buffer as an array of
- // float (1 float = 4 bytes per pixel)
- m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]];
- // set attributes
- setWhole((offscreen) ? true : 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[2])
-{
- m_whole = false;
- if (size == NULL)
- size = m_capSize;
- for (int idx = 0; idx < 2; ++idx)
- {
- if (size[idx] < 1)
- m_capSize[idx] = 1;
- else if (size[idx] > getViewportSize()[idx])
- m_capSize[idx] = short(getViewportSize()[idx]);
- else
- m_capSize[idx] = size[idx];
- }
- init(m_capSize[0], m_capSize[1]);
- // set capture position
- setPosition();
-}
-
-// set position of capture rectangle
-void ImageViewport::setPosition (GLint pos[2])
-{
- // 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::calcViewport (unsigned int texId, double ts, unsigned int format)
-{
- // if scale was changed
- if (m_scaleChange)
- // reset image
- init(m_capSize[0], m_capSize[1]);
- // if texture wasn't initialized
- if (!m_texInit && texId != 0) {
- // initialize it
- loadTexture(texId, m_image, m_size);
- m_texInit = true;
- }
- // if texture can be directly created
- if (texId != 0 && m_pyfilter == NULL && m_size[0] == m_capSize[0] &&
- m_size[1] == m_capSize[1] && !m_flip && !m_zbuff && !m_depth)
- {
- // just copy current viewport to texture
- glBindTexture(GL_TEXTURE_2D, texId);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]);
- glBindTexture(GL_TEXTURE_2D, 0);
- // image is not available
- m_avail = false;
- }
- // otherwise copy viewport to buffer, if image is not available
- else if (!m_avail) {
- if (m_zbuff) {
- // Use read pixels with the depth buffer
- // *** misusing m_viewportImage here, but since it has the correct size
- // (4 bytes per pixel = size of float) and we just need it to apply
- // the filter, it's ok
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
- GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage);
- // filter loaded data
- FilterZZZA filt;
- filterImage(filt, (float *)m_viewportImage, m_capSize);
- }
- else {
-
- if (m_depth) {
- // Use read pixels with the depth buffer
- // See warning above about m_viewportImage.
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
- GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage);
- // filter loaded data
- FilterDEPTH filt;
- filterImage(filt, (float *)m_viewportImage, m_capSize);
- }
- else {
-
- // get frame buffer data
- if (m_alpha) {
- // as we are reading the pixel in the native format, we can read directly in the image buffer
- // if we are sure that no processing is needed on the image
- if (m_size[0] == m_capSize[0] &&
- m_size[1] == m_capSize[1] &&
- !m_flip &&
- !m_pyfilter)
- {
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
- GL_UNSIGNED_BYTE, m_image);
- m_avail = true;
- }
- else if (!m_pyfilter) {
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
- GL_UNSIGNED_BYTE, m_viewportImage);
- FilterRGBA32 filt;
- filterImage(filt, m_viewportImage, m_capSize);
- }
- else {
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA,
- GL_UNSIGNED_BYTE, m_viewportImage);
- FilterRGBA32 filt;
- filterImage(filt, m_viewportImage, m_capSize);
- if (format == GL_BGRA) {
- // in place byte swapping
- swapImageBR();
- }
- }
- }
- else {
- 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
- FilterRGB24 filt;
- filterImage(filt, m_viewportImage, m_capSize);
- if (format == GL_BGRA) {
- // in place byte swapping
- swapImageBR();
- }
- }
- }
- }
- }
-}
-
-bool ImageViewport::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
-{
- unsigned int *tmp_image;
- bool ret;
-
- // if scale was changed
- if (m_scaleChange) {
- // reset image
- init(m_capSize[0], m_capSize[1]);
- }
-
- // size must be identical
- if (size < getBuffSize())
- return false;
-
- if (m_avail) {
- // just copy
- return ImageBase::loadImage(buffer, size, format, ts);
- }
- else {
- tmp_image = m_image;
- m_image = buffer;
- calcViewport(0, ts, format);
- ret = m_avail;
- m_image = tmp_image;
- // since the image was not loaded to our buffer, it's not valid
- m_avail = false;
- }
- return ret;
-}
-
-
-// cast Image pointer to ImageViewport
-inline ImageViewport * getImageViewport (PyImage *self)
-{ return static_cast<ImageViewport*>(self->m_image); }
-
-
-// python methods
-
-
-// get whole
-PyObject *ImageViewport_getWhole (PyImage *self, void *closure)
-{
- if (self->m_image != NULL && getImageViewport(self)->getWhole()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set whole
-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;
- }
- try
- {
- // set whole, can throw in case of resize and buffer exports
- if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // success
- return 0;
-}
-
-// get alpha
-PyObject *ImageViewport_getAlpha (PyImage *self, void *closure)
-{
- if (self->m_image != NULL && getImageViewport(self)->getAlpha()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set whole
-int ImageViewport_setAlpha(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 alpha
- if (self->m_image != NULL) getImageViewport(self)->setAlpha(value == Py_True);
- // success
- return 0;
-}
-
-
-// get position
-static PyObject *ImageViewport_getPosition (PyImage *self, void *closure)
-{
- GLint *pos = getImageViewport(self)->getPosition();
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, PyLong_FromLong(pos[0]));
- PyTuple_SET_ITEM(ret, 1, PyLong_FromLong(pos[1]));
- return ret;
-}
-
-// set position
-static int ImageViewport_setPosition(PyImage *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL ||
- !(PyTuple_Check(value) || PyList_Check(value)) ||
- PySequence_Fast_GET_SIZE(value) != 2 ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints");
- return -1;
- }
- // set position
- GLint pos[2] = {
- GLint(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
- GLint(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 1)))
- };
- getImageViewport(self)->setPosition(pos);
- // success
- return 0;
-}
-
-// get capture size
-PyObject *ImageViewport_getCaptureSize (PyImage *self, void *closure)
-{
- short *size = getImageViewport(self)->getCaptureSize();
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, PyLong_FromLong(size[0]));
- PyTuple_SET_ITEM(ret, 1, PyLong_FromLong(size[1]));
- return ret;
-}
-
-// set capture size
-int ImageViewport_setCaptureSize(PyImage *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL ||
- !(PyTuple_Check(value) || PyList_Check(value)) ||
- PySequence_Fast_GET_SIZE(value) != 2 ||
- !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) ||
- !PyLong_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[2] = {
- short(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
- short(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 1)))
- };
- try
- {
- // can throw in case of resize and buffer exports
- getImageViewport(self)->setCaptureSize(size);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // success
- return 0;
-}
-
-
-// methods structure
-static PyMethodDef imageViewportMethods[] =
-{ // methods from ImageBase class
- {"refresh", (PyCFunction)Image_refresh, METH_VARARGS, "Refresh image - invalidate its current content"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef imageViewportGetSets[] =
-{
- {(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},
- {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", NULL},
- {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
- {(char*)"zbuff", (getter)Image_getZbuff, (setter)Image_setZbuff, (char*)"use depth buffer as texture", NULL},
- {(char*)"depth", (getter)Image_getDepth, (setter)Image_setDepth, (char*)"get depth information from z-buffer as array of float", NULL},
- {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
- {NULL}
-};
-
-
-// define python type
-PyTypeObject ImageViewportType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Image source from viewport", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- imageViewportMethods, /* tp_methods */
- 0, /* tp_members */
- imageViewportGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Image_init<ImageViewport>, /* tp_init */
- 0, /* tp_alloc */
- Image_allocNew, /* tp_new */
-};
diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h
deleted file mode 100644
index 8a7e9cfd2ba..00000000000
--- a/source/gameengine/VideoTexture/ImageViewport.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file ImageViewport.h
- * \ingroup bgevideotex
- */
-
-#ifndef __IMAGEVIEWPORT_H__
-#define __IMAGEVIEWPORT_H__
-
-
-#include "Common.h"
-
-#include "ImageBase.h"
-#include "RAS_IOffScreen.h"
-
-
-/// class for viewport access
-class ImageViewport : public ImageBase
-{
-public:
- /// constructor
- ImageViewport (PyRASOffScreen *offscreen=NULL);
-
- /// destructor
- virtual ~ImageViewport (void);
-
- /// is whole buffer used
- bool getWhole (void) { return m_whole; }
- /// set whole buffer use
- void setWhole (bool whole);
-
- /// is alpha channel used
- bool getAlpha (void) { return m_alpha; }
- /// set whole buffer use
- void setAlpha (bool alpha) { m_alpha = alpha; }
-
- /// get capture size in viewport
- short * getCaptureSize (void) { return m_capSize; }
- /// set capture size in viewport
- void setCaptureSize (short size[2] = NULL);
-
- /// get position in viewport
- GLint * getPosition (void) { return m_position; }
- /// set position in viewport
- void setPosition (GLint pos[2] = NULL);
-
- /// capture image from viewport to user buffer
- virtual bool loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts);
-
-protected:
- /// frame buffer rectangle
- GLint m_viewport[4];
-
- /// size of captured area
- short m_capSize[2];
- /// use whole viewport
- bool m_whole;
- /// use alpha channel
- bool m_alpha;
-
- /// position of capture rectangle in viewport
- GLint m_position[2];
- /// upper left point for capturing
- GLint m_upLeft[2];
-
- /// buffer to copy viewport
- BYTE * m_viewportImage;
- /// texture is initialized
- bool m_texInit;
-
- /// capture image from viewport
- virtual void calcImage (unsigned int texId, double ts) { calcViewport(texId, ts, GL_RGBA); }
-
- /// capture image from viewport
- virtual void calcViewport (unsigned int texId, double ts, unsigned int format);
-
- /// get viewport size
- GLint * getViewportSize (void) { return m_viewport + 2; }
-};
-
-PyObject *ImageViewport_getCaptureSize(PyImage *self, void *closure);
-int ImageViewport_setCaptureSize(PyImage *self, PyObject *value, void *closure);
-PyObject *ImageViewport_getWhole(PyImage *self, void *closure);
-int ImageViewport_setWhole(PyImage *self, PyObject *value, void *closure);
-PyObject *ImageViewport_getAlpha(PyImage *self, void *closure);
-int ImageViewport_setAlpha(PyImage *self, PyObject *value, void *closure);
-
-#endif
-
diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp
deleted file mode 100644
index 18f477f6178..00000000000
--- a/source/gameengine/VideoTexture/PyTypeList.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/PyTypeList.cpp
- * \ingroup bgevideotex
- */
-
-#include "PyTypeList.h"
-
-#include <memory>
-#include <vector>
-
-#include "EXP_PyObjectPlus.h"
-
-/// destructor
-PyTypeList::~PyTypeList()
-{
- // if list exists
- if (m_list.get() != NULL)
- for (PyTypeListType::iterator it = m_list->begin(); it != m_list->end(); ++it)
- delete *it;
-}
-
-/// 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)
-{
- // 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
deleted file mode 100644
index ce0eb81e656..00000000000
--- a/source/gameengine/VideoTexture/PyTypeList.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of blendTex library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file PyTypeList.h
- * \ingroup bgevideotex
- */
-
-#ifndef __PYTYPELIST_H__
-#define __PYTYPELIST_H__
-
-#include "Common.h"
-
-#include <memory>
-#include <vector>
-
-#include "EXP_PyObjectPlus.h"
-
-// forward declaration
-class PyTypeListItem;
-
-// type for list of types
-typedef std::vector<PyTypeListItem*> PyTypeListType;
-
-
-/// class to store list of python types
-class PyTypeList
-{
-public:
- /// destructor
- ~PyTypeList();
-
- /// 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
-#if (__cplusplus > 199711L) /* || (defined(_MSC_VER) && _MSC_VER >= 1800) */
- std::unique_ptr<PyTypeListType> m_list;
-#else
- std::auto_ptr<PyTypeListType> m_list;
-#endif
-};
-
-
-/// class for item of python type list
-class PyTypeListItem
-{
-public:
- /// constructor adds type into list
- PyTypeListItem (PyTypeObject *type, const char * name)
- : m_type(type), m_name(name)
- { }
-
- /// does type match
- PyTypeObject *getType (void) { return m_type; }
-
- /// get name of type
- const char * getName (void) { return m_name; }
-
-protected:
- /// pointer to type object
- PyTypeObject *m_type;
- /// name of type
- const char *m_name;
-};
-
-
-#endif
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
deleted file mode 100644
index 48dc4c705bf..00000000000
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/Texture.cpp
- * \ingroup bgevideotex
- */
-
-// implementation
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "KX_GameObject.h"
-#include "KX_Light.h"
-#include "RAS_MeshObject.h"
-#include "RAS_ILightObject.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_image_types.h"
-#include "IMB_imbuf_types.h"
-#include "BKE_image.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "KX_BlenderMaterial.h"
-#include "BL_Texture.h"
-
-#include "KX_KetsjiEngine.h"
-#include "KX_PythonInit.h"
-#include "Texture.h"
-#include "ImageBase.h"
-#include "Exception.h"
-
-#include <memory.h>
-#include "GPU_glew.h"
-
-extern "C" {
- #include "IMB_imbuf.h"
-}
-
-// macro for exception handling and logging
-#define CATCH_EXCP catch (Exception & exp) \
-{ exp.report(); return NULL; }
-
-
-// Blender GameObject type
-static BlendType<KX_GameObject> gameObjectType ("KX_GameObject");
-static BlendType<KX_LightObject> lightObjectType ("KX_LightObject");
-
-
-// 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)
- {
- int i;
- ImBuf *ibuf;
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- ibuf = IMB_allocFromBuffer(texture, NULL, size[0], size[1]);
-
- IMB_makemipmap(ibuf, true);
-
- for (i = 0; i < ibuf->miptot; i++) {
- ImBuf *mip = IMB_getmipmap(ibuf, i);
-
- glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
- }
- IMB_freeImBuf(ibuf);
- }
- else
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
- }
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-}
-
-
-// get pointer to material
-RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID)
-{
- // if object is available
- if (obj != NULL)
- {
- // get pointer to texture image
- KX_GameObject * gameObj = gameObjectType.checkType(obj);
- if (gameObj != NULL && gameObj->GetMeshCount() > 0)
- {
- // get material from mesh
- RAS_MeshObject * mesh = gameObj->GetMesh(0);
- RAS_MeshMaterial *meshMat = mesh->GetMeshMaterial(matID);
- if (meshMat != NULL && meshMat->m_bucket != NULL)
- // return pointer to polygon or blender material
- return meshMat->m_bucket->GetPolyMaterial();
- }
- }
- // otherwise material was not found
- return NULL;
-}
-
-// get pointer to a lamp
-static KX_LightObject *getLamp(PyObject *obj)
-{
- // if object is available
- if (obj == NULL) return NULL;
-
- // returns NULL if obj is not a KX_LightObject
- return lightObjectType.checkType(obj);
-}
-
-
-// get material ID
-short getMaterialID(PyObject *obj, const 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;
- // name is a material name if it starts with MA and a UV texture name if it starts with IM
- if (name[0] == 'I' && name[1] == 'M') {
- // if texture name matches
- if (strcmp(mat->GetTextureName().ReadPtr(), name) == 0)
- return matID;
- }
- else {
- // if material name matches
- if (strcmp(mat->GetMaterialName().ReadPtr(), name) == 0)
- return matID;
- }
- }
- // material was not found
- return -1;
-}
-
-
-// Texture object allocation
-static PyObject *Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- // allocate object
- Texture * self = reinterpret_cast<Texture*>(type->tp_alloc(type, 0));
- // initialize object structure
- self->m_actTex = 0;
- self->m_orgSaved = false;
- self->m_imgBuf = NULL;
- self->m_imgTexture = NULL;
- self->m_matTexture = NULL;
- self->m_mipmap = false;
- self->m_scaledImBuf = NULL;
- self->m_source = NULL;
- self->m_lastClock = 0.0;
- // return allocated object
- return reinterpret_cast<PyObject*>(self);
-}
-
-
-// forward declaration
-PyObject *Texture_close(Texture *self);
-int Texture_setSource(Texture *self, PyObject *value, void *closure);
-
-
-// Texture object deallocation
-static void Texture_dealloc(Texture *self)
-{
- // release renderer
- Py_XDECREF(self->m_source);
- // close texture
- PyObject *ret = Texture_close(self);
- Py_DECREF(ret);
- // release scaled image buffer
- IMB_freeImBuf(self->m_scaledImBuf);
- // release object
- Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
-}
-
-
-ExceptionID MaterialNotAvail;
-ExpDesc MaterialNotAvailDesc(MaterialNotAvail, "Texture material is not available");
-
-// Texture object initialization
-static 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 const char *kwlist[] = {"gameObj", "materialID", "textureID", "textureObj", NULL};
-
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhO!",
- const_cast<char**>(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);
- KX_LightObject * lamp = getLamp(obj);
- if (mat != NULL)
- {
- // is it blender material or polygon material
- if (mat->GetFlag() & RAS_BLENDERGLSL)
- {
- self->m_imgTexture = static_cast<KX_BlenderMaterial*>(mat)->getImage(texID);
- self->m_useMatTexture = false;
- } else
- {
- // get blender material texture
- self->m_matTexture = static_cast<KX_BlenderMaterial*>(mat)->getTex(texID);
- self->m_useMatTexture = true;
- }
- }
- else if (lamp != NULL)
- {
- self->m_imgTexture = lamp->GetLightData()->GetTextureImage(texID);
- self->m_useMatTexture = false;
- }
-
- // check if texture is available, if not, initialization failed
- if (self->m_imgTexture == NULL && self->m_matTexture == NULL)
- // throw exception if initialization failed
- THRWEXCP(MaterialNotAvail, S_OK);
-
- // if texture object is provided
- if (texObj != NULL)
- {
- // copy texture code
- self->m_actTex = texObj->m_actTex;
- self->m_mipmap = texObj->m_mipmap;
- if (texObj->m_source != NULL)
- Texture_setSource(self, reinterpret_cast<PyObject*>(texObj->m_source), NULL);
- }
- else
- // otherwise generate texture code
- glGenTextures(1, (GLuint*)&self->m_actTex);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- }
- // initialization succeded
- return 0;
-}
-
-
-// close added texture
-PyObject *Texture_close(Texture * self)
-{
- // restore texture
- if (self->m_orgSaved)
- {
- self->m_orgSaved = false;
- // restore original texture code
- if (self->m_useMatTexture)
- self->m_matTexture->swapTexture(self->m_orgTex);
- else
- {
- self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_orgTex;
- BKE_image_release_ibuf(self->m_imgTexture, self->m_imgBuf, NULL);
- self->m_imgBuf = NULL;
- }
- // drop actual texture
- if (self->m_actTex != 0)
- {
- glDeleteTextures(1, (GLuint *)&self->m_actTex);
- self->m_actTex = 0;
- }
- }
- Py_RETURN_NONE;
-}
-
-
-// refresh texture
-static PyObject *Texture_refresh(Texture *self, PyObject *args)
-{
- // get parameter - refresh source
- PyObject *param;
- double ts = -1.0;
-
- if (!PyArg_ParseTuple(args, "O|d:refresh", &param, &ts) || !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 (self->m_useMatTexture)
- self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex);
- else
- {
- // Swapping will work only if the GPU has already loaded the image.
- // If not, it will delete and overwrite our texture on next render.
- // To avoid that, we acquire the image buffer now.
- // WARNING: GPU has a ImageUser to pass, we don't. Using NULL
- // works on image file, not necessarily on other type of image.
- self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL);
- self->m_orgTex = self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D];
- self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_actTex;
- }
- }
-
- // get texture
- unsigned int * texture = self->m_source->m_image->getImage(self->m_actTex, ts);
- // if texture is available
- if (texture != NULL)
- {
- // get texture size
- short * orgSize = self->m_source->m_image->getSize();
- // calc scaled sizes
- short size[2];
- if (GLEW_ARB_texture_non_power_of_two)
- {
- size[0] = orgSize[0];
- size[1] = orgSize[1];
- }
- else
- {
- size[0] = ImageBase::calcSize(orgSize[0]);
- size[1] = ImageBase::calcSize(orgSize[1]);
- }
- // scale texture if needed
- if (size[0] != orgSize[0] || size[1] != orgSize[1])
- {
- IMB_freeImBuf(self->m_scaledImBuf);
- self->m_scaledImBuf = IMB_allocFromBuffer(texture, NULL, orgSize[0], orgSize[1]);
- IMB_scaleImBuf(self->m_scaledImBuf, size[0], size[1]);
-
- // use scaled image instead original
- texture = self->m_scaledImBuf->rect;
- }
- // 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 OpenGL Bind Id
-static PyObject *Texture_getBindId(Texture *self, void *closure)
-{
- unsigned int id = self->m_actTex;
- return Py_BuildValue("h", id);
-}
-
-// get mipmap value
-static 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
-static 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
-static PyObject *Texture_getSource(Texture *self, PyObject *value, void *closure)
-{
- // if source exists
- if (self->m_source != NULL)
- {
- Py_INCREF(self->m_source);
- return reinterpret_cast<PyObject*>(self->m_source);
- }
- // otherwise return None
- Py_RETURN_NONE;
-}
-
-
-// set source object
-int Texture_setSource(Texture *self, PyObject *value, void *closure)
-{
- // check new value
- if (value == NULL || !pyImageTypes.in(Py_TYPE(value)))
- {
- // report value error
- PyErr_SetString(PyExc_TypeError, "Invalid type of value");
- return -1;
- }
- // increase ref count for new value
- Py_INCREF(value);
- // release previous
- Py_XDECREF(self->m_source);
- // set new value
- self->m_source = reinterpret_cast<PyImage*>(value);
- // return success
- return 0;
-}
-
-
-// class Texture methods
-static PyMethodDef textureMethods[] =
-{
- { "close", (PyCFunction)Texture_close, METH_NOARGS, "Close dynamic texture and restore original"},
- { "refresh", (PyCFunction)Texture_refresh, METH_VARARGS, "Refresh texture from source"},
- {NULL} /* Sentinel */
-};
-
-// class Texture attributes
-static PyGetSetDef textureGetSets[] =
-{
- {(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},
- {(char*)"bindId", (getter)Texture_getBindId, NULL, (char*)"OpenGL Bind Name", NULL},
- {NULL}
-};
-
-
-// class Texture declaration
-PyTypeObject TextureType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*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
deleted file mode 100644
index dc38b4181bb..00000000000
--- a/source/gameengine/VideoTexture/Texture.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoTexture/Texture.h
- * \ingroup bgevideotex
- */
-
-#ifndef __TEXTURE_H__
-#define __TEXTURE_H__
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "DNA_image_types.h"
-#include "BL_Texture.h"
-#include "KX_BlenderMaterial.h"
-
-#include "ImageBase.h"
-#include "BlendType.h"
-#include "Exception.h"
-
-
-struct ImBuf;
-
-// type Texture declaration
-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
- bool m_orgSaved;
-
- // kernel image buffer, to make sure the image is loaded before we swap the bindcode
- struct ImBuf *m_imgBuf;
- // texture image for game materials
- Image * m_imgTexture;
- // texture for blender materials
- BL_Texture * m_matTexture;
-
- // use mipmapping
- bool m_mipmap;
-
- // scaled image buffer
- ImBuf * m_scaledImBuf;
- // last refresh
- double m_lastClock;
-
- // image source
- PyImage * m_source;
-};
-
-
-// Texture type description
-extern PyTypeObject TextureType;
-
-// 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, const char *name);
-
-// Exceptions
-extern ExceptionID MaterialNotAvail;
-
-#endif
diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp
deleted file mode 100644
index d373055b5df..00000000000
--- a/source/gameengine/VideoTexture/VideoBase.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/VideoBase.cpp
- * \ingroup bgevideotex
- */
-
-#if defined WIN32
-#define WINDOWS_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "VideoBase.h"
-
-#include "FilterSource.h"
-
-// VideoBase implementation
-
-
-// initialize image data
-void VideoBase::init(short width, short height)
-{
- // save original sizes
- m_orgSize[0] = width;
- m_orgSize[1] = height;
- // call base class initialization
- ImageBase::init(width, height);
-}
-
-
-// process video frame
-void VideoBase::process (BYTE *sample)
-{
- // if scale was changed
- if (m_scaleChange)
- // reset image
- init(m_orgSize[0], m_orgSize[1]);
- // if image is allocated and is able to store new image
- if (m_image != NULL && !m_avail)
- {
- // filters used
- // convert video format to image
- switch (m_format)
- {
- case RGBA32:
- {
- FilterRGBA32 filtRGBA;
- // use filter object for format to convert image
- filterImage(filtRGBA, sample, m_orgSize);
- // finish
- break;
- }
- case RGB24:
- {
- FilterRGB24 filtRGB;
- // 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
- FilterYV12 filtYUV;
- filtYUV.setBuffs(sample, m_orgSize);
- filterImage(filtYUV, sample, m_orgSize);
- // finish
- break;
- }
- case None:
- break; /* assert? */
- }
- }
-}
-
-
-// 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; }
-
-// pause video
-PyObject *Video_pause(PyImage *self)
-{ if (getVideo(self)->pause()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
-
-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, PyObject *args)
-{
- Py_buffer buffer;
- char *mode = NULL;
- unsigned int format;
- double ts = -1.0;
-
- memset(&buffer, 0, sizeof(buffer));
- if (PyArg_ParseTuple(args, "|s*sd:refresh", &buffer, &mode, &ts)) {
- if (buffer.buf) {
- // a target buffer is provided, verify its format
- if (buffer.readonly) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be writable");
- }
- else if (!PyBuffer_IsContiguous(&buffer, 'C')) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be contiguous in memory");
- }
- else if (((intptr_t)buffer.buf & 3) != 0) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be aligned to 4 bytes boundary");
- }
- else {
- // ready to get the image into our buffer
- try {
- if (mode == NULL || !strcmp(mode, "RGBA"))
- format = GL_RGBA;
- else if (!strcmp(mode, "BGRA"))
- format = GL_BGRA;
- else
- THRWEXCP(InvalidImageMode,S_OK);
-
- if (!self->m_image->loadImage((unsigned int *)buffer.buf, buffer.len, format, ts)) {
- PyErr_SetString(PyExc_TypeError, "Could not load the buffer, perhaps size is not compatible");
- }
- }
- catch (Exception & exp) {
- exp.report();
- }
- }
- PyBuffer_Release(&buffer);
- if (PyErr_Occurred())
- return NULL;
- }
- }
- else
- {
- return NULL;
- }
- 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_Size(value) != 2 ||
- /* XXX - this is incorrect if the sequence is not a list/tuple! */
- !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 float");
- 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 || !PyLong_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be an int");
- return -1;
- }
- // set repeat
- getVideo(self)->setRepeat(int(PyLong_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
deleted file mode 100644
index 77f46fdccd8..00000000000
--- a/source/gameengine/VideoTexture/VideoBase.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoBase.h
- * \ingroup bgevideotex
- */
-
-#ifndef __VIDEOBASE_H__
-#define __VIDEOBASE_H__
-
-
-#include "EXP_PyObjectPlus.h"
-
-#include "ImageBase.h"
-
-#include "Exception.h"
-
-// source states
-const int SourceError = -1;
-const int SourceEmpty = 0;
-const int SourceReady = 1;
-const int SourcePlaying = 2;
-const int SourceStopped = 3;
-
-
-// video source formats
-enum VideoFormat { None, RGB24, YV12, RGBA32 };
-
-
-/// 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;
- }
- /// pause video
- virtual bool pause (void)
- {
- if (m_status == SourcePlaying)
- {
- m_status = SourceStopped;
- return true;
- }
- return false;
- }
- /// stop 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.0f ? rate : 1.0f; }
-
-protected:
- /// video format
- VideoFormat m_format;
- /// original video size
- short m_orgSize[2];
-
- /// video status
- int m_status;
-
- /// is source file
- bool m_isFile;
-
- /// replay range
- double m_range[2];
- /// repeat count
- int m_repeat;
- /// frame rate
- float m_frameRate;
-
- /// initialize image data
- void init (short width, short height);
-
- /// process source data
- void process (BYTE * sample);
-};
-
-
-
-// python fuctions
-
-
-// cast Image pointer to Video
-inline VideoBase *getVideo(PyImage *self)
-{ return static_cast<VideoBase*>(self->m_image); }
-
-
-extern ExceptionID SourceVideoCreation;
-
-// object initialization
-template <class T> void Video_init(PyImage *self)
-{
- // create source video object
- if (self->m_image != NULL) delete self->m_image;
- HRESULT hRslt = S_OK;
- self->m_image = new T(&hRslt);
- CHCKHRSLT(hRslt, SourceVideoCreation);
-}
-
-
-// video functions
-void Video_open(VideoBase *self, char *file, short captureID);
-PyObject *Video_play(PyImage *self);
-PyObject *Video_pause(PyImage *self);
-PyObject *Video_stop(PyImage *self);
-PyObject *Video_refresh(PyImage *self, PyObject *args);
-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);
-
-/* py api */
-extern PyTypeObject ImageRenderType;
-extern PyTypeObject ImageMirrorType;
-extern PyTypeObject ImageViewportType;
-
-#endif /* __VIDEOBASE_H__ */
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.cpp b/source/gameengine/VideoTexture/VideoDeckLink.cpp
deleted file mode 100644
index c588a4b33cf..00000000000
--- a/source/gameengine/VideoTexture/VideoDeckLink.cpp
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2015, Blender Foundation
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Blender Foundation.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/VideoDeckLink.cpp
- * \ingroup bgevideotex
- */
-
-#ifdef WITH_GAMEENGINE_DECKLINK
-
-// FFmpeg defines its own version of stdint.h on Windows.
-// Decklink needs FFmpeg, so it uses its version of stdint.h
-// this is necessary for INT64_C macro
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-// this is necessary for UINTPTR_MAX (used by atomic-ops)
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#ifdef __STDC_LIMIT_MACROS /* else it may be unused */
-#endif
-#endif
-#include <stdint.h>
-#include <string.h>
-#ifndef WIN32
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#endif
-
-#include "atomic_ops.h"
-
-#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-#include "VideoDeckLink.h"
-#include "DeckLink.h"
-#include "Exception.h"
-#include "KX_KetsjiEngine.h"
-#include "KX_PythonInit.h"
-
-extern ExceptionID DeckLinkInternalError;
-ExceptionID SourceVideoOnlyCapture, VideoDeckLinkBadFormat, VideoDeckLinkOpenCard, VideoDeckLinkDvpInternalError, VideoDeckLinkPinMemoryError;
-ExpDesc SourceVideoOnlyCaptureDesc(SourceVideoOnlyCapture, "This video source only allows live capture");
-ExpDesc VideoDeckLinkBadFormatDesc(VideoDeckLinkBadFormat, "Invalid or unsupported capture format, should be <mode>/<pixel>[/3D]");
-ExpDesc VideoDeckLinkOpenCardDesc(VideoDeckLinkOpenCard, "Cannot open capture card, check if driver installed");
-ExpDesc VideoDeckLinkDvpInternalErrorDesc(VideoDeckLinkDvpInternalError, "DVP API internal error, please report");
-ExpDesc VideoDeckLinkPinMemoryErrorDesc(VideoDeckLinkPinMemoryError, "Error pinning memory");
-
-
-#ifdef WIN32
-////////////////////////////////////////////
-// SynInfo
-//
-// Sets up a semaphore which is shared between the GPU and CPU and used to
-// synchronise access to DVP buffers.
-#define DVP_CHECK(cmd) if ((cmd) != DVP_STATUS_OK) THRWEXCP(VideoDeckLinkDvpInternalError, S_OK)
-
-struct SyncInfo
-{
- SyncInfo(uint32_t semaphoreAllocSize, uint32_t semaphoreAddrAlignment)
- {
- mSemUnaligned = (uint32_t*)malloc(semaphoreAllocSize + semaphoreAddrAlignment - 1);
-
- // Apply alignment constraints
- uint64_t val = (uint64_t)mSemUnaligned;
- val += semaphoreAddrAlignment - 1;
- val &= ~((uint64_t)semaphoreAddrAlignment - 1);
- mSem = (uint32_t*)val;
-
- // Initialise
- mSem[0] = 0;
- mReleaseValue = 0;
- mAcquireValue = 0;
-
- // Setup DVP sync object and import it
- DVPSyncObjectDesc syncObjectDesc;
- syncObjectDesc.externalClientWaitFunc = NULL;
- syncObjectDesc.sem = (uint32_t*)mSem;
-
- DVP_CHECK(dvpImportSyncObject(&syncObjectDesc, &mDvpSync));
-
- }
- ~SyncInfo()
- {
- dvpFreeSyncObject(mDvpSync);
- free((void*)mSemUnaligned);
- }
-
- volatile uint32_t* mSem;
- volatile uint32_t* mSemUnaligned;
- volatile uint32_t mReleaseValue;
- volatile uint32_t mAcquireValue;
- DVPSyncObjectHandle mDvpSync;
-};
-
-////////////////////////////////////////////
-// TextureTransferDvp: transfer with GPUDirect
-////////////////////////////////////////////
-
-class TextureTransferDvp : public TextureTransfer
-{
-public:
- TextureTransferDvp(DVPBufferHandle dvpTextureHandle, TextureDesc *pDesc, void *address, uint32_t allocatedSize)
- {
- DVPSysmemBufferDesc sysMemBuffersDesc;
-
- mExtSync = NULL;
- mGpuSync = NULL;
- mDvpSysMemHandle = 0;
- mDvpTextureHandle = 0;
- mTextureHeight = 0;
- mAllocatedSize = 0;
- mBuffer = NULL;
-
- if (!_PinBuffer(address, allocatedSize))
- THRWEXCP(VideoDeckLinkPinMemoryError, S_OK);
- mAllocatedSize = allocatedSize;
- mBuffer = address;
-
- try {
- if (!mBufferAddrAlignment) {
- DVP_CHECK(dvpGetRequiredConstantsGLCtx(&mBufferAddrAlignment, &mBufferGpuStrideAlignment,
- &mSemaphoreAddrAlignment, &mSemaphoreAllocSize,
- &mSemaphorePayloadOffset, &mSemaphorePayloadSize));
- }
- mExtSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
- mGpuSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
- sysMemBuffersDesc.width = pDesc->width;
- sysMemBuffersDesc.height = pDesc->height;
- sysMemBuffersDesc.stride = pDesc->stride;
- switch (pDesc->format) {
- case GL_RED_INTEGER:
- sysMemBuffersDesc.format = DVP_RED_INTEGER;
- break;
- default:
- sysMemBuffersDesc.format = DVP_BGRA;
- break;
- }
- switch (pDesc->type) {
- case GL_UNSIGNED_BYTE:
- sysMemBuffersDesc.type = DVP_UNSIGNED_BYTE;
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- sysMemBuffersDesc.type = DVP_UNSIGNED_INT_2_10_10_10_REV;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- sysMemBuffersDesc.type = DVP_UNSIGNED_INT_8_8_8_8;
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- sysMemBuffersDesc.type = DVP_UNSIGNED_INT_10_10_10_2;
- break;
- default:
- sysMemBuffersDesc.type = DVP_UNSIGNED_INT;
- break;
- }
- sysMemBuffersDesc.size = pDesc->width * pDesc->height * 4;
- sysMemBuffersDesc.bufAddr = mBuffer;
- DVP_CHECK(dvpCreateBuffer(&sysMemBuffersDesc, &mDvpSysMemHandle));
- DVP_CHECK(dvpBindToGLCtx(mDvpSysMemHandle));
- mDvpTextureHandle = dvpTextureHandle;
- mTextureHeight = pDesc->height;
- }
- catch (Exception &) {
- clean();
- throw;
- }
- }
- ~TextureTransferDvp()
- {
- clean();
- }
-
- virtual void PerformTransfer()
- {
- // perform the transfer
- // tell DVP that the old texture buffer will no longer be used
- dvpMapBufferEndAPI(mDvpTextureHandle);
- // do we need this?
- mGpuSync->mReleaseValue++;
- dvpBegin();
- // Copy from system memory to GPU texture
- dvpMapBufferWaitDVP(mDvpTextureHandle);
- dvpMemcpyLined(mDvpSysMemHandle, mExtSync->mDvpSync, mExtSync->mAcquireValue, DVP_TIMEOUT_IGNORED,
- mDvpTextureHandle, mGpuSync->mDvpSync, mGpuSync->mReleaseValue, 0, mTextureHeight);
- dvpMapBufferEndDVP(mDvpTextureHandle);
- dvpEnd();
- dvpMapBufferWaitAPI(mDvpTextureHandle);
- // the transfer is now complete and the texture is ready for use
- }
-
-private:
- static uint32_t mBufferAddrAlignment;
- static uint32_t mBufferGpuStrideAlignment;
- static uint32_t mSemaphoreAddrAlignment;
- static uint32_t mSemaphoreAllocSize;
- static uint32_t mSemaphorePayloadOffset;
- static uint32_t mSemaphorePayloadSize;
-
- void clean()
- {
- if (mDvpSysMemHandle) {
- dvpUnbindFromGLCtx(mDvpSysMemHandle);
- dvpDestroyBuffer(mDvpSysMemHandle);
- }
- if (mExtSync)
- delete mExtSync;
- if (mGpuSync)
- delete mGpuSync;
- if (mBuffer)
- _UnpinBuffer(mBuffer, mAllocatedSize);
- }
- SyncInfo* mExtSync;
- SyncInfo* mGpuSync;
- DVPBufferHandle mDvpSysMemHandle;
- DVPBufferHandle mDvpTextureHandle;
- uint32_t mTextureHeight;
- uint32_t mAllocatedSize;
- void* mBuffer;
-};
-
-uint32_t TextureTransferDvp::mBufferAddrAlignment;
-uint32_t TextureTransferDvp::mBufferGpuStrideAlignment;
-uint32_t TextureTransferDvp::mSemaphoreAddrAlignment;
-uint32_t TextureTransferDvp::mSemaphoreAllocSize;
-uint32_t TextureTransferDvp::mSemaphorePayloadOffset;
-uint32_t TextureTransferDvp::mSemaphorePayloadSize;
-
-#endif
-
-////////////////////////////////////////////
-// TextureTransferOGL: transfer using standard OGL buffers
-////////////////////////////////////////////
-
-class TextureTransferOGL : public TextureTransfer
-{
-public:
- TextureTransferOGL(GLuint texId, TextureDesc *pDesc, void *address)
- {
- memcpy(&mDesc, pDesc, sizeof(mDesc));
- mTexId = texId;
- mBuffer = address;
-
- // as we cache transfer object, we will create one texture to hold the buffer
- glGenBuffers(1, &mUnpinnedTextureBuffer);
- // create a storage for it
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mUnpinnedTextureBuffer);
- glBufferData(GL_PIXEL_UNPACK_BUFFER, pDesc->size, NULL, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- }
- ~TextureTransferOGL()
- {
- glDeleteBuffers(1, &mUnpinnedTextureBuffer);
- }
-
- virtual void PerformTransfer()
- {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mUnpinnedTextureBuffer);
- glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, mDesc.size, mBuffer);
- glBindTexture(GL_TEXTURE_2D, mTexId);
- // NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDesc.width, mDesc.height, mDesc.format, mDesc.type, NULL);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- }
-private:
- // intermediate texture to receive the buffer
- GLuint mUnpinnedTextureBuffer;
- // target texture to receive the image
- GLuint mTexId;
- // buffer
- void *mBuffer;
- // characteristic of the image
- TextureDesc mDesc;
-};
-
-////////////////////////////////////////////
-// TextureTransferPMB: transfer using pinned memory buffer
-////////////////////////////////////////////
-
-class TextureTransferPMD : public TextureTransfer
-{
-public:
- TextureTransferPMD(GLuint texId, TextureDesc *pDesc, void *address, uint32_t allocatedSize)
- {
- memcpy(&mDesc, pDesc, sizeof(mDesc));
- mTexId = texId;
- mBuffer = address;
- mAllocatedSize = allocatedSize;
-
- _PinBuffer(address, allocatedSize);
-
- // as we cache transfer object, we will create one texture to hold the buffer
- glGenBuffers(1, &mPinnedTextureBuffer);
- // create a storage for it
- glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, mPinnedTextureBuffer);
- glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, pDesc->size, address, GL_STREAM_DRAW);
- glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
- }
- ~TextureTransferPMD()
- {
- glDeleteBuffers(1, &mPinnedTextureBuffer);
- if (mBuffer)
- _UnpinBuffer(mBuffer, mAllocatedSize);
- }
-
- virtual void PerformTransfer()
- {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPinnedTextureBuffer);
- glBindTexture(GL_TEXTURE_2D, mTexId);
- // NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDesc.width, mDesc.height, mDesc.format, mDesc.type, NULL);
- // wait for the trasnfer to complete
- GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 40 * 1000 * 1000); // timeout in nanosec
- glDeleteSync(fence);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- }
-private:
- // intermediate texture to receive the buffer
- GLuint mPinnedTextureBuffer;
- // target texture to receive the image
- GLuint mTexId;
- // buffer
- void *mBuffer;
- // the allocated size
- uint32_t mAllocatedSize;
- // characteristic of the image
- TextureDesc mDesc;
-};
-
-bool TextureTransfer::_PinBuffer(void *address, uint32_t size)
-{
-#ifdef WIN32
- return VirtualLock(address, size);
-#elif defined(_POSIX_MEMLOCK_RANGE)
- return !mlock(address, size);
-#endif
-}
-
-void TextureTransfer::_UnpinBuffer(void* address, uint32_t size)
-{
-#ifdef WIN32
- VirtualUnlock(address, size);
-#elif defined(_POSIX_MEMLOCK_RANGE)
- munlock(address, size);
-#endif
-}
-
-
-
-////////////////////////////////////////////
-// PinnedMemoryAllocator
-////////////////////////////////////////////
-
-
-// static members
-bool PinnedMemoryAllocator::mGPUDirectInitialized = false;
-bool PinnedMemoryAllocator::mHasDvp = false;
-bool PinnedMemoryAllocator::mHasAMDPinnedMemory = false;
-size_t PinnedMemoryAllocator::mReservedProcessMemory = 0;
-
-bool PinnedMemoryAllocator::ReserveMemory(size_t size)
-{
-#ifdef WIN32
- // Increase the process working set size to allow pinning of memory.
- if (size <= mReservedProcessMemory)
- return true;
- SIZE_T dwMin = 0, dwMax = 0;
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA, FALSE, GetCurrentProcessId());
- if (!hProcess)
- return false;
-
- // Retrieve the working set size of the process.
- if (!dwMin && !GetProcessWorkingSetSize(hProcess, &dwMin, &dwMax))
- return false;
-
- BOOL res = SetProcessWorkingSetSize(hProcess, (size - mReservedProcessMemory) + dwMin, (size - mReservedProcessMemory) + dwMax);
- if (!res)
- return false;
- mReservedProcessMemory = size;
- CloseHandle(hProcess);
- return true;
-#else
- struct rlimit rlim;
- if (getrlimit(RLIMIT_MEMLOCK, &rlim) == 0) {
- if (rlim.rlim_cur < size) {
- if (rlim.rlim_max < size)
- rlim.rlim_max = size;
- rlim.rlim_cur = size;
- return !setrlimit(RLIMIT_MEMLOCK, &rlim);
- }
- }
- return false;
-#endif
-}
-
-PinnedMemoryAllocator::PinnedMemoryAllocator(unsigned cacheSize, size_t memSize) :
-mRefCount(1U),
-#ifdef WIN32
-mDvpCaptureTextureHandle(0),
-#endif
-mTexId(0),
-mBufferCacheSize(cacheSize)
-{
- pthread_mutex_init(&mMutex, NULL);
- // do it once
- if (!mGPUDirectInitialized) {
-#ifdef WIN32
- // In windows, AMD_pinned_memory option is not available,
- // we must use special DVP API only available for Quadro cards
- const char* renderer = (const char *)glGetString(GL_RENDERER);
- mHasDvp = (strstr(renderer, "Quadro") != NULL);
-
- if (mHasDvp) {
- // In case the DLL is not in place, don't fail, just fallback on OpenGL
- if (dvpInitGLContext(DVP_DEVICE_FLAGS_SHARE_APP_CONTEXT) != DVP_STATUS_OK) {
- printf("Warning: Could not initialize DVP context, fallback on OpenGL transfer.\nInstall dvp.dll to take advantage of nVidia GPUDirect.\n");
- mHasDvp = false;
- }
- }
-#endif
- if (GLEW_AMD_pinned_memory)
- mHasAMDPinnedMemory = true;
-
- mGPUDirectInitialized = true;
- }
- if (mHasDvp || mHasAMDPinnedMemory) {
- ReserveMemory(memSize);
- }
-}
-
-PinnedMemoryAllocator::~PinnedMemoryAllocator()
-{
- void *address;
- // first clean the cache if not already done
- while (!mBufferCache.empty()) {
- address = mBufferCache.back();
- mBufferCache.pop_back();
- _ReleaseBuffer(address);
- }
- // clean preallocated buffers
- while (!mAllocatedSize.empty()) {
- address = mAllocatedSize.begin()->first;
- _ReleaseBuffer(address);
- }
-
-#ifdef WIN32
- if (mDvpCaptureTextureHandle)
- dvpDestroyBuffer(mDvpCaptureTextureHandle);
-#endif
-}
-
-void PinnedMemoryAllocator::TransferBuffer(void* address, TextureDesc* texDesc, GLuint texId)
-{
- uint32_t allocatedSize = 0;
- TextureTransfer *pTransfer = NULL;
-
- Lock();
- if (mAllocatedSize.count(address) > 0)
- allocatedSize = mAllocatedSize[address];
- Unlock();
- if (!allocatedSize)
- // internal error!!
- return;
- if (mTexId != texId)
- {
- // first time we try to send data to the GPU, allocate a buffer for the texture
- glBindTexture(GL_TEXTURE_2D, texId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_2D, 0, texDesc->internalFormat, texDesc->width, texDesc->height, 0, texDesc->format, texDesc->type, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
- mTexId = texId;
- }
-#ifdef WIN32
- if (mHasDvp)
- {
- if (!mDvpCaptureTextureHandle)
- {
- // bind DVP to the OGL texture
- DVP_CHECK(dvpCreateGPUTextureGL(texId, &mDvpCaptureTextureHandle));
- }
- }
-#endif
- Lock();
- if (mPinnedBuffer.count(address) > 0)
- {
- pTransfer = mPinnedBuffer[address];
- }
- Unlock();
- if (!pTransfer)
- {
-#ifdef WIN32
- if (mHasDvp)
- pTransfer = new TextureTransferDvp(mDvpCaptureTextureHandle, texDesc, address, allocatedSize);
- else
-#endif
- if (mHasAMDPinnedMemory) {
- pTransfer = new TextureTransferPMD(texId, texDesc, address, allocatedSize);
- }
- else {
- pTransfer = new TextureTransferOGL(texId, texDesc, address);
- }
- if (pTransfer)
- {
- Lock();
- mPinnedBuffer[address] = pTransfer;
- Unlock();
- }
- }
- if (pTransfer)
- pTransfer->PerformTransfer();
-}
-
-// IUnknown methods
-HRESULT STDMETHODCALLTYPE PinnedMemoryAllocator::QueryInterface(REFIID /*iid*/, LPVOID* /*ppv*/)
-{
- return E_NOTIMPL;
-}
-
-ULONG STDMETHODCALLTYPE PinnedMemoryAllocator::AddRef(void)
-{
- return atomic_add_and_fetch_uint32(&mRefCount, 1U);
-}
-
-ULONG STDMETHODCALLTYPE PinnedMemoryAllocator::Release(void)
-{
- uint32_t newCount = atomic_sub_and_fetch_uint32(&mRefCount, 1U);
- if (newCount == 0)
- delete this;
- return (ULONG)newCount;
-}
-
-// IDeckLinkMemoryAllocator methods
-HRESULT STDMETHODCALLTYPE PinnedMemoryAllocator::AllocateBuffer(dl_size_t bufferSize, void* *allocatedBuffer)
-{
- Lock();
- if (mBufferCache.empty())
- {
- // Allocate memory on a page boundary
- // Note: aligned alloc exist in Blender but only for small alignment, use direct allocation then.
- // Note: the DeckLink API tries to allocate up to 65 buffer in advance, we will limit this to 3
- // because we don't need any caching
- if (mAllocatedSize.size() >= mBufferCacheSize)
- *allocatedBuffer = NULL;
- else {
-#ifdef WIN32
- *allocatedBuffer = VirtualAlloc(NULL, bufferSize, MEM_COMMIT | MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
-#else
- if (posix_memalign(allocatedBuffer, 4096, bufferSize) != 0)
- *allocatedBuffer = NULL;
-#endif
- mAllocatedSize[*allocatedBuffer] = bufferSize;
- }
- }
- else {
- // Re-use most recently ReleaseBuffer'd address
- *allocatedBuffer = mBufferCache.back();
- mBufferCache.pop_back();
- }
- Unlock();
- return (*allocatedBuffer) ? S_OK : E_OUTOFMEMORY;
-}
-
-HRESULT STDMETHODCALLTYPE PinnedMemoryAllocator::ReleaseBuffer(void* buffer)
-{
- HRESULT result = S_OK;
- Lock();
- if (mBufferCache.size() < mBufferCacheSize) {
- mBufferCache.push_back(buffer);
- }
- else {
- result = _ReleaseBuffer(buffer);
- }
- Unlock();
- return result;
-}
-
-
-HRESULT PinnedMemoryAllocator::_ReleaseBuffer(void* buffer)
-{
- TextureTransfer *pTransfer;
- if (mAllocatedSize.count(buffer) == 0) {
- // Internal error!!
- return S_OK;
- }
- else {
- // No room left in cache, so un-pin (if it was pinned) and free this buffer
- if (mPinnedBuffer.count(buffer) > 0) {
- pTransfer = mPinnedBuffer[buffer];
- mPinnedBuffer.erase(buffer);
- delete pTransfer;
- }
-#ifdef WIN32
- VirtualFree(buffer, 0, MEM_RELEASE);
-#else
- free(buffer);
-#endif
- mAllocatedSize.erase(buffer);
- }
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE PinnedMemoryAllocator::Commit()
-{
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE PinnedMemoryAllocator::Decommit()
-{
- void *buffer;
- Lock();
- while (!mBufferCache.empty()) {
- // Cleanup any frames allocated and pinned in AllocateBuffer() but not freed in ReleaseBuffer()
- buffer = mBufferCache.back();
- mBufferCache.pop_back();
- _ReleaseBuffer(buffer);
- }
- Unlock();
- return S_OK;
-}
-
-
-////////////////////////////////////////////
-// Capture Delegate Class
-////////////////////////////////////////////
-
-CaptureDelegate::CaptureDelegate(VideoDeckLink* pOwner) : mpOwner(pOwner)
-{
-}
-
-HRESULT CaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* inputFrame, IDeckLinkAudioInputPacket* /*audioPacket*/)
-{
- if (!inputFrame) {
- // It's possible to receive a NULL inputFrame, but a valid audioPacket. Ignore audio-only frame.
- return S_OK;
- }
- if ((inputFrame->GetFlags() & bmdFrameHasNoInputSource) == bmdFrameHasNoInputSource) {
- // let's not bother transferring frames if there is no source
- return S_OK;
- }
- mpOwner->VideoFrameArrived(inputFrame);
- return S_OK;
-}
-
-HRESULT CaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode *newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags)
-{
- return S_OK;
-}
-
-
-
-
-// macro for exception handling and logging
-#define CATCH_EXCP catch (Exception & exp) \
-{ exp.report(); m_status = SourceError; }
-
-// class VideoDeckLink
-
-
-// constructor
-VideoDeckLink::VideoDeckLink (HRESULT * hRslt) : VideoBase(),
-mDLInput(NULL),
-mUse3D(false),
-mFrameWidth(0),
-mFrameHeight(0),
-mpAllocator(NULL),
-mpCaptureDelegate(NULL),
-mpCacheFrame(NULL),
-mClosing(false)
-{
- mDisplayMode = (BMDDisplayMode)0;
- mPixelFormat = (BMDPixelFormat)0;
- pthread_mutex_init(&mCacheMutex, NULL);
-}
-
-// destructor
-VideoDeckLink::~VideoDeckLink ()
-{
- LockCache();
- mClosing = true;
- if (mpCacheFrame)
- {
- mpCacheFrame->Release();
- mpCacheFrame = NULL;
- }
- UnlockCache();
- if (mDLInput != NULL)
- {
- // Cleanup for Capture
- mDLInput->StopStreams();
- mDLInput->SetCallback(NULL);
- mDLInput->DisableVideoInput();
- mDLInput->DisableAudioInput();
- mDLInput->FlushStreams();
- if (mDLInput->Release() != 0) {
- printf("Reference count not NULL on DeckLink device when closing it, please report!\n");
- }
- mDLInput = NULL;
- }
-
- if (mpAllocator)
- {
- // if the device was properly cleared, this should be 0
- if (mpAllocator->Release() != 0) {
- printf("Reference count not NULL on Allocator when closing it, please report!\n");
- }
- mpAllocator = NULL;
- }
- if (mpCaptureDelegate)
- {
- delete mpCaptureDelegate;
- mpCaptureDelegate = NULL;
- }
-}
-
-void VideoDeckLink::refresh(void)
-{
- m_avail = false;
-}
-
-// release components
-bool VideoDeckLink::release()
-{
- // release
- return true;
-}
-
-// open video file
-void VideoDeckLink::openFile (char *filename)
-{
- // only live capture on this device
- THRWEXCP(SourceVideoOnlyCapture, S_OK);
-}
-
-
-// open video capture device
-void VideoDeckLink::openCam (char *format, short camIdx)
-{
- IDeckLinkDisplayModeIterator* pDLDisplayModeIterator;
- BMDDisplayModeSupport modeSupport;
- IDeckLinkDisplayMode* pDLDisplayMode;
- IDeckLinkIterator* pIterator;
- BMDTimeValue frameDuration;
- BMDTimeScale frameTimescale;
- IDeckLink* pDL;
- uint32_t displayFlags, inputFlags;
- char *pPixel, *p3D, *pEnd, *pSize;
- size_t len;
- int i, modeIdx, cacheSize;
-
- // format is constructed as <displayMode>/<pixelFormat>[/3D][:<cacheSize>]
- // <displayMode> takes the form of BMDDisplayMode identifier minus the 'bmdMode' prefix.
- // This implementation understands all the modes defined in SDK 10.3.1 but you can alternatively
- // use the 4 characters internal representation of the mode (e.g. 'HD1080p24' == '24ps')
- // <pixelFormat> takes the form of BMDPixelFormat identifier minus the 'bmdFormat' prefix.
- // This implementation understand all the formats defined in SDK 10.32.1 but you can alternatively
- // use the 4 characters internal representation of the format (e.g. '10BitRGB' == 'r210')
- // Not all combinations of mode and pixel format are possible and it also depends on the card!
- // Use /3D postfix if you are capturing a 3D stream with frame packing
- // Example: To capture FullHD 1920x1080@24Hz with 3D packing and 4:4:4 10 bits RGB pixel format, use
- // "HD1080p24/10BitRGB/3D" (same as "24ps/r210/3D")
- // (this will be the normal capture format for FullHD on the DeckLink 4k extreme)
-
- if ((pSize = strchr(format, ':')) != NULL) {
- cacheSize = strtol(pSize+1, &pEnd, 10);
- }
- else {
- cacheSize = 8;
- pSize = format + strlen(format);
- }
- if ((pPixel = strchr(format, '/')) == NULL ||
- ((p3D = strchr(pPixel + 1, '/')) != NULL && strncmp(p3D, "/3D", pSize-p3D)))
- THRWEXCP(VideoDeckLinkBadFormat, S_OK);
- mUse3D = (p3D) ? true : false;
- // to simplify pixel format parsing
- if (!p3D)
- p3D = pSize;
-
- // read the mode
- len = (size_t)(pPixel - format);
- // accept integer display mode
-
- try {
- // throws if bad mode
- decklink_ReadDisplayMode(format, len, &mDisplayMode);
- // found a valid mode, remember that we do not look for an index
- modeIdx = -1;
- }
- catch (Exception &) {
- // accept also purely numerical mode as a mode index
- modeIdx = strtol(format, &pEnd, 10);
- if (pEnd != pPixel || modeIdx < 0)
- // not a pure number, give up
- throw;
- }
-
- // skip /
- pPixel++;
- len = (size_t)(p3D - pPixel);
- // throws if bad format
- decklink_ReadPixelFormat(pPixel, len, &mPixelFormat);
-
- // Caution: DeckLink API used from this point, make sure entity are released before throwing
- // open the card
- pIterator = BMD_CreateDeckLinkIterator();
- if (pIterator) {
- i = 0;
- while (pIterator->Next(&pDL) == S_OK) {
- if (i == camIdx) {
- if (pDL->QueryInterface(IID_IDeckLinkInput, (void**)&mDLInput) != S_OK)
- mDLInput = NULL;
- pDL->Release();
- break;
- }
- i++;
- pDL->Release();
- }
- pIterator->Release();
- }
- if (!mDLInput)
- THRWEXCP(VideoDeckLinkOpenCard, S_OK);
-
-
- // check if display mode and pixel format are supported
- if (mDLInput->GetDisplayModeIterator(&pDLDisplayModeIterator) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
-
- pDLDisplayMode = NULL;
- displayFlags = (mUse3D) ? bmdDisplayModeSupports3D : 0;
- inputFlags = (mUse3D) ? bmdVideoInputDualStream3D : bmdVideoInputFlagDefault;
- while (pDLDisplayModeIterator->Next(&pDLDisplayMode) == S_OK)
- {
- if (modeIdx == 0 || pDLDisplayMode->GetDisplayMode() == mDisplayMode) {
- // in case we get here because of modeIdx, make sure we have mDisplayMode set
- mDisplayMode = pDLDisplayMode->GetDisplayMode();
- if ((pDLDisplayMode->GetFlags() & displayFlags) == displayFlags &&
- mDLInput->DoesSupportVideoMode(mDisplayMode, mPixelFormat, inputFlags, &modeSupport, NULL) == S_OK &&
- modeSupport == bmdDisplayModeSupported)
- {
- break;
- }
- }
- pDLDisplayMode->Release();
- pDLDisplayMode = NULL;
- if (modeIdx-- == 0) {
- // reached the correct mode index but it does not meet the pixel format, give up
- break;
- }
- }
- pDLDisplayModeIterator->Release();
-
- if (pDLDisplayMode == NULL)
- THRWEXCP(VideoDeckLinkBadFormat, S_OK);
-
- mFrameWidth = pDLDisplayMode->GetWidth();
- mFrameHeight = pDLDisplayMode->GetHeight();
- mTextureDesc.height = (mUse3D) ? 2 * mFrameHeight : mFrameHeight;
- pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale);
- pDLDisplayMode->Release();
- // for information, in case the application wants to know
- m_size[0] = mFrameWidth;
- m_size[1] = mTextureDesc.height;
- m_frameRate = (float)frameTimescale / (float)frameDuration;
-
- switch (mPixelFormat)
- {
- case bmdFormat8BitYUV:
- // 2 pixels per word
- mTextureDesc.stride = mFrameWidth * 2;
- mTextureDesc.width = mFrameWidth / 2;
- mTextureDesc.internalFormat = GL_RGBA;
- mTextureDesc.format = GL_BGRA;
- mTextureDesc.type = GL_UNSIGNED_BYTE;
- break;
- case bmdFormat10BitYUV:
- // 6 pixels in 4 words, rounded to 48 pixels
- mTextureDesc.stride = ((mFrameWidth + 47) / 48) * 128;
- mTextureDesc.width = mTextureDesc.stride/4;
- mTextureDesc.internalFormat = GL_RGB10_A2;
- mTextureDesc.format = GL_BGRA;
- mTextureDesc.type = GL_UNSIGNED_INT_2_10_10_10_REV;
- break;
- case bmdFormat8BitARGB:
- mTextureDesc.stride = mFrameWidth * 4;
- mTextureDesc.width = mFrameWidth;
- mTextureDesc.internalFormat = GL_RGBA;
- mTextureDesc.format = GL_BGRA;
- mTextureDesc.type = GL_UNSIGNED_INT_8_8_8_8;
- break;
- case bmdFormat8BitBGRA:
- mTextureDesc.stride = mFrameWidth * 4;
- mTextureDesc.width = mFrameWidth;
- mTextureDesc.internalFormat = GL_RGBA;
- mTextureDesc.format = GL_BGRA;
- mTextureDesc.type = GL_UNSIGNED_BYTE;
- break;
- case bmdFormat10BitRGBXLE:
- // 1 pixel per word, rounded to 64 pixels
- mTextureDesc.stride = ((mFrameWidth + 63) / 64) * 256;
- mTextureDesc.width = mTextureDesc.stride/4;
- mTextureDesc.internalFormat = GL_RGB10_A2;
- mTextureDesc.format = GL_RGBA;
- mTextureDesc.type = GL_UNSIGNED_INT_10_10_10_2;
- break;
- case bmdFormat10BitRGBX:
- case bmdFormat10BitRGB:
- // 1 pixel per word, rounded to 64 pixels
- mTextureDesc.stride = ((mFrameWidth + 63) / 64) * 256;
- mTextureDesc.width = mTextureDesc.stride/4;
- mTextureDesc.internalFormat = GL_R32UI;
- mTextureDesc.format = GL_RED_INTEGER;
- mTextureDesc.type = GL_UNSIGNED_INT;
- break;
- case bmdFormat12BitRGB:
- case bmdFormat12BitRGBLE:
- // 8 pixels in 9 word
- mTextureDesc.stride = (mFrameWidth * 36) / 8;
- mTextureDesc.width = mTextureDesc.stride/4;
- mTextureDesc.internalFormat = GL_R32UI;
- mTextureDesc.format = GL_RED_INTEGER;
- mTextureDesc.type = GL_UNSIGNED_INT;
- break;
- default:
- // for unknown pixel format, this will be resolved when a frame arrives
- mTextureDesc.format = GL_RED_INTEGER;
- mTextureDesc.type = GL_UNSIGNED_INT;
- break;
- }
- // reserve memory for cache frame + 1 to accomodate for pixel format that we don't know yet
- // note: we can't use stride as it is not yet known if the pixel format is unknown
- // use instead the frame width as in worst case it's not much different (e.g. HD720/10BITYUV: 1296 pixels versus 1280)
- // note: some pixel format take more than 4 bytes take that into account (9/8 versus 1)
- mpAllocator = new PinnedMemoryAllocator(cacheSize, mFrameWidth*mTextureDesc.height * 4 * (1+cacheSize*9/8));
-
- if (mDLInput->SetVideoInputFrameMemoryAllocator(mpAllocator) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
-
- mpCaptureDelegate = new CaptureDelegate(this);
- if (mDLInput->SetCallback(mpCaptureDelegate) != S_OK)
- THRWEXCP(DeckLinkInternalError, S_OK);
-
- if (mDLInput->EnableVideoInput(mDisplayMode, mPixelFormat, ((mUse3D) ? bmdVideoInputDualStream3D : bmdVideoInputFlagDefault)) != S_OK)
- // this shouldn't failed, we tested above
- THRWEXCP(DeckLinkInternalError, S_OK);
-
- // just in case it is needed to capture from certain cards, we don't check error because we don't need audio
- mDLInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);
-
- // open base class
- VideoBase::openCam(format, camIdx);
-
- // ready to capture, will start when application calls play()
-}
-
-// play video
-bool VideoDeckLink::play (void)
-{
- try
- {
- // if object is able to play
- if (VideoBase::play())
- {
- mDLInput->FlushStreams();
- return (mDLInput->StartStreams() == S_OK);
- }
- }
- CATCH_EXCP;
- return false;
-}
-
-
-// pause video
-bool VideoDeckLink::pause (void)
-{
- try
- {
- if (VideoBase::pause())
- {
- mDLInput->PauseStreams();
- return true;
- }
- }
- CATCH_EXCP;
- return false;
-}
-
-// stop video
-bool VideoDeckLink::stop (void)
-{
- try
- {
- VideoBase::stop();
- mDLInput->StopStreams();
- return true;
- }
- CATCH_EXCP;
- return false;
-}
-
-
-// set video range
-void VideoDeckLink::setRange (double start, double stop)
-{
-}
-
-// set framerate
-void VideoDeckLink::setFrameRate (float rate)
-{
-}
-
-
-// image calculation
-// send cache frame directly to GPU
-void VideoDeckLink::calcImage (unsigned int texId, double ts)
-{
- IDeckLinkVideoInputFrame* pFrame;
- LockCache();
- pFrame = mpCacheFrame;
- mpCacheFrame = NULL;
- UnlockCache();
- if (pFrame) {
- // BUG: the dvpBindToGLCtx function fails the first time it is used, don't know why.
- // This causes an exception to be thrown.
- // This should be fixed but in the meantime we will catch the exception because
- // it is crucial that we release the frame to keep the reference count right on the DeckLink device
- try {
- uint32_t rowSize = pFrame->GetRowBytes();
- uint32_t textureSize = rowSize * pFrame->GetHeight();
- void* videoPixels = NULL;
- void* rightEyePixels = NULL;
- if (!mTextureDesc.stride) {
- // we could not compute the texture size earlier (unknown pixel size)
- // let's do it now
- mTextureDesc.stride = rowSize;
- mTextureDesc.width = mTextureDesc.stride / 4;
- }
- if (mTextureDesc.stride != rowSize) {
- // unexpected frame size, ignore
- // TBD: print a warning
- }
- else {
- pFrame->GetBytes(&videoPixels);
- if (mUse3D) {
- IDeckLinkVideoFrame3DExtensions *if3DExtensions = NULL;
- IDeckLinkVideoFrame *rightEyeFrame = NULL;
- if (pFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **)&if3DExtensions) == S_OK &&
- if3DExtensions->GetFrameForRightEye(&rightEyeFrame) == S_OK) {
- rightEyeFrame->GetBytes(&rightEyePixels);
- textureSize += ((uint64_t)rightEyePixels - (uint64_t)videoPixels);
- }
- if (rightEyeFrame)
- rightEyeFrame->Release();
- if (if3DExtensions)
- if3DExtensions->Release();
- }
- mTextureDesc.size = mTextureDesc.width * mTextureDesc.height * 4;
- if (mTextureDesc.size == textureSize) {
- // this means that both left and right frame are contiguous and that there is no padding
- // do the transfer
- mpAllocator->TransferBuffer(videoPixels, &mTextureDesc, texId);
- }
- }
- }
- catch (Exception &) {
- pFrame->Release();
- throw;
- }
- // this will trigger PinnedMemoryAllocator::RealaseBuffer
- pFrame->Release();
- }
- // currently we don't pass the image to the application
- m_avail = false;
-}
-
-// A frame is available from the board
-// Called from an internal thread, just pass the frame to the main thread
-void VideoDeckLink::VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame)
-{
- IDeckLinkVideoInputFrame* pOldFrame = NULL;
- LockCache();
- if (!mClosing)
- {
- pOldFrame = mpCacheFrame;
- mpCacheFrame = inputFrame;
- inputFrame->AddRef();
- }
- UnlockCache();
- // old frame no longer needed, just release it
- if (pOldFrame)
- pOldFrame->Release();
-}
-
-// python methods
-
-// object initialization
-static int VideoDeckLink_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- static const char *kwlist[] = { "format", "capture", NULL };
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
- // see openCam for a description of format
- char * format = NULL;
- // capture device number, i.e. DeckLink card number, default first one
- short capt = 0;
-
- if (!GLEW_VERSION_1_5) {
- PyErr_SetString(PyExc_RuntimeError, "VideoDeckLink requires at least OpenGL 1.5");
- return -1;
- }
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|h",
- const_cast<char**>(kwlist), &format, &capt))
- return -1;
-
- try {
- // create video object
- Video_init<VideoDeckLink>(self);
-
- // open video source, control comes back to VideoDeckLink::openCam
- Video_open(getVideo(self), format, capt);
- }
- catch (Exception & exp) {
- exp.report();
- return -1;
- }
- // initialization succeded
- return 0;
-}
-
-// methods structure
-static PyMethodDef videoMethods[] =
-{ // methods from VideoBase class
- {"play", (PyCFunction)Video_play, METH_NOARGS, "Play (restart) video"},
- {"pause", (PyCFunction)Video_pause, METH_NOARGS, "pause video"},
- {"stop", (PyCFunction)Video_stop, METH_NOARGS, "stop video (play will replay it from start)"},
- {"refresh", (PyCFunction)Video_refresh, METH_VARARGS, "Refresh video - get its status"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef videoGetSets[] =
-{ // methods from VideoBase class
- {(char*)"status", (getter)Video_getStatus, NULL, (char*)"video status", NULL},
- {(char*)"framerate", (getter)Video_getFrameRate, NULL, (char*)"frame rate", NULL},
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", 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}
-};
-
-// python type declaration
-PyTypeObject VideoDeckLinkType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.VideoDeckLink", /*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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "DeckLink 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)VideoDeckLink_init, /* tp_init */
- 0, /* tp_alloc */
- Image_allocNew, /* tp_new */
-};
-
-
-
-////////////////////////////////////////////
-// DeckLink Capture Delegate Class
-////////////////////////////////////////////
-
-#endif // WITH_GAMEENGINE_DECKLINK
-
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.h b/source/gameengine/VideoTexture/VideoDeckLink.h
deleted file mode 100644
index d5419176691..00000000000
--- a/source/gameengine/VideoTexture/VideoDeckLink.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2015, Blender Foundation
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Blender Foundation.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoDeckLink.h
- * \ingroup bgevideotex
- */
-
-#ifndef __VIDEODECKLINK_H__
-#define __VIDEODECKLINK_H__
-
-#ifdef WITH_GAMEENGINE_DECKLINK
-
-/* this needs to be parsed with __cplusplus defined before included through DeckLink_compat.h */
-#if defined(__FreeBSD__)
-# include <inttypes.h>
-#endif
-#include <map>
-#include <set>
-
-extern "C" {
-#include <pthread.h>
-#include "DNA_listBase.h"
-#include "BLI_threads.h"
-#include "BLI_blenlib.h"
-}
-#include "GPU_glew.h"
-#ifdef WIN32
-#include "dvpapi.h"
-#endif
-#include "DeckLinkAPI.h"
-#include "VideoBase.h"
-
-class PinnedMemoryAllocator;
-
-struct TextureDesc
-{
- uint32_t width;
- uint32_t height;
- uint32_t stride;
- uint32_t size;
- GLenum internalFormat;
- GLenum format;
- GLenum type;
- TextureDesc()
- {
- width = 0;
- height = 0;
- stride = 0;
- size = 0;
- internalFormat = 0;
- format = 0;
- type = 0;
- }
-};
-
-class CaptureDelegate;
-
-// type VideoDeckLink declaration
-class VideoDeckLink : public VideoBase
-{
- friend class CaptureDelegate;
-public:
- /// constructor
- VideoDeckLink (HRESULT * hRslt);
- /// destructor
- virtual ~VideoDeckLink ();
-
- /// open video/image file
- virtual void openFile(char *file);
- /// open video capture device
- virtual void openCam(char *driver, short camIdx);
-
- /// release video source
- virtual bool release (void);
- /// overwrite base refresh to handle fixed image
- virtual void refresh(void);
- /// play video
- virtual bool play (void);
- /// pause video
- virtual bool pause (void);
- /// stop video
- virtual bool stop (void);
- /// set play range
- virtual void setRange (double start, double stop);
- /// set frame rate
- virtual void setFrameRate (float rate);
-
-protected:
- // format and codec information
- /// image calculation
- virtual void calcImage (unsigned int texId, double ts);
-
-private:
- void VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame);
- void LockCache()
- {
- pthread_mutex_lock(&mCacheMutex);
- }
- void UnlockCache()
- {
- pthread_mutex_unlock(&mCacheMutex);
- }
-
- IDeckLinkInput* mDLInput;
- BMDDisplayMode mDisplayMode;
- BMDPixelFormat mPixelFormat;
- bool mUse3D;
- uint32_t mFrameWidth;
- uint32_t mFrameHeight;
- TextureDesc mTextureDesc;
- PinnedMemoryAllocator* mpAllocator;
- CaptureDelegate* mpCaptureDelegate;
-
- // cache frame in transit between the callback thread and the main BGE thread
- // keep only one frame in cache because we just want to keep up with real time
- pthread_mutex_t mCacheMutex;
- IDeckLinkVideoInputFrame* mpCacheFrame;
- bool mClosing;
-
-};
-
-inline VideoDeckLink *getDeckLink(PyImage *self)
-{
- return static_cast<VideoDeckLink*>(self->m_image);
-}
-
-////////////////////////////////////////////
-// TextureTransfer : Abstract class to perform a transfer to GPU memory using fast transfer if available
-////////////////////////////////////////////
-class TextureTransfer
-{
-public:
- TextureTransfer() {}
- virtual ~TextureTransfer() { }
-
- virtual void PerformTransfer() = 0;
-protected:
- static bool _PinBuffer(void *address, uint32_t size);
- static void _UnpinBuffer(void* address, uint32_t size);
-};
-
-////////////////////////////////////////////
-// PinnedMemoryAllocator
-////////////////////////////////////////////
-
-// PinnedMemoryAllocator implements the IDeckLinkMemoryAllocator interface and can be used instead of the
-// built-in frame allocator, by setting with SetVideoInputFrameMemoryAllocator() or SetVideoOutputFrameMemoryAllocator().
-//
-// For this sample application a custom frame memory allocator is used to ensure each address
-// of frame memory is aligned on a 4kB boundary required by the OpenGL pinned memory extension.
-// If the pinned memory extension is not available, this allocator will still be used and
-// demonstrates how to cache frame allocations for efficiency.
-//
-// The frame cache delays the releasing of buffers until the cache fills up, thereby avoiding an
-// allocate plus pin operation for every frame, followed by an unpin and deallocate on every frame.
-
-
-class PinnedMemoryAllocator : public IDeckLinkMemoryAllocator
-{
-public:
- PinnedMemoryAllocator(unsigned cacheSize, size_t memSize);
- virtual ~PinnedMemoryAllocator();
-
- void TransferBuffer(void* address, TextureDesc* texDesc, GLuint texId);
-
- // IUnknown methods
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv);
- virtual ULONG STDMETHODCALLTYPE AddRef(void);
- virtual ULONG STDMETHODCALLTYPE Release(void);
-
- // IDeckLinkMemoryAllocator methods
- virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(dl_size_t bufferSize, void* *allocatedBuffer);
- virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer(void* buffer);
- virtual HRESULT STDMETHODCALLTYPE Commit();
- virtual HRESULT STDMETHODCALLTYPE Decommit();
-
-private:
- static bool mGPUDirectInitialized;
- static bool mHasDvp;
- static bool mHasAMDPinnedMemory;
- static size_t mReservedProcessMemory;
- static bool ReserveMemory(size_t size);
-
- void Lock()
- {
- pthread_mutex_lock(&mMutex);
- }
- void Unlock()
- {
- pthread_mutex_unlock(&mMutex);
- }
- HRESULT _ReleaseBuffer(void* buffer);
-
- uint32_t mRefCount;
- // protect the cache and the allocated map,
- // not the pinnedBuffer map as it is only used from main thread
- pthread_mutex_t mMutex;
- std::map<void*, uint32_t> mAllocatedSize;
- std::vector<void*> mBufferCache;
- std::map<void *, TextureTransfer*> mPinnedBuffer;
-#ifdef WIN32
- DVPBufferHandle mDvpCaptureTextureHandle;
-#endif
- // target texture in GPU
- GLuint mTexId;
- uint32_t mBufferCacheSize;
-};
-
-////////////////////////////////////////////
-// Capture Delegate Class
-////////////////////////////////////////////
-
-class CaptureDelegate : public IDeckLinkInputCallback
-{
- VideoDeckLink* mpOwner;
-
-public:
- CaptureDelegate(VideoDeckLink* pOwner);
-
- // IUnknown needs only a dummy implementation
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
- virtual ULONG STDMETHODCALLTYPE AddRef() { return 1; }
- virtual ULONG STDMETHODCALLTYPE Release() { return 1; }
-
- virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioPacket);
- virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode *newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags);
-};
-
-
-#endif /* WITH_GAMEENGINE_DECKLINK */
-
-#endif /* __VIDEODECKLINK_H__ */
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
deleted file mode 100644
index 11ec97ca5f8..00000000000
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/VideoFFmpeg.cpp
- * \ingroup bgevideotex
- */
-
-
-#ifdef WITH_FFMPEG
-
-// INT64_C fix for some linux machines (C99ism)
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#ifdef __STDC_CONSTANT_MACROS /* quiet warning */
-#endif
-#endif
-
-#include <stdint.h>
-
-
-#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-
-#include <string>
-
-#include "VideoFFmpeg.h"
-#include "Exception.h"
-
-
-// default framerate
-const double defFrameRate = 25.0;
-
-// macro for exception handling and logging
-#define CATCH_EXCP catch (Exception & exp) \
-{ exp.report(); m_status = SourceError; }
-
-// class RenderVideo
-
-// constructor
-VideoFFmpeg::VideoFFmpeg (HRESULT * hRslt) : VideoBase(),
-m_codec(NULL), m_formatCtx(NULL), m_codecCtx(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_eof(false), m_externTime(false), m_curPosition(-1), m_startTime(0),
-m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false),
-m_isThreaded(false), m_isStreaming(false), m_stopThread(false), m_cacheStarted(false)
-{
- // 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;
- BLI_listbase_clear(&m_thread);
- pthread_mutex_init(&m_cacheMutex, NULL);
- BLI_listbase_clear(&m_frameCacheFree);
- BLI_listbase_clear(&m_frameCacheBase);
- BLI_listbase_clear(&m_packetCacheFree);
- BLI_listbase_clear(&m_packetCacheBase);
-}
-
-// destructor
-VideoFFmpeg::~VideoFFmpeg ()
-{
-}
-
-void VideoFFmpeg::refresh(void)
-{
- // a fixed image will not refresh because it is loaded only once at creation
- if (m_isImage)
- return;
- m_avail = false;
-}
-
-// release components
-bool VideoFFmpeg::release()
-{
- // release
- stopCache();
- if (m_codecCtx)
- {
- avcodec_close(m_codecCtx);
- m_codecCtx = NULL;
- }
- if (m_formatCtx)
- {
- avformat_close_input(&m_formatCtx);
- m_formatCtx = NULL;
- }
- if (m_frame)
- {
- av_free(m_frame);
- m_frame = NULL;
- }
- if (m_frameDeinterlaced)
- {
- MEM_freeN(m_frameDeinterlaced->data[0]);
- av_free(m_frameDeinterlaced);
- m_frameDeinterlaced = NULL;
- }
- if (m_frameRGB)
- {
- MEM_freeN(m_frameRGB->data[0]);
- av_free(m_frameRGB);
- m_frameRGB = NULL;
- }
- if (m_imgConvertCtx)
- {
- sws_freeContext(m_imgConvertCtx);
- m_imgConvertCtx = NULL;
- }
- m_codec = NULL;
- m_status = SourceStopped;
- m_lastFrame = -1;
- return true;
-}
-
-AVFrame *VideoFFmpeg::allocFrameRGB()
-{
- AVFrame *frame;
- frame = av_frame_alloc();
- if (m_format == RGBA32)
- {
- avpicture_fill((AVPicture*)frame,
- (uint8_t*)MEM_callocN(avpicture_get_size(
- AV_PIX_FMT_RGBA,
- m_codecCtx->width, m_codecCtx->height),
- "ffmpeg rgba"),
- AV_PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
- } else
- {
- avpicture_fill((AVPicture*)frame,
- (uint8_t*)MEM_callocN(avpicture_get_size(
- AV_PIX_FMT_RGB24,
- m_codecCtx->width, m_codecCtx->height),
- "ffmpeg rgb"),
- AV_PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
- }
- return frame;
-}
-
-// set initial parameters
-void VideoFFmpeg::initParams (short width, short height, float rate, bool image)
-{
- m_captWidth = width;
- m_captHeight = height;
- m_captRate = rate;
- m_isImage = image;
-}
-
-
-int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AVDictionary **formatParams)
-{
- AVFormatContext *formatCtx = NULL;
- int i, videoStream;
- AVCodec *codec;
- AVCodecContext *codecCtx;
-
- if (avformat_open_input(&formatCtx, filename, inputFormat, formatParams)!=0)
- return -1;
-
- if (avformat_find_stream_info(formatCtx, NULL) < 0)
- {
- avformat_close_input(&formatCtx);
- return -1;
- }
-
- /* Find the first video stream */
- videoStream=-1;
- for (i=0; i<formatCtx->nb_streams; i++)
- {
- if (formatCtx->streams[i] &&
- get_codec_from_stream(formatCtx->streams[i]) &&
- (get_codec_from_stream(formatCtx->streams[i])->codec_type==AVMEDIA_TYPE_VIDEO))
- {
- videoStream=i;
- break;
- }
- }
-
- if (videoStream==-1)
- {
- avformat_close_input(&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)
- {
- avformat_close_input(&formatCtx);
- return -1;
- }
- codecCtx->workaround_bugs = 1;
- if (avcodec_open2(codecCtx, codec, NULL) < 0)
- {
- avformat_close_input(&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(av_get_r_frame_rate_compat(formatCtx, formatCtx->streams[videoStream]));
-#endif
- if (m_baseFrameRate <= 0.0)
- m_baseFrameRate = defFrameRate;
-
- m_codec = codec;
- m_codecCtx = codecCtx;
- m_formatCtx = formatCtx;
- m_videoStream = videoStream;
- m_frame = av_frame_alloc();
- m_frameDeinterlaced = av_frame_alloc();
-
- // 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);
-
- // check if the pixel format supports Alpha
- if (m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32 ||
- m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32 ||
- m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32_1 ||
- m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32_1)
- {
- // allocate buffer to store final decoded frame
- m_format = RGBA32;
- // allocate sws context
- m_imgConvertCtx = sws_getContext(
- m_codecCtx->width,
- m_codecCtx->height,
- m_codecCtx->pix_fmt,
- m_codecCtx->width,
- m_codecCtx->height,
- AV_PIX_FMT_RGBA,
- SWS_FAST_BILINEAR,
- NULL, NULL, NULL);
- } else
- {
- // allocate buffer to store final decoded frame
- m_format = RGB24;
- // allocate sws context
- m_imgConvertCtx = sws_getContext(
- m_codecCtx->width,
- m_codecCtx->height,
- m_codecCtx->pix_fmt,
- m_codecCtx->width,
- m_codecCtx->height,
- AV_PIX_FMT_RGB24,
- SWS_FAST_BILINEAR,
- NULL, NULL, NULL);
- }
- m_frameRGB = allocFrameRGB();
-
- if (!m_imgConvertCtx) {
- avcodec_close(m_codecCtx);
- m_codecCtx = NULL;
- avformat_close_input(&m_formatCtx);
- m_formatCtx = NULL;
- av_free(m_frame);
- m_frame = NULL;
- MEM_freeN(m_frameDeinterlaced->data[0]);
- av_free(m_frameDeinterlaced);
- m_frameDeinterlaced = NULL;
- MEM_freeN(m_frameRGB->data[0]);
- av_free(m_frameRGB);
- m_frameRGB = NULL;
- return -1;
- }
- return 0;
-}
-
-/*
- * This thread is used to load video frame asynchronously.
- * It provides a frame caching service.
- * The main thread is responsible for positioning the frame pointer in the
- * file correctly before calling startCache() which starts this thread.
- * The cache is organized in two layers: 1) a cache of 20-30 undecoded packets to keep
- * memory and CPU low 2) a cache of 5 decoded frames.
- * If the main thread does not find the frame in the cache (because the video has restarted
- * or because the GE is lagging), it stops the cache with StopCache() (this is a synchronous
- * function: it sends a signal to stop the cache thread and wait for confirmation), then
- * change the position in the stream and restarts the cache thread.
- */
-void *VideoFFmpeg::cacheThread(void *data)
-{
- VideoFFmpeg* video = (VideoFFmpeg*)data;
- // holds the frame that is being decoded
- CacheFrame *currentFrame = NULL;
- CachePacket *cachePacket;
- bool endOfFile = false;
- int frameFinished = 0;
- double timeBase = av_q2d(video->m_formatCtx->streams[video->m_videoStream]->time_base);
- int64_t startTs = video->m_formatCtx->streams[video->m_videoStream]->start_time;
-
- if (startTs == AV_NOPTS_VALUE)
- startTs = 0;
-
- while (!video->m_stopThread)
- {
- // packet cache is used solely by this thread, no need to lock
- // In case the stream/file contains other stream than the one we are looking for,
- // allow a bit of cycling to get rid quickly of those frames
- frameFinished = 0;
- while ( !endOfFile
- && (cachePacket = (CachePacket *)video->m_packetCacheFree.first) != NULL
- && frameFinished < 25)
- {
- // free packet => packet cache is not full yet, just read more
- if (av_read_frame(video->m_formatCtx, &cachePacket->packet)>=0)
- {
- if (cachePacket->packet.stream_index == video->m_videoStream)
- {
- // make sure fresh memory is allocated for the packet and move it to queue
- av_dup_packet(&cachePacket->packet);
- BLI_remlink(&video->m_packetCacheFree, cachePacket);
- BLI_addtail(&video->m_packetCacheBase, cachePacket);
- break;
- } else {
- // this is not a good packet for us, just leave it on free queue
- // Note: here we could handle sound packet
- av_free_packet(&cachePacket->packet);
- frameFinished++;
- }
-
- } else {
- if (video->m_isFile)
- // this mark the end of the file
- endOfFile = true;
- // if we cannot read a packet, no need to continue
- break;
- }
- }
- // frame cache is also used by main thread, lock
- if (currentFrame == NULL)
- {
- // no current frame being decoded, take free one
- pthread_mutex_lock(&video->m_cacheMutex);
- if ((currentFrame = (CacheFrame *)video->m_frameCacheFree.first) != NULL)
- BLI_remlink(&video->m_frameCacheFree, currentFrame);
- pthread_mutex_unlock(&video->m_cacheMutex);
- }
- if (currentFrame != NULL)
- {
- // this frame is out of free and busy queue, we can manipulate it without locking
- frameFinished = 0;
- while (!frameFinished && (cachePacket = (CachePacket *)video->m_packetCacheBase.first) != NULL)
- {
- BLI_remlink(&video->m_packetCacheBase, cachePacket);
- // use m_frame because when caching, it is not used in main thread
- // we can't use currentFrame directly because we need to convert to RGB first
- avcodec_decode_video2(video->m_codecCtx,
- video->m_frame, &frameFinished,
- &cachePacket->packet);
- if (frameFinished)
- {
- AVFrame * input = video->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)
- {
- if (video->m_deinterlace)
- {
- if (avpicture_deinterlace(
- (AVPicture*) video->m_frameDeinterlaced,
- (const AVPicture*) video->m_frame,
- video->m_codecCtx->pix_fmt,
- video->m_codecCtx->width,
- video->m_codecCtx->height) >= 0)
- {
- input = video->m_frameDeinterlaced;
- }
- }
- // convert to RGB24
- sws_scale(video->m_imgConvertCtx,
- input->data,
- input->linesize,
- 0,
- video->m_codecCtx->height,
- currentFrame->frame->data,
- currentFrame->frame->linesize);
- // move frame to queue, this frame is necessarily the next one
- video->m_curPosition = (long)((cachePacket->packet.dts-startTs) * (video->m_baseFrameRate*timeBase) + 0.5);
- currentFrame->framePosition = video->m_curPosition;
- pthread_mutex_lock(&video->m_cacheMutex);
- BLI_addtail(&video->m_frameCacheBase, currentFrame);
- pthread_mutex_unlock(&video->m_cacheMutex);
- currentFrame = NULL;
- }
- }
- av_free_packet(&cachePacket->packet);
- BLI_addtail(&video->m_packetCacheFree, cachePacket);
- }
- if (currentFrame && endOfFile)
- {
- // no more packet and end of file => put a special frame that indicates that
- currentFrame->framePosition = -1;
- pthread_mutex_lock(&video->m_cacheMutex);
- BLI_addtail(&video->m_frameCacheBase, currentFrame);
- pthread_mutex_unlock(&video->m_cacheMutex);
- currentFrame = NULL;
- // no need to stay any longer in this thread
- break;
- }
- }
- // small sleep to avoid unnecessary looping
- PIL_sleep_ms(10);
- }
- // before quitting, put back the current frame to queue to allow freeing
- if (currentFrame)
- {
- pthread_mutex_lock(&video->m_cacheMutex);
- BLI_addtail(&video->m_frameCacheFree, currentFrame);
- pthread_mutex_unlock(&video->m_cacheMutex);
- }
- return 0;
-}
-
-// start thread to cache video frame from file/capture/stream
-// this function should be called only when the position in the stream is set for the
-// first frame to cache
-bool VideoFFmpeg::startCache()
-{
- if (!m_cacheStarted && m_isThreaded)
- {
- m_stopThread = false;
- for (int i=0; i<CACHE_FRAME_SIZE; i++)
- {
- CacheFrame *frame = new CacheFrame();
- frame->frame = allocFrameRGB();
- BLI_addtail(&m_frameCacheFree, frame);
- }
- for (int i=0; i<CACHE_PACKET_SIZE; i++)
- {
- CachePacket *packet = new CachePacket();
- BLI_addtail(&m_packetCacheFree, packet);
- }
- BLI_threadpool_init(&m_thread, cacheThread, 1);
- BLI_threadpool_insert(&m_thread, this);
- m_cacheStarted = true;
- }
- return m_cacheStarted;
-}
-
-void VideoFFmpeg::stopCache()
-{
- if (m_cacheStarted)
- {
- m_stopThread = true;
- BLI_threadpool_end(&m_thread);
- // now delete the cache
- CacheFrame *frame;
- CachePacket *packet;
- while ((frame = (CacheFrame *)m_frameCacheBase.first) != NULL)
- {
- BLI_remlink(&m_frameCacheBase, frame);
- MEM_freeN(frame->frame->data[0]);
- av_free(frame->frame);
- delete frame;
- }
- while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL)
- {
- BLI_remlink(&m_frameCacheFree, frame);
- MEM_freeN(frame->frame->data[0]);
- av_free(frame->frame);
- delete frame;
- }
- while ((packet = (CachePacket *)m_packetCacheBase.first) != NULL)
- {
- BLI_remlink(&m_packetCacheBase, packet);
- av_free_packet(&packet->packet);
- delete packet;
- }
- while ((packet = (CachePacket *)m_packetCacheFree.first) != NULL)
- {
- BLI_remlink(&m_packetCacheFree, packet);
- delete packet;
- }
- m_cacheStarted = false;
- }
-}
-
-void VideoFFmpeg::releaseFrame(AVFrame *frame)
-{
- if (frame == m_frameRGB)
- {
- // this is not a frame from the cache, ignore
- return;
- }
- // this frame MUST be the first one of the queue
- pthread_mutex_lock(&m_cacheMutex);
- CacheFrame *cacheFrame = (CacheFrame *)m_frameCacheBase.first;
- assert (cacheFrame != NULL && cacheFrame->frame == frame);
- BLI_remlink(&m_frameCacheBase, cacheFrame);
- BLI_addtail(&m_frameCacheFree, cacheFrame);
- pthread_mutex_unlock(&m_cacheMutex);
-}
-
-// open video file
-void VideoFFmpeg::openFile (char *filename)
-{
- 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 (
- // ffmpeg reports that http source are actually non stream
- // but it is really not desirable to seek on http file, so force streaming.
- // It would be good to find this information from the context but there are no simple indication
- !strncmp(filename, "http://", 7) ||
- !strncmp(filename, "rtsp://", 7) ||
- (m_formatCtx->pb && !m_formatCtx->pb->seekable)
- )
- {
- // the file is in fact a streaming source, treat as cam to prevent seeking
- m_isFile = false;
- // but it's not handled exactly like a camera.
- m_isStreaming = true;
- // for streaming it is important to do non blocking read
- m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK;
- }
-
- if (m_isImage)
- {
- // the file is to be treated as an image, i.e. load the first frame only
- m_isFile = false;
- // in case of reload, the filename is taken from m_imageName, no need to change it
- if (m_imageName.Ptr() != filename)
- m_imageName = filename;
- m_preseek = 0;
- m_avail = false;
- play();
- }
- // check if we should do multi-threading?
- if (!m_isImage && BLI_system_thread_count() > 1)
- {
- // never thread image: there are no frame to read ahead
- // no need to thread if the system has a single core
- m_isThreaded = true;
- }
-}
-
-
-// open video capture device
-void VideoFFmpeg::openCam (char *file, short camIdx)
-{
- // open camera source
- AVInputFormat *inputFormat;
- AVDictionary *formatParams = NULL;
- char filename[28], rateStr[20];
-
-#ifdef WIN32
- // video capture on windows only through Video For Windows driver
- inputFormat = av_find_input_format("vfwcap");
- if (!inputFormat)
- // Video For Windows not supported??
- return;
- sprintf(filename, "%d", camIdx);
-#else
- // In Linux we support two types of devices: VideoForLinux and DV1394.
- // the user specify it with the filename:
- // [<device_type>][:<standard>]
- // <device_type> : 'v4l' for VideoForLinux, 'dv1394' for DV1394. By default 'v4l'
- // <standard> : 'pal', 'secam' or 'ntsc'. By default 'ntsc'
- // The driver name is constructed automatically from the device type:
- // v4l : /dev/video<camIdx>
- // dv1394: /dev/dv1394/<camIdx>
- // If you have different driver name, you can specify the driver name explicitly
- // instead of device type. Examples of valid filename:
- // /dev/v4l/video0:pal
- // /dev/ieee1394/1:ntsc
- // dv1394:secam
- // v4l:pal
- char *p;
-
- 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
- {
- const char *formats[] = {"video4linux2,v4l2", "video4linux2", "video4linux"};
- int i, formatsCount = sizeof(formats) / sizeof(char*);
- for (i = 0; i < formatsCount; i++) {
- inputFormat = av_find_input_format(formats[i]);
- if (inputFormat)
- break;
- }
- 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) {
- av_dict_set(&formatParams, "standard", p+1, 0);
- }
-#endif
- //frame rate
- if (m_captRate <= 0.f)
- m_captRate = defFrameRate;
- sprintf(rateStr, "%f", m_captRate);
-
- av_dict_set(&formatParams, "framerate", rateStr, 0);
-
- if (m_captWidth > 0 && m_captHeight > 0) {
- char video_size[64];
- BLI_snprintf(video_size, sizeof(video_size), "%dx%d", m_captWidth, m_captHeight);
- av_dict_set(&formatParams, "video_size", video_size, 0);
- }
-
- 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);
- // check if we should do multi-threading?
- if (BLI_system_thread_count() > 1)
- {
- // no need to thread if the system has a single core
- m_isThreaded = true;
- }
-
- av_dict_free(&formatParams);
-}
-
-// play video
-bool VideoFFmpeg::play (void)
-{
- try
- {
- // if object is able to play
- if (VideoBase::play())
- {
- // set video position
- setPositions();
-
- if (m_isStreaming)
- {
- av_read_play(m_formatCtx);
- }
-
- // return success
- return true;
- }
- }
- CATCH_EXCP;
- return false;
-}
-
-
-// pause video
-bool VideoFFmpeg::pause (void)
-{
- try
- {
- if (VideoBase::pause())
- {
- if (m_isStreaming)
- {
- av_read_pause(m_formatCtx);
- }
- return true;
- }
- }
- CATCH_EXCP;
- return false;
-}
-
-// stop video
-bool VideoFFmpeg::stop (void)
-{
- try
- {
- VideoBase::stop();
- // force restart when play
- m_lastFrame = -1;
- return true;
- }
- CATCH_EXCP;
- return false;
-}
-
-
-// set video range
-void VideoFFmpeg::setRange (double start, double stop)
-{
- try
- {
- // set range
- if (m_isFile)
- {
- VideoBase::setRange(start, stop);
- // set range for video
- setPositions();
- }
- }
- CATCH_EXCP;
-}
-
-// set framerate
-void VideoFFmpeg::setFrameRate (float rate)
-{
- VideoBase::setFrameRate(rate);
-}
-
-
-// image calculation
-// load frame from video
-void VideoFFmpeg::calcImage (unsigned int texId, double ts)
-{
- if (m_status == SourcePlaying)
- {
- // get actual time
- double startTime = PIL_check_seconds_timer();
- double actTime;
- // timestamp passed from audio actuators can sometimes be slightly negative
- if (m_isFile && ts >= -0.5)
- {
- // allow setting timestamp only when not streaming
- actTime = ts;
- if (actTime * actFrameRate() < m_lastFrame)
- {
- // user is asking to rewind, force a cache clear to make sure we will do a seek
- // note that this does not decrement m_repeat if ts didn't reach m_range[1]
- stopCache();
- }
- }
- else
- {
- if (m_lastFrame == -1 && !m_isFile)
- m_startTime = startTime;
- actTime = startTime - m_startTime;
- }
- // if video has ended
- if (m_isFile && actTime * m_frameRate >= m_range[1])
- {
- // in any case, this resets the cache
- stopCache();
- // 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;
- return;
- }
- }
- // actual frame
- long actFrame = (m_isImage) ? m_lastFrame+1 : long(actTime * actFrameRate());
- // if actual frame differs from last frame
- if (actFrame != m_lastFrame)
- {
- AVFrame* frame;
- // get image
- if ((frame = grabFrame(actFrame)) != NULL)
- {
- if (!m_isFile && !m_cacheStarted)
- {
- // streaming without cache: detect synchronization problem
- double execTime = PIL_check_seconds_timer() - startTime;
- if (execTime > 0.005)
- {
- // exec time is too long, it means that the function was blocking
- // resynchronize the stream from this time
- m_startTime += execTime;
- }
- }
- // 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]));
- // finished with the frame, release it so that cache can reuse it
- releaseFrame(frame);
- // in case it is an image, automatically stop reading it
- if (m_isImage)
- {
- m_status = SourceStopped;
- // close the file as we don't need it anymore
- release();
- }
- } else if (m_isStreaming)
- {
- // we didn't get a frame and we are streaming, this may be due to
- // a delay in the network or because we are getting the frame too fast.
- // In the later case, shift time by a small amount to compensate for a drift
- m_startTime += 0.001;
- }
- }
- }
-}
-
-
-// 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_eof && m_lastFrame >= 0 && (!m_isFile || m_lastFrame < m_range[1] * actFrameRate()))
- // continue from actual position
- m_startTime -= double(m_lastFrame) / actFrameRate();
- else {
- m_startTime -= m_range[0];
- // start from beginning, stop cache just in case
- stopCache();
- }
-}
-
-// position pointer in file, position in second
-AVFrame *VideoFFmpeg::grabFrame(long position)
-{
- AVPacket packet;
- int frameFinished;
- int posFound = 1;
- bool frameLoaded = false;
- int64_t targetTs = 0;
- CacheFrame *frame;
- int64_t dts = 0;
-
- if (m_cacheStarted)
- {
- // when cache is active, we must not read the file directly
- do {
- pthread_mutex_lock(&m_cacheMutex);
- frame = (CacheFrame *)m_frameCacheBase.first;
- pthread_mutex_unlock(&m_cacheMutex);
- // no need to remove the frame from the queue: the cache thread does not touch the head, only the tail
- if (frame == NULL)
- {
- // no frame in cache, in case of file it is an abnormal situation
- if (m_isFile)
- {
- // go back to no threaded reading
- stopCache();
- break;
- }
- return NULL;
- }
- if (frame->framePosition == -1)
- {
- // this frame mark the end of the file (only used for file)
- // leave in cache to make sure we don't miss it
- m_eof = true;
- return NULL;
- }
- // for streaming, always return the next frame,
- // that's what grabFrame does in non cache mode anyway.
- if (m_isStreaming || frame->framePosition == position)
- {
- return frame->frame;
- }
- // for cam, skip old frames to keep image realtime.
- // There should be no risk of clock drift since it all happens on the same CPU
- if (frame->framePosition > position)
- {
- // this can happen after rewind if the seek didn't find the first frame
- // the frame in the buffer is ahead of time, just leave it there
- return NULL;
- }
- // this frame is not useful, release it
- pthread_mutex_lock(&m_cacheMutex);
- BLI_remlink(&m_frameCacheBase, frame);
- BLI_addtail(&m_frameCacheFree, frame);
- pthread_mutex_unlock(&m_cacheMutex);
- } while (true);
- }
- double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
- int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time;
- if (startTs == AV_NOPTS_VALUE)
- startTs = 0;
-
- // come here when there is no cache or cache has been stopped
- // locate the frame, by seeking if necessary (seeking is only possible for files)
- if (m_isFile)
- {
- // 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_video2(
- m_codecCtx,
- m_frame, &frameFinished,
- &packet);
- if (frameFinished)
- {
- m_curPosition = (long)((packet.dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
- }
- }
- 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)
- {
- int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase));
-
- if (pos < 0)
- pos = 0;
-
- pos += startTs;
-
- if (position <= m_curPosition || !m_eof)
- {
-#if 0
- // Tried to make this work but couldn't: seeking on byte is ignored by the
- // format plugin and it will generally continue to read from last timestamp.
- // Too bad because frame seek is not always able to get the first frame
- // of the file.
- if (position <= m_preseek)
- {
- // we can safely go the beginning of the file
- if (av_seek_frame(m_formatCtx, m_videoStream, 0, AVSEEK_FLAG_BYTE) >= 0)
- {
- // binary seek does not reset the timestamp, must do it now
- av_update_cur_dts(m_formatCtx, m_formatCtx->streams[m_videoStream], startTs);
- m_curPosition = 0;
- }
- }
- else
-#endif
- {
- // current position is now lost, guess a value.
- if (av_seek_frame(m_formatCtx, m_videoStream, pos, AVSEEK_FLAG_BACKWARD) >= 0)
- {
- // 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 = (int64_t)(position / (m_baseFrameRate * timeBase)) + startTs;
-
- posFound = 0;
- avcodec_flush_buffers(m_codecCtx);
- }
- } else if (m_isThreaded)
- {
- // cache is not started but threading is possible
- // better not read the stream => make take some time, better start caching
- if (startCache())
- return NULL;
- // Abnormal!!! could not start cache, fall back on direct read
- m_isThreaded = false;
- }
-
- // find the correct frame, in case of streaming and no cache, it means just
- // return the next frame. This is not quite correct, may need more work
- while (av_read_frame(m_formatCtx, &packet) >= 0)
- {
- if (packet.stream_index == m_videoStream)
- {
- AVFrame *input = m_frame;
- short counter = 0;
-
- /* If m_isImage, while the data is not read properly (png, tiffs, etc formats may need several pass), else don't need while loop*/
- do {
- avcodec_decode_video2(m_codecCtx, m_frame, &frameFinished, &packet);
- counter++;
- } while ((input->data[0] == 0 && input->data[1] == 0 && input->data[2] == 0 && input->data[3] == 0) && counter < 10 && m_isImage);
-
- // remember dts to compute exact frame number
- dts = packet.dts;
- if (frameFinished && !posFound)
- {
- if (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 RGB24
- sws_scale(m_imgConvertCtx,
- input->data,
- input->linesize,
- 0,
- m_codecCtx->height,
- m_frameRGB->data,
- m_frameRGB->linesize);
- av_free_packet(&packet);
- frameLoaded = true;
- break;
- }
- }
- av_free_packet(&packet);
- }
- m_eof = m_isFile && !frameLoaded;
- if (frameLoaded)
- {
- m_curPosition = (long)((dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
- if (m_isThreaded)
- {
- // normal case for file: first locate, then start cache
- if (!startCache())
- {
- // Abnormal!! could not start cache, return to non-cache mode
- m_isThreaded = false;
- }
- }
- return m_frameRGB;
- }
- return NULL;
-}
-
-
-// python methods
-
-
-// cast Image pointer to VideoFFmpeg
-inline VideoFFmpeg * getVideoFFmpeg (PyImage *self)
-{ return static_cast<VideoFFmpeg*>(self->m_image); }
-
-
-// object initialization
-static int VideoFFmpeg_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
- // parameters - video source
- // file name or format type for capture (only for Linux: video4linux or dv1394)
- char * file = NULL;
- // capture device number
- short capt = -1;
- // capture width, only if capt is >= 0
- short width = 0;
- // capture height, only if capt is >= 0
- short height = 0;
- // capture rate, only if capt is >= 0
- float rate = 25.f;
-
- static const char *kwlist[] = {"file", "capture", "rate", "width", "height", NULL};
-
- // get parameters
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|hfhh",
- const_cast<char**>(kwlist), &file, &capt, &rate, &width, &height))
- return -1;
-
- try
- {
- // create video object
- Video_init<VideoFFmpeg>(self);
-
- // set thread usage
- getVideoFFmpeg(self)->initParams(width, height, rate);
-
- // open video source
- Video_open(getVideo(self), file, capt);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // initialization succeded
- return 0;
-}
-
-static PyObject *VideoFFmpeg_getPreseek(PyImage *self, void *closure)
-{
- return Py_BuildValue("h", getFFmpeg(self)->getPreseek());
-}
-
-// set range
-static int VideoFFmpeg_setPreseek(PyImage *self, PyObject *value, void *closure)
-{
- // check validity of parameter
- if (value == NULL || !PyLong_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be an integer");
- return -1;
- }
- // set preseek
- getFFmpeg(self)->setPreseek(PyLong_AsLong(value));
- // success
- return 0;
-}
-
-// get deinterlace
-static PyObject *VideoFFmpeg_getDeinterlace(PyImage *self, void *closure)
-{
- if (getFFmpeg(self)->getDeinterlace())
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-// set flip
-static 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 (restart) video"},
- {"pause", (PyCFunction)Video_pause, METH_NOARGS, "pause video"},
- {"stop", (PyCFunction)Video_stop, METH_NOARGS, "stop video (play will replay it from start)"},
- {"refresh", (PyCFunction)Video_refresh, METH_VARARGS, "Refresh video - get its status"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef videoGetSets[] =
-{ // methods from VideoBase class
- {(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
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", 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}
-};
-
-// python type declaration
-PyTypeObject VideoFFmpegType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "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*/
- &imageBufferProcs, /*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 */
-};
-
-// object initialization
-static int ImageFFmpeg_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
-{
- PyImage *self = reinterpret_cast<PyImage*>(pySelf);
- // parameters - video source
- // file name or format type for capture (only for Linux: video4linux or dv1394)
- char * file = NULL;
-
- // get parameters
- if (!PyArg_ParseTuple(args, "s:ImageFFmpeg", &file))
- return -1;
-
- try
- {
- // create video object
- Video_init<VideoFFmpeg>(self);
-
- getVideoFFmpeg(self)->initParams(0, 0, 1.0, true);
-
- // open video source
- Video_open(getVideo(self), file, -1);
- }
- catch (Exception & exp)
- {
- exp.report();
- return -1;
- }
- // initialization succeded
- return 0;
-}
-
-static PyObject *Image_reload(PyImage *self, PyObject *args)
-{
- char * newname = NULL;
- if (!PyArg_ParseTuple(args, "|s:reload", &newname))
- return NULL;
- if (self->m_image != NULL)
- {
- VideoFFmpeg* video = getFFmpeg(self);
- // check type of object
- if (!newname)
- newname = video->getImageName();
- if (!newname) {
- // if not set, retport error
- PyErr_SetString(PyExc_RuntimeError, "No image file name given");
- return NULL;
- }
- // make sure the previous file is cleared
- video->release();
- // open the new file
- video->openFile(newname);
- }
- Py_RETURN_NONE;
-}
-
-// methods structure
-static PyMethodDef imageMethods[] =
-{ // methods from VideoBase class
- {"refresh", (PyCFunction)Video_refresh, METH_VARARGS, "Refresh image, i.e. load it"},
- {"reload", (PyCFunction)Image_reload, METH_VARARGS, "Reload image, i.e. reopen it"},
- {NULL}
-};
-// attributes structure
-static PyGetSetDef imageGetSets[] =
-{ // methods from VideoBase class
- {(char*)"status", (getter)Video_getStatus, NULL, (char*)"video status", NULL},
- // attributes from ImageBase class
- {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", 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 neighbor)", 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}
-};
-
-// python type declaration
-PyTypeObject ImageFFmpegType =
-{
- PyVarObject_HEAD_INIT(NULL, 0)
- "VideoTexture.ImageFFmpeg", /*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*/
- &imageBufferProcs, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "FFmpeg image source", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- imageMethods, /* tp_methods */
- 0, /* tp_members */
- imageGetSets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ImageFFmpeg_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
deleted file mode 100644
index 0a49a0b19bb..00000000000
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file VideoFFmpeg.h
- * \ingroup bgevideotex
- */
-
-#ifndef __VIDEOFFMPEG_H__
-#define __VIDEOFFMPEG_H__
-
-#ifdef WITH_FFMPEG
-/* this needs to be parsed with __cplusplus defined before included through ffmpeg_compat.h */
-#if defined(__FreeBSD__)
-# include <inttypes.h>
-#endif
-extern "C" {
-#include <pthread.h>
-#include "ffmpeg_compat.h"
-#include "DNA_listBase.h"
-#include "BLI_threads.h"
-#include "BLI_blenlib.h"
-}
-
-#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"
-
-#define CACHE_FRAME_SIZE 10
-#define CACHE_PACKET_SIZE 30
-
-// 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, bool image=false);
- /// open video/image file
- virtual void openFile(char *file);
- /// open video capture device
- virtual void openCam(char *driver, short camIdx);
-
- /// release video source
- virtual bool release (void);
- /// overwrite base refresh to handle fixed image
- virtual void refresh(void);
- /// play video
- virtual bool play (void);
- /// pause video
- virtual bool pause (void);
- /// stop 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; }
- char *getImageName(void) { return (m_isImage) ? m_imageName.Ptr() : NULL; }
-
-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_frameRGB;
- // 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;
-
- /// end of file reached
- bool m_eof;
-
- /// flag to indicate that time is coming from application
- bool m_externTime;
-
- /// 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;
-
- /// is file an image?
- bool m_isImage;
-
- /// is image loading done in a separate thread?
- bool m_isThreaded;
-
- /// is streaming or camera?
- bool m_isStreaming;
-
- /// keep last image name
- STR_String m_imageName;
-
- /// image calculation
- virtual void calcImage (unsigned int texId, double ts);
-
- /// 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, AVDictionary **formatParams);
-
- /// check if a frame is available and load it in pFrame, return true if a frame could be retrieved
- AVFrame* grabFrame(long frame);
-
- /// in case of caching, put the frame back in free queue
- void releaseFrame(AVFrame* frame);
-
- /// start thread to load the video file/capture/stream
- bool startCache();
- void stopCache();
-
-private:
- typedef struct {
- Link link;
- long framePosition;
- AVFrame *frame;
- } CacheFrame;
- typedef struct {
- Link link;
- AVPacket packet;
- } CachePacket;
-
- bool m_stopThread;
- bool m_cacheStarted;
- ListBase m_thread;
- ListBase m_frameCacheBase; // list of frames that are ready
- ListBase m_frameCacheFree; // list of frames that are unused
- ListBase m_packetCacheBase; // list of packets that are ready for decoding
- ListBase m_packetCacheFree; // list of packets that are unused
- pthread_mutex_t m_cacheMutex;
-
- AVFrame *allocFrameRGB();
- static void *cacheThread(void *);
-};
-
-inline VideoFFmpeg *getFFmpeg(PyImage *self)
-{
- return static_cast<VideoFFmpeg*>(self->m_image);
-}
-
-#endif /* WITH_FFMPEG */
-
-#endif /* __VIDEOFFMPEG_H__ */
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
deleted file mode 100644
index 9b046d46412..00000000000
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2006 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/blendVideoTex.cpp
- * \ingroup bgevideotex
- */
-
-#include "EXP_PyObjectPlus.h"
-
-#include "KX_PythonInit.h"
-
-#include <RAS_IPolygonMaterial.h>
-
-//Old API
-//#include "TexPlayer.h"
-//#include "TexImage.h"
-//#include "TexFrameBuff.h"
-
-//#include "TexPlayerGL.h"
-
-#include "ImageBase.h"
-#include "VideoBase.h"
-#include "FilterBase.h"
-#include "Texture.h"
-
-#include "Exception.h"
-
-// access to IMB_BLEND_* constants
-extern "C"
-{
-#include "IMB_imbuf.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:materialID", &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, "VideoTexture.materialID(ob, string): 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 PyUnicode_FromString(Exception::m_lastError.c_str());
-}
-
-// set log file
-static PyObject *setLogFile (PyObject *self, PyObject *args)
-{
- // get parameters
- if (!PyArg_ParseTuple(args, "s:setLogFile", &Exception::m_logFile))
- return Py_BuildValue("i", -1);
- // log file was loaded
- return Py_BuildValue("i", 0);
-}
-
-
-// image to numpy array
-static PyObject *imageToArray(PyObject *self, PyObject *args)
-{
- // parameter is Image object
- PyObject *pyImg;
- char *mode = NULL;
- if (!PyArg_ParseTuple(args, "O|s:imageToArray", &pyImg, &mode) || !pyImageTypes.in(Py_TYPE(pyImg)))
- {
- // if object is incorect, report error
- PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object");
- return NULL;
- }
- // get image structure
- PyImage * img = reinterpret_cast<PyImage*>(pyImg);
- return Image_getImage(img, mode);
-}
-
-
-// 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 buffer from image source, color channels are selectable"},
- {NULL} /* Sentinel */
-};
-
-#ifdef WITH_FFMPEG
-extern PyTypeObject VideoFFmpegType;
-extern PyTypeObject ImageFFmpegType;
-#endif
-#ifdef WITH_GAMEENGINE_DECKLINK
-extern PyTypeObject VideoDeckLinkType;
-extern PyTypeObject DeckLinkType;
-#endif
-extern PyTypeObject FilterBlueScreenType;
-extern PyTypeObject FilterGrayType;
-extern PyTypeObject FilterColorType;
-extern PyTypeObject FilterLevelType;
-extern PyTypeObject FilterNormalType;
-extern PyTypeObject FilterRGB24Type;
-extern PyTypeObject FilterRGBA32Type;
-extern PyTypeObject FilterBGR24Type;
-extern PyTypeObject ImageBuffType;
-extern PyTypeObject ImageMixType;
-
-static void registerAllTypes(void)
-{
-#ifdef WITH_FFMPEG
- pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg");
- pyImageTypes.add(&ImageFFmpegType, "ImageFFmpeg");
-#endif
-#ifdef WITH_GAMEENGINE_DECKLINK
- pyImageTypes.add(&VideoDeckLinkType, "VideoDeckLink");
-#endif
- pyImageTypes.add(&ImageBuffType, "ImageBuff");
- pyImageTypes.add(&ImageMixType, "ImageMix");
- pyImageTypes.add(&ImageRenderType, "ImageRender");
- pyImageTypes.add(&ImageMirrorType, "ImageMirror");
- 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(&FilterRGBA32Type, "FilterRGBA32");
- pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
-}
-
-PyDoc_STRVAR(VideoTexture_module_documentation,
-"Module that allows to play video files on textures in GameBlender."
-);
-
-static struct PyModuleDef VideoTexture_module_def = {
- PyModuleDef_HEAD_INIT,
- "VideoTexture", /* m_name */
- VideoTexture_module_documentation, /* m_doc */
- 0, /* m_size */
- moduleMethods, /* m_methods */
- 0, /* m_reload */
- 0, /* m_traverse */
- 0, /* m_clear */
- 0, /* m_free */
-};
-
-PyMODINIT_FUNC initVideoTexturePythonBinding(void)
-{
- PyObject *m;
-
- // initialize GL extensions
- //bgl::InitExtensions(0);
-
- // prepare classes
- registerAllTypes();
- registerAllExceptions();
-
- if (!pyImageTypes.ready())
- return NULL;
- if (!pyFilterTypes.ready())
- return NULL;
- if (PyType_Ready(&TextureType) < 0)
- return NULL;
-#ifdef WITH_GAMEENGINE_DECKLINK
- if (PyType_Ready(&DeckLinkType) < 0)
- return NULL;
-#endif
-
- m = PyModule_Create(&VideoTexture_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m);
-
- if (m == NULL)
- return NULL;
-
- // initialize classes
- pyImageTypes.reg(m);
- pyFilterTypes.reg(m);
-
- Py_INCREF(&TextureType);
- PyModule_AddObject(m, "Texture", (PyObject *)&TextureType);
-#ifdef WITH_GAMEENGINE_DECKLINK
- Py_INCREF(&DeckLinkType);
- PyModule_AddObject(m, "DeckLink", (PyObject *)&DeckLinkType);
-#endif
- PyModule_AddIntConstant(m, "SOURCE_ERROR", SourceError);
- PyModule_AddIntConstant(m, "SOURCE_EMPTY", SourceEmpty);
- PyModule_AddIntConstant(m, "SOURCE_READY", SourceReady);
- PyModule_AddIntConstant(m, "SOURCE_PLAYING", SourcePlaying);
- PyModule_AddIntConstant(m, "SOURCE_STOPPED", SourceStopped);
-
- PyModule_AddIntConstant(m, "IMB_BLEND_MIX", IMB_BLEND_MIX);
- PyModule_AddIntConstant(m, "IMB_BLEND_ADD", IMB_BLEND_ADD);
- PyModule_AddIntConstant(m, "IMB_BLEND_SUB", IMB_BLEND_SUB);
- PyModule_AddIntConstant(m, "IMB_BLEND_MUL", IMB_BLEND_MUL);
- PyModule_AddIntConstant(m, "IMB_BLEND_LIGHTEN", IMB_BLEND_LIGHTEN);
- PyModule_AddIntConstant(m, "IMB_BLEND_DARKEN", IMB_BLEND_DARKEN);
- PyModule_AddIntConstant(m, "IMB_BLEND_ERASE_ALPHA", IMB_BLEND_ERASE_ALPHA);
- PyModule_AddIntConstant(m, "IMB_BLEND_ADD_ALPHA", IMB_BLEND_ADD_ALPHA);
- PyModule_AddIntConstant(m, "IMB_BLEND_OVERLAY", IMB_BLEND_OVERLAY);
- PyModule_AddIntConstant(m, "IMB_BLEND_HARDLIGHT", IMB_BLEND_HARDLIGHT);
- PyModule_AddIntConstant(m, "IMB_BLEND_COLORBURN", IMB_BLEND_COLORBURN);
- PyModule_AddIntConstant(m, "IMB_BLEND_LINEARBURN", IMB_BLEND_LINEARBURN);
- PyModule_AddIntConstant(m, "IMB_BLEND_COLORDODGE", IMB_BLEND_COLORDODGE);
- PyModule_AddIntConstant(m, "IMB_BLEND_SCREEN", IMB_BLEND_SCREEN);
- PyModule_AddIntConstant(m, "IMB_BLEND_SOFTLIGHT", IMB_BLEND_SOFTLIGHT);
- PyModule_AddIntConstant(m, "IMB_BLEND_PINLIGHT", IMB_BLEND_PINLIGHT);
- PyModule_AddIntConstant(m, "IMB_BLEND_VIVIDLIGHT", IMB_BLEND_VIVIDLIGHT);
- PyModule_AddIntConstant(m, "IMB_BLEND_LINEARLIGHT", IMB_BLEND_LINEARLIGHT);
- PyModule_AddIntConstant(m, "IMB_BLEND_DIFFERENCE", IMB_BLEND_DIFFERENCE);
- PyModule_AddIntConstant(m, "IMB_BLEND_EXCLUSION", IMB_BLEND_EXCLUSION);
- PyModule_AddIntConstant(m, "IMB_BLEND_HUE", IMB_BLEND_HUE);
- PyModule_AddIntConstant(m, "IMB_BLEND_SATURATION", IMB_BLEND_SATURATION);
- PyModule_AddIntConstant(m, "IMB_BLEND_LUMINOSITY", IMB_BLEND_LUMINOSITY);
- PyModule_AddIntConstant(m, "IMB_BLEND_COLOR", IMB_BLEND_COLOR);
-
- PyModule_AddIntConstant(m, "IMB_BLEND_COPY", IMB_BLEND_COPY);
- PyModule_AddIntConstant(m, "IMB_BLEND_COPY_RGB", IMB_BLEND_COPY_RGB);
- PyModule_AddIntConstant(m, "IMB_BLEND_COPY_ALPHA", IMB_BLEND_COPY_ALPHA);
-
- // init last error description
- Exception::m_lastError = "";
-
- return m;
-}
-
-// registration to Image types, put here because of silly linker bug