From a2bebb088095343af9af3a4799d46b6328ae84d7 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 3 Nov 2015 17:37:50 +0100 Subject: BGE: asynchronous render with ImageRender new render() method usage: ir = bge.texture.ImageRender(..) ir.render() ir.refresh(buffer) --- source/gameengine/VideoTexture/ImageRender.cpp | 58 +++++++++++++++++++++----- source/gameengine/VideoTexture/ImageRender.h | 9 ++-- 2 files changed, 54 insertions(+), 13 deletions(-) (limited to 'source/gameengine/VideoTexture') diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index e3e35515634..776cae19487 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -68,6 +68,7 @@ ExpDesc MirrorTooSmallDesc(MirrorTooSmall, "Mirror is too small"); ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera, PyRASOffScreen * offscreen) : ImageViewport(offscreen), m_render(true), + m_done(false), m_scene(scene), m_camera(camera), m_owncamera(false), @@ -133,24 +134,26 @@ void ImageRender::setBackgroundFromScene (KX_Scene *scene) void ImageRender::calcViewport (unsigned int texId, double ts, unsigned int format) { // render the scene from the camera - if (!Render()) + if (!m_done) { - m_avail = false; - return; + if (!Render()) + { + return; + } + } + else if (m_offscreen) + { + m_offscreen->ofs->Bind(RAS_IOffScreen::RAS_OFS_BIND_READ); } - - // In case multisample is active, blit the FBO - if (m_offscreen) - m_offscreen->ofs->Blit(); // get image from viewport (or FBO) ImageViewport::calcViewport(texId, ts, format); - // restore OpenGL state - m_canvas->EndFrame(); if (m_offscreen) { m_offscreen->ofs->Unbind(); } + // so that next time we render again + m_done = false; } bool ImageRender::Render() @@ -238,7 +241,7 @@ bool ImageRender::Render() if (m_offscreen) { // bind the fbo and set the viewport to full size - m_offscreen->ofs->Bind(); + m_offscreen->ofs->Bind(RAS_IOffScreen::RAS_OFS_BIND_RENDER); // this is needed to stop crashing in canvas check m_canvas->UpdateViewPort(0, 0, m_offscreen->ofs->GetWidth(), m_offscreen->ofs->GetHeight()); } @@ -345,10 +348,25 @@ bool ImageRender::Render() // restore the canvas area now that the render is completed m_canvas->GetWindowArea() = area; + m_canvas->EndFrame(); + // In case multisample is active, blit the FBO + if (m_offscreen) + m_offscreen->ofs->Blit(); + // remember that we have done render + m_done = true; + // the image is not available at this stage + m_avail = false; return true; } +void ImageRender::Unbind() +{ + if (m_offscreen) + { + m_offscreen->ofs->Unbind(); + } +} // cast Image pointer to ImageRender inline ImageRender * getImageRender (PyImage *self) @@ -411,6 +429,24 @@ static int ImageRender_init(PyObject *pySelf, PyObject *args, PyObject *kwds) return 0; } +// refresh image +static PyObject *ImageRender_render(PyImage *self) +{ + ImageRender *imageRender = getImageRender(self); + + if (!imageRender) + { + PyErr_SetString(PyExc_TypeError, "Incomplete ImageRender() object"); + return NULL; + } + if (!imageRender->Render()) + { + Py_RETURN_FALSE; + } + imageRender->Unbind(); + Py_RETURN_TRUE; +} + // get background color static PyObject *getBackground (PyImage *self, void *closure) @@ -450,6 +486,7 @@ static int setBackground(PyImage *self, PyObject *value, void *closure) static PyMethodDef imageRenderMethods[] = { // methods from ImageBase class {"refresh", (PyCFunction)Image_refresh, METH_VARARGS, "Refresh image - invalidate its current content after optionally transferring its content to a target buffer"}, + {"render", (PyCFunction)ImageRender_render, METH_NOARGS, "Render scene - run before refresh() to performs asynchronous render"}, {NULL} }; // attributes structure @@ -640,6 +677,7 @@ static PyGetSetDef imageMirrorGetSets[] = ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial *mat) : ImageViewport(), m_render(false), + m_done(false), m_scene(scene), m_offscreen(NULL), m_observer(observer), diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h index 5b7c789b87b..cc4c86225f2 100644 --- a/source/gameengine/VideoTexture/ImageRender.h +++ b/source/gameengine/VideoTexture/ImageRender.h @@ -64,10 +64,16 @@ public: float getClip (void) { return m_clip; } /// set whole buffer use void setClip (float clip) { m_clip = clip; } + /// render frame (public so that it is accessible from python) + bool Render(); + /// in case fbo is used, method to unbind + void Unbind(); protected: /// true if ready to render bool m_render; + /// is render done already? + bool m_done; /// rendered scene KX_Scene * m_scene; /// camera for render @@ -103,9 +109,6 @@ protected: /// render 3d scene to image virtual void calcViewport (unsigned int texId, double ts, unsigned int format); - bool Render(); - void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam); - void RenderFrame(KX_Scene* scene, KX_Camera* cam); void setBackgroundFromScene(KX_Scene *scene); void SetWorldSettings(KX_WorldInfo* wi); }; -- cgit v1.2.3