Commit: 74757522ba4accf82f4a6c08556d2e12de73a49a
Author: Benoit Bolsee
Date:   Sat Nov 21 18:19:23 2015 +0100
Branches: decklink
https://developer.blender.org/rB74757522ba4accf82f4a6c08556d2e12de73a49a

BGE: bge.render.offScreenCreate() target argument to select Texture or 
RenderBuffer as render target.

fbo = bge.render.offScreenCreate(w,h,samples,target)
target = bge.render.RAS_OFS_RENDER_BUFFER: send render to RenderBuffers 
(compatible with MSAA on Intel GPU)
target = bge.render.RAS_OFS_RENDER_TEXTURE: send render to Texture (not 
compatible with MSAA on Intel GPU)

The default (RAS_OFS_RENDER_BUFFER) is preferable in all cases expect
if you need to access directly the texture for some applications.

The texture bind code is accessible with the new attribute color (fbo.color).
The attribute value is 0 if target is RAS_OFS_RENDER_BUFFER.

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

M       doc/python_api/rst/bge.render.rst
M       intern/ghost/intern/GHOST_ContextGLX.cpp
M       source/gameengine/Ketsji/KX_PythonInit.cpp
M       source/gameengine/Rasterizer/RAS_IOffScreen.h
M       source/gameengine/Rasterizer/RAS_IRasterizer.h
M       
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
M       source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.h
M       
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
M       source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h

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

diff --git a/doc/python_api/rst/bge.render.rst 
b/doc/python_api/rst/bge.render.rst
index 80638c3..0c6f9a9 100644
--- a/doc/python_api/rst/bge.render.rst
+++ b/doc/python_api/rst/bge.render.rst
@@ -90,6 +90,14 @@ Constants
 
    Right eye being used during stereoscopic rendering.
 
+.. data:: RAS_OFS_RENDER_BUFFER
+
+   The pixel buffer for offscreen render is a RenderBuffer. Argument to 
:func:`offScreenCreate`
+
+.. data:: RAS_OFS_RENDER_TEXTURE
+
+   The pixel buffer for offscreen render is a Texture. Argument to 
:func:`offScreenCreate`
+
 *****
 Types
 *****
@@ -98,7 +106,7 @@ Types
 
    An off-screen render buffer object. 
 
-   Use bge.render.offScreenCreate() to create it.
+   Use :func:`offScreenCreate` to create it.
    Currently it can only be used in the :class:`bge.texture.ImageRender` 
constructor to render on a FBO rather than the 
    default viewport.
 
@@ -114,6 +122,12 @@ Types
 
      :type: integer
 
+  .. attribute:: color
+
+     The underlying OpenGL bind code of the texture object that holds the 
rendered image, 0 if the FBO is using RenderBuffer. The choice between 
RenderBuffer and Texture is determined by the target argument of 
:func:`offScreenCreate`.
+
+     :type: integer
+
 *********
 Functions
 *********
@@ -386,7 +400,7 @@ Functions
 
    :rtype: One of VSYNC_OFF, VSYNC_ON, VSYNC_ADAPTIVE
 
-.. function:: offScreenCreate(width,height)
+.. function:: 
offScreenCreate(width,height[,samples=0][,target=bge.render.RAS_OFS_RENDER_BUFFER])
 
    Create a Off-screen render buffer object.
 
@@ -394,5 +408,9 @@ Functions
    :type width: integer
    :arg height: the height of the buffer in pixels
    :type height: integer
+   :arg samples: the number of multisample for anti-aliasing (MSAA), 0 to 
disable MSAA
+   :type samples: integer
+   :arg target: the pixel storage: :data:`RAS_OFS_RENDER_BUFFER` to render on 
RenderBuffers (the default), :data:`RAS_OFS_RENDER_TEXTURE` to render on 
texture. The later is interesting if you want to access the texture directly 
(see :attr:`RASOffScreen.color`). Otherwise the default is preferable as it's 
more widely supported by GPUs and more efficient. If the GPU does not support 
MSAA+Texture (e.g. Intel HD GPU), MSAA will be disabled.
+   :type target: integer
    :rtype: :class:`RASOffScreen`
 
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp 
b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 439b3ba..97b4cbf 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -39,7 +39,6 @@
 #include <cassert>
 #include <cstdio>
 #include <cstring>
