VideoTexture: use PyObjectPlus.h instead of Python.h for compatibility with Python2.3
[blender.git] / source / gameengine / VideoTexture / ImageRender.cpp
1 /* $Id$
2 -----------------------------------------------------------------------------
3 This source file is part of VideoTexture library
4
5 Copyright (c) 2007 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 // implementation
24
25 #include <PyObjectPlus.h>
26 #include <structmember.h>
27
28 #include <KX_BlenderCanvas.h>
29 #include <KX_BlenderRenderTools.h>
30 #include <RAS_IRasterizer.h>
31 #include <RAS_OpenGLRasterizer.h>
32 #include <KX_WorldInfo.h>
33 #include <KX_Light.h>
34
35 #include "ImageRender.h"
36
37 #include "ImageBase.h"
38 #include "BlendType.h"
39 #include "Exception.h"
40
41
42 // constructor
43 ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : m_scene(scene),
44 m_camera(camera)
45 {
46         // create screen area
47         m_area.winrct.xmin = m_upLeft[0];
48         m_area.winrct.ymin = m_upLeft[1];
49         m_area.winx = m_size[0];
50         m_area.winy = m_size[1];
51         // create canvas
52         m_canvas = new KX_BlenderCanvas(&m_area);
53         // create render tools
54         m_rendertools = new KX_BlenderRenderTools();
55         // create rasterizer
56         m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
57         m_rasterizer->Init();
58         // initialize background colour
59         setBackground(0, 0, 255);
60         // refresh lights
61         refreshLights();
62 }
63
64 // destructor
65 ImageRender::~ImageRender (void)
66 {
67         // release allocated objects
68         delete m_rasterizer;
69         delete m_rendertools;
70         delete m_canvas;
71 }
72
73
74 // set background color
75 void ImageRender::setBackground (unsigned char red, unsigned char green, unsigned char blue)
76 {
77         m_background[0] = red;
78         m_background[1] = green;
79         m_background[2] = blue;
80         m_rasterizer->SetBackColor(m_background[0], m_background[1], m_background[2], 1.0);
81 }
82
83
84 // capture image from viewport
85 void ImageRender::calcImage (unsigned int texId)
86 {
87         // setup camera
88         bool cameraPasive = !m_camera->GetViewport();
89         // render scene
90         Render();
91         // reset camera
92         if (cameraPasive) m_camera->EnableViewport(false);
93         // get image from viewport
94         ImageViewport::calcImage(texId);
95 }
96
97 void ImageRender::Render()
98 {
99     //
100 }
101
102 // refresh lights
103 void ImageRender::refreshLights (void)
104 {
105         // clear lights list
106         //m_rendertools->RemoveAllLights();
107         // set lights
108         //for (int idx = 0; idx < scene->GetLightList()->GetCount(); ++idx)
109         //  m_rendertools->AddLight(((KX_LightObject*)(scene->GetLightList()->GetValue(idx)))->GetLightData());
110 }
111
112
113
114 // cast Image pointer to ImageRender
115 inline ImageRender * getImageRender (PyImage * self)
116 { return static_cast<ImageRender*>(self->m_image); }
117
118
119 // python methods
120
121 // Blender Scene type
122 BlendType<KX_Scene> sceneType ("KX_Scene");
123 // Blender Camera type
124 BlendType<KX_Camera> cameraType ("KX_Camera");
125
126
127 ExceptionID SceneInvalid, CameraInvalid;
128 ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid");
129 ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid");
130
131 // object initialization
132 static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
133 {
134         // parameters - scene object
135         PyObject * scene;
136         // camera object
137         PyObject * camera;
138         // parameter keywords
139         static char *kwlist[] = {"sceneObj", "cameraObj", NULL};
140         // get parameters
141         if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &scene, &camera))
142                 return -1;
143         try
144         {
145                 // get scene pointer
146                 KX_Scene * scenePtr (NULL);
147                 if (scene != NULL) scenePtr = sceneType.checkType(scene);
148                 // throw exception if scene is not available
149                 if (scenePtr == NULL) THRWEXCP(SceneInvalid, S_OK);
150
151                 // get camera pointer
152                 KX_Camera * cameraPtr (NULL);
153                 if (camera != NULL) cameraPtr = cameraType.checkType(camera);
154                 // throw exception if camera is not available
155                 if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK);
156
157                 // get pointer to image structure
158                 PyImage * self = reinterpret_cast<PyImage*>(pySelf);
159                 // create source object
160                 if (self->m_image != NULL) delete self->m_image;
161                 self->m_image = new ImageRender(scenePtr, cameraPtr);
162         }
163         catch (Exception & exp)
164         {
165                 exp.report();
166                 return -1;
167         }
168         // initialization succeded
169         return 0;
170 }
171
172
173 // get background color
174 PyObject * getBackground (PyImage * self, void * closure)
175 {
176         return Py_BuildValue("[BBB]", getImageRender(self)->getBackground()[0],
177                 getImageRender(self)->getBackground()[1], getImageRender(self)->getBackground()[2]);
178 }
179
180 // set color
181 static int setBackground (PyImage * self, PyObject * value, void * closure)
182 {
183         // check validity of parameter
184         if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3
185                 || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
186                 || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))
187                 || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)))
188         {
189                 PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints");
190                 return -1;
191         }
192         // set background color
193         getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
194                 (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
195                 (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))));
196         // success
197         return 0;
198 }
199
200
201 // methods structure
202 static PyMethodDef imageRenderMethods[] =
203 { // methods from ImageBase class
204         {"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"},
205         {NULL}
206 };
207 // attributes structure
208 static PyGetSetDef imageRenderGetSets[] =
209
210         {"background", (getter)getBackground, (setter)setBackground, "background color", NULL},
211         // attributes from ImageBase class
212         {"image", (getter)Image_getImage, NULL, "image data", NULL},
213         {"size", (getter)Image_getSize, NULL, "image size", NULL},
214         {"scale", (getter)Image_getScale, (setter)Image_setScale, "fast scale of image (near neighbour)",       NULL},
215         {"flip", (getter)Image_getFlip, (setter)Image_setFlip, "flip image vertically", NULL},
216         {"filter", (getter)Image_getFilter, (setter)Image_setFilter, "pixel filter", NULL},
217         {NULL}
218 };
219
220
221 // define python type
222 PyTypeObject ImageRenderType =
223
224         PyObject_HEAD_INIT(NULL)
225         0,                         /*ob_size*/
226         "VideoTexture.ImageRender",   /*tp_name*/
227         sizeof(PyImage),          /*tp_basicsize*/
228         0,                         /*tp_itemsize*/
229         (destructor)Image_dealloc, /*tp_dealloc*/
230         0,                         /*tp_print*/
231         0,                         /*tp_getattr*/
232         0,                         /*tp_setattr*/
233         0,                         /*tp_compare*/
234         0,                         /*tp_repr*/
235         0,                         /*tp_as_number*/
236         0,                         /*tp_as_sequence*/
237         0,                         /*tp_as_mapping*/
238         0,                         /*tp_hash */
239         0,                         /*tp_call*/
240         0,                         /*tp_str*/
241         0,                         /*tp_getattro*/
242         0,                         /*tp_setattro*/
243         0,                         /*tp_as_buffer*/
244         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
245         "Image source from render",       /* tp_doc */
246         0,                             /* tp_traverse */
247         0,                             /* tp_clear */
248         0,                             /* tp_richcompare */
249         0,                             /* tp_weaklistoffset */
250         0,                             /* tp_iter */
251         0,                             /* tp_iternext */
252         imageRenderMethods,    /* tp_methods */
253         0,                   /* tp_members */
254         imageRenderGetSets,          /* tp_getset */
255         0,                         /* tp_base */
256         0,                         /* tp_dict */
257         0,                         /* tp_descr_get */
258         0,                         /* tp_descr_set */
259         0,                         /* tp_dictoffset */
260         (initproc)ImageRender_init,     /* tp_init */
261         0,                         /* tp_alloc */
262         Image_allocNew,           /* tp_new */
263 };
264
265