Commit: a2bebb088095343af9af3a4799d46b6328ae84d7
Author: Benoit Bolsee
Date:   Tue Nov 3 17:37:50 2015 +0100
Branches: decklink
https://developer.blender.org/rBa2bebb088095343af9af3a4799d46b6328ae84d7

BGE: asynchronous render with ImageRender new render() method

usage:
ir = bge.texture.ImageRender(..)
ir.render()
ir.refresh(buffer)

===================================================================

M       source/gameengine/Rasterizer/RAS_IOffScreen.h
M       
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
M       source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h
M       source/gameengine/VideoTexture/ImageRender.cpp
M       source/gameengine/VideoTexture/ImageRender.h

===================================================================

diff --git a/source/gameengine/Rasterizer/RAS_IOffScreen.h 
b/source/gameengine/Rasterizer/RAS_IOffScreen.h
index 0acf1bb..6063d90 100644
--- a/source/gameengine/Rasterizer/RAS_IOffScreen.h
+++ b/source/gameengine/Rasterizer/RAS_IOffScreen.h
@@ -46,6 +46,10 @@ struct Image;
 class RAS_IOffScreen
 {
 public:
+       enum RAS_OFS_BIND_MODE {
+               RAS_OFS_BIND_RENDER = 0,
+               RAS_OFS_BIND_READ,
+       };
        int             m_width;
        int     m_height;
        int         m_samples;
@@ -54,7 +58,7 @@ public:
 
        virtual bool Create(int width, int height, int samples) = 0;
        virtual void Destroy() = 0;
-       virtual void Bind() = 0;
+       virtual void Bind(RAS_OFS_BIND_MODE mode) = 0;
        virtual void Blit() = 0;
        virtual void Unbind() = 0;
 
diff --git 
a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp 
b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
index bde6764..decf921 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
@@ -133,11 +133,14 @@ void RAS_OpenGLOffScreen::Destroy()
        m_samples = 0;
 }
 
-void RAS_OpenGLOffScreen::Bind()
+void RAS_OpenGLOffScreen::Bind(RAS_OFS_BIND_MODE mode)
 {
        if (m_ofs)
        {
-               GPU_offscreen_bind(m_ofs, false);
+               if (mode == RAS_OFS_BIND_RENDER || !m_blitfbo)
+                       GPU_offscreen_bind(m_ofs, false);
+               else
+                       glBindFramebuffer(GL_READ_FRAMEBUFFER, m_blitfbo);
                m_bound = true;
        }
 }
diff --git 
a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h 
b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h
index 63ac02f..86c6dce 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h
@@ -44,7 +44,7 @@ public:
 
        bool Create(int width, int height, int samples);
        void Destroy();
-       void Bind();
+       void Bind(RAS_OFS_BIND_MODE mode);
        void Blit();
        void Unbind();
 };
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp 
b/source/gameengine/VideoTexture/ImageRender.cpp
index e3e3551..776cae1 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 5b7c789..cc4c862 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);
 };

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to