-#include <iostream>
 
 /* needed for intel drivers (works w/ mesa-swrast & nvidia) */
 #define USE_GLXEW_INIT_WORKAROUND
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp 
b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 21f953c..d1119b0 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -1492,19 +1492,27 @@ static PyObject *RASOffScreen_height_get(PyRASOffScreen 
*self, void *UNUSED(type
        return PyLong_FromLong(self->ofs->GetHeight());
 }
 
+PyDoc_STRVAR(RASOffScreen_color_doc, "Offscreen buffer texture object (if 
target is RAS_OFS_RENDER_TEXTURE).\n\n:type: GLuint");
+static PyObject *RASOffScreen_color_get(PyRASOffScreen *self, void 
*UNUSED(type))
+{
+       return PyLong_FromLong(self->ofs->GetColor());
+}
+
 static PyGetSetDef RASOffScreen_getseters[] = {
        {(char *)"width", (getter)RASOffScreen_width_get, (setter)NULL, 
RASOffScreen_width_doc, NULL},
        {(char *)"height", (getter)RASOffScreen_height_get, (setter)NULL, 
RASOffScreen_height_doc, NULL},
+    {(char *)"color", (getter)RASOffScreen_color_get, (setter)NULL, 
RASOffScreen_color_doc, NULL},
        {NULL, NULL, NULL, NULL, NULL}  /* Sentinel */
 };
 
 static int PyRASOffScreen__tp_init(PyRASOffScreen *self, PyObject *args, 
PyObject *kwargs)
 {
-       int width, height, samples;
-       const char *keywords[] = {"width", "height", "samples", NULL};
+       int width, height, samples, target;
+       const char *keywords[] = {"width", "height", "samples", "target", NULL};
 
        samples = 0;
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:RASOffscreen", 
(char **)keywords, &width, &height, &samples)) {
+       target = RAS_IOffScreen::RAS_OFS_RENDER_BUFFER;
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii:RASOffscreen", 
(char **)keywords, &width, &height, &samples, &target)) {
                return -1;
        }
 
@@ -1523,12 +1531,17 @@ static int PyRASOffScreen__tp_init(PyRASOffScreen 
*self, PyObject *args, PyObjec
                return -1;
        }
 
+       if (target != RAS_IOffScreen::RAS_OFS_RENDER_BUFFER && target != 
RAS_IOffScreen::RAS_OFS_RENDER_TEXTURE)
+       {
+               PyErr_SetString(PyExc_ValueError, "invalid 'target' given, can 
only be RAS_OFS_RENDER_BUFFER or RAS_OFS_RENDER_TEXTURE");
+               return -1;
+       }
        if (!gp_Rasterizer)
        {
                PyErr_SetString(PyExc_SystemError, "no rasterizer");
                return -1;
        }
-       self->ofs = gp_Rasterizer->CreateOffScreen(width, height, samples);
+       self->ofs = gp_Rasterizer->CreateOffScreen(width, height, samples, 
target);
        if (!self->ofs) {
                PyErr_SetString(PyExc_SystemError, "creation failed");
                return -1;
@@ -1592,9 +1605,10 @@ static PyObject *gPyOffScreenCreate(PyObject 
*UNUSED(self), PyObject *args)
        int width;
        int height;
        int samples;
+       int target;
 
        samples = 0;
-       if (!PyArg_ParseTuple(args, "ii|i:offscreen_create", &width, &height, 
&samples))
+       if (!PyArg_ParseTuple(args, "ii|ii:offScreenCreate", &width, &height, 
&samples, &target))
                return NULL;
 
        return PyObject_CallObject((PyObject *) &PyRASOffScreen_Type, args);
@@ -2485,6 +2499,11 @@ PyMODINIT_FUNC initRasterizerPythonBinding()
        KX_MACRO_addTypesToDict(d, LEFT_EYE, 
RAS_IRasterizer::RAS_STEREO_LEFTEYE);
        KX_MACRO_addTypesToDict(d, RIGHT_EYE, 
RAS_IRasterizer::RAS_STEREO_RIGHTEYE);
 
+       /* offscreen render */
+       KX_MACRO_addTypesToDict(d, RAS_OFS_RENDER_BUFFER, 
RAS_IOffScreen::RAS_OFS_RENDER_BUFFER);
+       KX_MACRO_addTypesToDict(d, RAS_OFS_RENDER_TEXTURE, 
RAS_IOffScreen::RAS_OFS_RENDER_TEXTURE);
+
+
        // XXXX Add constants here
 
        // Check for errors
diff --git a/source/gameengine/Rasterizer/RAS_IOffScreen.h 
b/source/gameengine/Rasterizer/RAS_IOffScreen.h
index f108ea3..0817b40 100644
--- a/source/gameengine/Rasterizer/RAS_IOffScreen.h
+++ b/source/gameengine/Rasterizer/RAS_IOffScreen.h
@@ -47,13 +47,19 @@ public:
                RAS_OFS_BIND_RENDER = 0,
                RAS_OFS_BIND_READ,
        };
+       enum RAS_OFS_RENDER_TARGET {
+               RAS_OFS_RENDER_BUFFER = 0,              // use texture as 
render target
+               RAS_OFS_RENDER_TEXTURE,                 // use render buffer as 
render target
+       };
+
        int         m_width;
        int     m_height;
        int         m_samples;
+       int         m_color;            // if used, holds the texture object, 0 
if not used
 
        virtual ~RAS_IOffScreen() {}
 
-       virtual bool Create(int width, int height, int samples) = 0;
+       virtual bool Create(int width, int height, int samples, 
RAS_OFS_RENDER_TARGET target) = 0;
        virtual void Destroy() = 0;
        virtual void Bind(RAS_OFS_BIND_MODE mode) = 0;
        virtual void Blit() = 0;
@@ -62,6 +68,7 @@ public:
        virtual int GetWidth() { return m_width; }
        virtual int GetHeight() { return m_height; }
        virtual int GetSamples() { return m_samples; }
+       virtual int GetColor() { return m_color; }
 };
 
 #ifdef WITH_PYTHON
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h 
b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index 062795c..487b824 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -262,7 +262,7 @@ public:
         * Create an offscreen render buffer that can be used as target for 
