diff options
Diffstat (limited to 'source/gameengine/VideoTexture/ImageBase.cpp')
-rw-r--r-- | source/gameengine/VideoTexture/ImageBase.cpp | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index 8be152c7b8e..0db1fa293da 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -32,7 +32,6 @@ extern "C" { #include "bgl.h" } -#include "glew-mx.h" #include <vector> #include <string.h> @@ -50,6 +49,14 @@ extern "C" { // 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), @@ -111,6 +118,28 @@ unsigned int * ImageBase::getImage (unsigned int texId, double ts) 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) @@ -179,11 +208,18 @@ void ImageBase::setFilter (PyFilter * filt) m_pyfilter = filt; } -ExceptionID ImageHasExports; -ExceptionID InvalidColorChannel; +void ImageBase::swapImageBR() +{ + unsigned int size, v, *s; -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"); + 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) @@ -500,10 +536,57 @@ PyObject *Image_getSize (PyImage *self, void *closure) } // refresh image -PyObject *Image_refresh (PyImage *self) -{ +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(); - Py_RETURN_NONE; + if (done) + Py_RETURN_TRUE; + Py_RETURN_FALSE; } // get scale |