[Bf-blender-cvs] [7475752] decklink: BGE: bge.render.offScreenCreate() target argument to select Texture or RenderBuffer as render target.

Benoit Bolsee noreply at git.blender.org
Sat Nov 21 18:28:25 CET 2015


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. @@




More information about the Bf-blender-cvs mailing list