// 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))
// 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; } }
// 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()); } }
// 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); }
// object initialization static int ImageRender_init(PyObject *pySelf, PyObject *args, PyObject *kwds) { // parameters - scene object PyObject *scene; // camera object PyObject *camera; // parameter keywords static const char *kwlist[] = {"sceneObj", "cameraObj", NULL}; // get parameters if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", const_cast<char**>(kwlist), &scene, &camera)) return -1; try { // get scene pointer KX_Scene * scenePtr (NULL); if (scene != NULL) scenePtr = sceneType.checkType(scene); // throw exception if scene is not available if (scenePtr == NULL) THRWEXCP(SceneInvalid, S_OK); // get camera pointer KX_Camera * cameraPtr (NULL); if (camera != NULL) cameraPtr = cameraType.checkType(camera); // throw exception if camera is not available if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK); // get pointer to image structure PyImage *self = reinterpret_cast<PyImage*>(pySelf); // create source object if (self->m_image != NULL) delete self->m_image; self->m_image = new ImageRender(scenePtr, cameraPtr); } catch (Exception & exp) { exp.report(); return -1; } // initialization succeded return 0; }
// 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; }
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; }
// 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; }
// Texture object initialization int Texture_init (Texture *self, PyObject *args, PyObject *kwds) { // parameters - game object with video texture PyObject * obj = NULL; // material ID short matID = 0; // texture ID short texID = 0; // texture object with shared texture ID Texture * texObj = NULL; static 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); 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 if (mat->GetFlag() & RAS_BLENDERMAT) { // get blender material texture self->m_matTexture = static_cast<KX_BlenderMaterial*>(mat)->getTex(texID); self->m_useMatTexture = true; } else { // get texture pointer from polygon material MTFace * tface = static_cast<KX_PolygonMaterial*>(mat)->GetMTFace(); self->m_imgTexture = (Image*)tface->tpage; 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; }