
The new class VideoTexture.ImageRender() is available to perform render to texture in the GE. Constructor: VideoTexture.ImageRender(scene,cam) cam : camera object that will be used for the render. It must be an inactive camera. scene: reference to the scene that will be rendered. The camera must be part of that scene. Returns an object that can be used as a source of a VideoTexture.Texture object Methods: none Attributes: background: 4-tuple representing the background color of the rendering as RGBA color components, each component being an integer between 0 and 255. Default value = [0,0,255,255] (=saturated blue) Note: athough the alpha component can be specified, it is not supported at the moment, the alpha channel of the rendered texture will always be 255. You can however introduce an alpha channel by appending a FilterBlueScreen() filter, it will set the alpha to 0 (transparent) on all pixels that were not rendered. capsize: 2-tuple representing the size of the render area as [x,y] number of pixels. Default value = largest rectangle with power of 2 dimensions that fits in the canvas You may want to reduce the render area to increase performance. For example, a render area of [256,128] is probably sufficient to implement a car inner mirror. For best performance, use power of 2 dimensions and don't set any filter: this allows direct transfer between the GPU frame buffer and texture memory without going through the host. alpha: Boolean indicating if the render alpha channel should be copied to the texture. Default value: False Experimental, do not use. whole: Boolean indicating if the entire canvas should be used for the rendering. Default value: False Note: There is no reason to set this attribute to True: the rendering will in any case be scaled down to the largest rectangle with power of 2 dimensions before transfering to the texture. Attributes inherited from the ImageBase class: image : image binary data, read-only size : [x,y] size of the texture, read-only scale : set to True for fast scale down in case the render area dimensions are not power of 2 flip : set to True for vertical flip. filter: set a post-processing filter on the render. Notes: * Aspect Ratio For consistent results in Blender and Blenderplayer, the same aspect ratio used by Blender to draw the camera viewport (Scene(F10)->Format tab->Size X/Size Y) is also used during the rendering. You can control the portion of the scene that will be rendered by "looking through the camera": the zone inside the outer dotted rectangle will be rendered to the texture. In order to reproduce the scene without X/Y distortion, you must apply the texture on an object or portion of object that has the same aspect ratio. * Order of rendering The rendereing is performed when you call the refresh() method of the parent Texture object. This happens outside the normal frame rendering and will have no effect on it. However, if you want to use ImageViewport and ImageRender at the same time, be sure to refresh the viewport texture before the render texture because the latter will destroy the frame buffer that is used by the former to update the texture. * Scene status The meshes are not updated during the render to texture: the rendered texture is one frame late to the rendered frame with regards to mesh deformation. * Example: cont = GameLogic.getCurrentController() # object that receives the texture obj = contr.getOwner() scene = GameLogic.getCurrentScene() # camera used for the render tvcam = scene.getObjectList()['OBtvcam'] # assume obj has some faces UV assigned to tv.png matID = VideoTexture.materialID(obj, 'IMtv.png') GameLogic.tv = VideoTexture.Texture(obj, matID) GameLogic.tv.source = VideoTexture.ImageRender(scene,tvcam) GameLogic.tv.source.capsize = [256,256] # to render the texture, just call GameLogic.tv.refresh(True) on each frame. You can download a demo game (with a video file) here: http://home.scarlet.be/~tsi46445/blender/VideoTextureDemo.zip For those who have already downloaded the demo, you can just update the blend file: http://home.scarlet.be/~tsi46445/blender/VideoTextureDemo.blend
195 lines
5.7 KiB
C++
195 lines
5.7 KiB
C++
/* $Id$
|
|
-----------------------------------------------------------------------------
|
|
This source file is part of VideoTexure library
|
|
|
|
Copyright (c) 2006 The Zdeno Ash Miklas
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU Lesser General Public License as published by the Free Software
|
|
Foundation; either version 2 of the License, or (at your option) any later
|
|
version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
|
http://www.gnu.org/copyleft/lesser.txt.
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <PyObjectPlus.h>
|
|
|
|
#include <RAS_GLExtensionManager.h>
|
|
|
|
#include <RAS_IPolygonMaterial.h>
|
|
|
|
//Old API
|
|
//#include "TexPlayer.h"
|
|
//#include "TexImage.h"
|
|
//#include "TexFrameBuff.h"
|
|
|
|
//#include "TexPlayerGL.h"
|
|
|
|
#include "ImageBase.h"
|
|
#include "FilterBase.h"
|
|
#include "Texture.h"
|
|
|
|
#include "Exception.h"
|
|
|
|
|
|
// get material id
|
|
static PyObject * getMaterialID (PyObject *self, PyObject *args)
|
|
{
|
|
// parameters - game object with video texture
|
|
PyObject * obj = NULL;
|
|
// material name
|
|
char * matName;
|
|
|
|
// get parameters
|
|
if (!PyArg_ParseTuple(args, "Os", &obj, &matName))
|
|
return NULL;
|
|
// get material id
|
|
short matID = getMaterialID(obj, matName);
|
|
// if material was not found, report errot
|
|
if (matID < 0)
|
|
{
|
|
PyErr_SetString(PyExc_RuntimeError, "object doesn't have material with given name");
|
|
return NULL;
|
|
}
|
|
// return material ID
|
|
return Py_BuildValue("h", matID);
|
|
}
|
|
|
|
|
|
// get last error description
|
|
static PyObject * getLastError (PyObject *self, PyObject *args)
|
|
{
|
|
return Py_BuildValue("s", Exception::m_lastError.c_str());
|
|
}
|
|
|
|
// set log file
|
|
static PyObject * setLogFile (PyObject *self, PyObject *args)
|
|
{
|
|
// get parameters
|
|
if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile))
|
|
return Py_BuildValue("i", -1);
|
|
// log file was loaded
|
|
return Py_BuildValue("i", 0);
|
|
}
|
|
|
|
|
|
// image to numpy array
|
|
static PyObject * imageToArray (PyObject * self, PyObject *args)
|
|
{
|
|
// parameter is Image object
|
|
PyObject * pyImg;
|
|
if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
|
|
{
|
|
// if object is incorect, report error
|
|
PyErr_SetString(PyExc_TypeError, "The value must be a image source object");
|
|
return NULL;
|
|
}
|
|
// get image structure
|
|
PyImage * img = reinterpret_cast<PyImage*>(pyImg);
|
|
// create array object
|
|
unsigned int * imgBuff = img->m_image->getImage();
|
|
// if image is available, convert it to array
|
|
if (imgBuff != NULL)
|
|
// Nasty problem here: the image buffer is an array of integers
|
|
// in the processor endian format. The user must take care of that in the script.
|
|
// Need to find an elegant solution to this problem
|
|
return Py_BuildValue("s#", imgBuff, img->m_image->getBuffSize());
|
|
// otherwise return None
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
// metody modulu
|
|
static PyMethodDef moduleMethods[] =
|
|
{
|
|
{"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"},
|
|
{"getLastError", getLastError, METH_NOARGS, "Gets last error description"},
|
|
{"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"},
|
|
{"imageToArray", imageToArray, METH_VARARGS, "get array from image source"},
|
|
{NULL} /* Sentinel */
|
|
};
|
|
|
|
#if WITH_FFMPEG
|
|
extern PyTypeObject VideoFFmpegType;
|
|
extern PyTypeObject ImageFFmpegType;
|
|
#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;
|
|
extern PyTypeObject ImageRenderType;
|
|
extern PyTypeObject ImageViewportType;
|
|
extern PyTypeObject ImageViewportType;
|
|
|
|
|
|
static void registerAllTypes(void)
|
|
{
|
|
#if WITH_FFMPEG
|
|
pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg");
|
|
pyImageTypes.add(&ImageFFmpegType, "ImageFFmpeg");
|
|
#endif
|
|
pyImageTypes.add(&ImageBuffType, "ImageBuff");
|
|
pyImageTypes.add(&ImageMixType, "ImageMix");
|
|
pyImageTypes.add(&ImageRenderType, "ImageRender");
|
|
pyImageTypes.add(&ImageViewportType, "ImageViewport");
|
|
|
|
pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen");
|
|
pyFilterTypes.add(&FilterGrayType, "FilterGray");
|
|
pyFilterTypes.add(&FilterColorType, "FilterColor");
|
|
pyFilterTypes.add(&FilterLevelType, "FilterLevel");
|
|
pyFilterTypes.add(&FilterNormalType, "FilterNormal");
|
|
pyFilterTypes.add(&FilterRGB24Type, "FilterRGB24");
|
|
pyFilterTypes.add(&FilterRGBA32Type, "FilterRGBA32");
|
|
pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
|
|
}
|
|
|
|
PyObject* initVideoTexture(void)
|
|
{
|
|
// 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;
|
|
|
|
PyObject * m = Py_InitModule4("VideoTexture", moduleMethods,
|
|
"Module that allows to play video files on textures in GameBlender.",
|
|
(PyObject*)NULL,PYTHON_API_VERSION);
|
|
if (m == NULL)
|
|
return NULL;
|
|
|
|
// initialize classes
|
|
pyImageTypes.reg(m);
|
|
pyFilterTypes.reg(m);
|
|
|
|
Py_INCREF(&TextureType);
|
|
PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType);
|
|
|
|
// init last error description
|
|
Exception::m_lastError[0] = '\0';
|
|
return m;
|
|
}
|
|
|
|
// registration to Image types, put here because of silly linker bug
|