render.
         * For the time being, it is only used in VideoTexture for custom 
render.
         */
-       virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int 
samples) = 0;
+       virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int 
samples, int target) = 0;
 
        /**
         * SwapBuffers swaps the back buffer with the front buffer.
diff --git 
a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp 
b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
index e1c652b..fd556e8 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLOffScreen.cpp
@@ -33,11 +33,13 @@
 #include "RAS_ICanvas.h"
 
 RAS_OpenGLOffScreen::RAS_OpenGLOffScreen(RAS_ICanvas *canvas)
-    :m_canvas(canvas), m_depthrb(0), m_colorrb(0), m_fbo(0), m_blitfbo(0), 
m_blitrbo(0), m_bound(false)
+    :m_canvas(canvas), m_depthrb(0), m_colorrb(0),     m_depthtx(0), 
m_colortx(0),
+     m_fbo(0), m_blitfbo(0), m_blitrbo(0), m_blittex(0), 
m_target(RAS_OFS_RENDER_BUFFER), m_bound(false)
 {
        m_width = 0;
        m_height = 0;
        m_samples = 0;
+       m_color = 0;
 }
 
 RAS_OpenGLOffScreen::~RAS_OpenGLOffScreen()
@@ -45,18 +47,23 @@ RAS_OpenGLOffScreen::~RAS_OpenGLOffScreen()
        Destroy();
 }
 
-bool RAS_OpenGLOffScreen::Create(int width, int height, int samples)
+bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, 
RAS_OFS_RENDER_TARGET target)
 {
        GLenum status;
-       GLuint rbo[2], fbo;
-       int max_samples;
+       GLuint glo[2], fbo;
+       GLint max_samples;
+       GLenum textarget;
 
        if (m_fbo)
        {
                printf("RAS_OpenGLOffScreen::Create(): buffer exists already, 
destroy first\n");
                return false;
        }
-
+       if (target != RAS_IOffScreen::RAS_OFS_RENDER_BUFFER && target != 
RAS_IOffScreen::RAS_OFS_RENDER_TEXTURE)
+       {
+               printf("RAS_OpenGLOffScreen::Create(): invalid offscren 
target\n");
+               return false;
+       }
        if (!GLEW_EXT_framebuffer_object)
        {
                printf("RAS_OpenGLOffScreen::Create(): frame buffer not 
supported\n");
@@ -70,6 +77,15 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int 
samples)
                        samples = 0;
                }
        }
+       if (samples && target == RAS_OFS_RENDER_TEXTURE)
+       {
+               // we need this in addition if we use multisample textures
+               if (   !GLEW_ARB_texture_multisample
+                   || !GLEW_EXT_framebuffer_multisample_blit_scaled)
+               {
+                       samples = 0;
+               }
+       }
        if (samples)
        {
                max_samples = 0;
@@ -77,6 +93,7 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int 
samples)
                if (samples > max_samples)
                        samples = max_samples;
        }
+       m_target = target;
        fbo = 0;
        glGenFramebuffersEXT(1, &fbo);
        if (fbo == 0)
@@ -85,26 +102,59 @@ bool RA

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to