VideoTexture module.
[blender-staging.git] / source / gameengine / VideoTexture / blendVideoTex.cpp
1 /* $Id$
2 -----------------------------------------------------------------------------
3 This source file is part of VideoTexure library
4
5 Copyright (c) 2006 The Zdeno Ash Miklas
6
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19 http://www.gnu.org/copyleft/lesser.txt.
20 -----------------------------------------------------------------------------
21 */
22
23 #define PY_ARRAY_UNIQUE_SYMBOL numpyPtr
24
25 #include <Python.h>
26
27 #include <RAS_GLExtensionManager.h>
28
29 #include <RAS_IPolygonMaterial.h>
30
31 #include <numpy/arrayobject.h>
32
33 //Old API
34 //#include "TexPlayer.h"
35 //#include "TexImage.h"
36 //#include "TexFrameBuff.h"
37
38 //#include "TexPlayerGL.h"
39
40 #include "ImageBase.h"
41 #include "FilterBase.h"
42 #include "Texture.h"
43
44 #include "Exception.h"
45
46
47 // get material id
48 static PyObject * getMaterialID (PyObject *self, PyObject *args)
49 {
50         // parameters - game object with video texture
51         PyObject * obj = NULL;
52         // material name
53         char * matName;
54
55         // get parameters
56         if (!PyArg_ParseTuple(args, "Os", &obj, &matName))
57                 return NULL;
58         // get material id
59         short matID = getMaterialID(obj, matName);
60         // if material was not found, report errot
61         if (matID < 0)
62         {
63                 PyErr_SetString(PyExc_RuntimeError, "object doesn't have material with given name");
64                 return NULL;
65         }
66         // return material ID
67         return Py_BuildValue("h", matID);
68 }
69
70
71 // get last error description
72 static PyObject * getLastError (PyObject *self, PyObject *args)
73 {
74         return Py_BuildValue("s", Exception::m_lastError.c_str());
75 }
76
77 // set log file
78 static PyObject * setLogFile (PyObject *self, PyObject *args)
79 {
80         // get parameters
81         if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile))
82                 return Py_BuildValue("i", -1);
83         // log file was loaded
84         return Py_BuildValue("i", 0);
85 }
86
87
88 // function to initialize numpy structures
89 static bool initNumpy (void)
90 {
91         // init module and report failure
92         import_array1(false);
93         // report success
94         return true;
95 }
96
97 // image to numpy array
98 static PyObject * imageToArray (PyObject * self, PyObject *args)
99 {
100         // parameter is Image object
101         PyObject * pyImg;
102         if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
103         {
104                 // if object is incorect, report error
105                 PyErr_SetString(PyExc_TypeError, "The value must be a image source object");
106                 return NULL;
107         }
108         // get image structure
109         PyImage * img = reinterpret_cast<PyImage*>(pyImg);
110         // check initialization of numpy interface, and initialize it if needed
111         if (numpyPtr == NULL && !initNumpy()) Py_RETURN_NONE;
112         // create array object
113         npy_intp dim[1];
114         dim[0] = img->m_image->getBuffSize() / sizeof(unsigned int);
115         unsigned int * imgBuff = img->m_image->getImage();
116         // if image is available, convert it to array
117         if (imgBuff != NULL)
118                 return PyArray_SimpleNewFromData(1, dim, NPY_UBYTE, imgBuff);
119         // otherwise return None
120         Py_RETURN_NONE;
121 }
122
123
124 // metody modulu
125 static PyMethodDef moduleMethods[] =
126 {
127         {"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"},
128         {"getLastError", getLastError, METH_NOARGS, "Gets last error description"},
129         {"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"},
130         {"imageToArray", imageToArray, METH_VARARGS, "get array from image source"},
131         {NULL}  /* Sentinel */
132 };
133
134 #if WITH_FFMPEG
135 extern PyTypeObject VideoFFmpegType;
136 #endif
137 extern PyTypeObject FilterBlueScreenType;
138 extern PyTypeObject FilterGrayType;
139 extern PyTypeObject FilterColorType;
140 extern PyTypeObject FilterLevelType;
141 extern PyTypeObject FilterNormalType;
142 extern PyTypeObject FilterRGB24Type;
143 extern PyTypeObject FilterBGR24Type;
144 extern PyTypeObject ImageBuffType;
145 extern PyTypeObject ImageMixType;
146 extern PyTypeObject ImageRenderType;
147 extern PyTypeObject ImageViewportType;
148 extern PyTypeObject ImageViewportType;
149
150
151 static void registerAllTypes(void)
152 {
153 #if WITH_FFMPEG
154         pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg");
155 #endif
156         pyImageTypes.add(&ImageBuffType, "ImageBuff");
157         pyImageTypes.add(&ImageMixType, "ImageMix");
158         //pyImageTypes.add(&ImageRenderType, "ImageRender");
159         pyImageTypes.add(&ImageViewportType, "ImageViewport");
160
161         pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen");
162         pyFilterTypes.add(&FilterGrayType, "FilterGray");
163         pyFilterTypes.add(&FilterColorType, "FilterColor");
164         pyFilterTypes.add(&FilterLevelType, "FilterLevel");
165         pyFilterTypes.add(&FilterNormalType, "FilterNormal");
166         pyFilterTypes.add(&FilterRGB24Type, "FilterRGB24");
167         pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
168 }
169
170 PyObject* initVideoTexture(void) 
171 {
172         // initialize GL extensions
173         //bgl::InitExtensions(0);
174
175         // prepare classes
176         registerAllTypes();
177
178         if (!pyImageTypes.ready()) 
179                 return NULL;
180         if (!pyFilterTypes.ready()) 
181                 return NULL;
182         if (PyType_Ready(&TextureType) < 0) 
183                 return NULL;
184
185         PyObject * m = Py_InitModule4("VideoTexture", moduleMethods,
186                 "Module that allows to play video files on textures in GameBlender.",
187                 (PyObject*)NULL,PYTHON_API_VERSION);
188         if (m == NULL) 
189                 return NULL;
190
191         // prepare numpy array
192         numpyPtr = NULL;
193
194         // initialize classes
195         pyImageTypes.reg(m);
196         pyFilterTypes.reg(m);
197
198         Py_INCREF(&TextureType);
199         PyModule_AddObject(m, "Texture", (PyObject*)&TextureType);
200
201         // init last error description
202         Exception::m_lastError[0] = '\0';
203         return m;
204 }
205
206 // registration to Image types, put here because of silly linker bug