| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2015, Blender Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/python/intern/gpu_offscreen.c
 | 
					
						
							|  |  |  |  *  \ingroup pythonintern | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file defines the offscreen functionalities of the 'gpu' module | 
					
						
							|  |  |  |  * used for off-screen OpenGL rendering. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 11:27:26 -02:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ED_screen.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "GPU_compositing.h"
 | 
					
						
							| 
									
										
										
										
											2015-12-06 21:20:19 +01:00
										 |  |  | #include "GPU_framebuffer.h"
 | 
					
						
							| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../mathutils/mathutils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../generic/py_capi_utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gpu.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ED_view3d.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* GPU Offscreen PyObject */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	GPUOffScreen *ofs; | 
					
						
							|  |  |  | } BPy_GPUOffScreen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int bpy_gpu_offscreen_valid_check(BPy_GPUOffScreen *py_gpu_ofs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (UNLIKELY(py_gpu_ofs->ofs == NULL)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ReferenceError, "GPU offscreen was freed, no further access is valid"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BPY_GPU_OFFSCREEN_CHECK_OBJ(pygpu) { \
 | 
					
						
							|  |  |  | 	if (UNLIKELY(bpy_gpu_offscreen_valid_check(pygpu) == -1)) { \ | 
					
						
							|  |  |  | 		return NULL; \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | } ((void)0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_width_doc, "Texture width.\n\n:type: int"); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_width_get(BPy_GPUOffScreen *self, void *UNUSED(type)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 	return PyLong_FromLong(GPU_offscreen_width(self->ofs)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_height_doc, "Texture height.\n\n:type: int"); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_height_get(BPy_GPUOffScreen *self, void *UNUSED(type)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 	return PyLong_FromLong(GPU_offscreen_height(self->ofs)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_color_texture_doc, "Color texture.\n\n:type: int"); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_color_texture_get(BPy_GPUOffScreen *self, void *UNUSED(type)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 	return PyLong_FromLong(GPU_offscreen_color_texture(self->ofs)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_bind_doc, | 
					
						
							|  |  |  | "bind(save=True)\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   Bind the offscreen object.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   :param save: save OpenGL current states.\n" | 
					
						
							|  |  |  | "   :type save: bool\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_bind(BPy_GPUOffScreen *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const char *kwlist[] = {"save", NULL}; | 
					
						
							|  |  |  | 	bool save = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTupleAndKeywords( | 
					
						
							|  |  |  | 	        args, kwds, "|O&:bind", (char **)(kwlist), | 
					
						
							|  |  |  | 	        PyC_ParseBool, &save)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_offscreen_bind(self->ofs, save); | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_unbind_doc, | 
					
						
							|  |  |  | "unbind(restore=True)\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   Unbind the offscreen object.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   :param restore: restore OpenGL previous states.\n" | 
					
						
							|  |  |  | "   :type restore: bool\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_unbind(BPy_GPUOffScreen *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const char *kwlist[] = {"restore", NULL}; | 
					
						
							|  |  |  | 	bool restore = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTupleAndKeywords( | 
					
						
							|  |  |  | 	        args, kwds, "|O&:unbind", (char **)(kwlist), | 
					
						
							|  |  |  | 	        PyC_ParseBool, &restore)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_offscreen_unbind(self->ofs, restore); | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Use with PyArg_ParseTuple's "O&" formatting. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int pygpu_offscreen_check_matrix(PyObject *o, void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MatrixObject **pymat_p = p; | 
					
						
							|  |  |  | 	MatrixObject  *pymat = (MatrixObject *)o; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!MatrixObject_Check(pymat)) { | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "expected a mathutils.Matrix, not a %.200s", | 
					
						
							|  |  |  | 		             Py_TYPE(o)->tp_name); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (BaseMath_ReadCallback(pymat) == -1) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((pymat->num_col != 4) || | 
					
						
							|  |  |  | 	    (pymat->num_row != 4)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ValueError, "matrix must be 4x4"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*pymat_p = pymat; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_draw_view3d_doc, | 
					
						
							|  |  |  | "draw_view3d(scene, view3d, region, modelview_matrix, projection_matrix)\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   Draw the 3d viewport in the offscreen object.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   :param scene: Scene to draw.\n" | 
					
						
							|  |  |  | "   :type scene: :class:`bpy.types.Scene`\n" | 
					
						
							|  |  |  | "   :param view3d: 3D View to get the drawing settings from.\n" | 
					
						
							|  |  |  | "   :type view3d: :class:`bpy.types.SpaceView3D`\n" | 
					
						
							|  |  |  | "   :param region: Region of the 3D View.\n" | 
					
						
							|  |  |  | "   :type region: :class:`bpy.types.Region`\n" | 
					
						
							|  |  |  | "   :param modelview_matrix: ModelView Matrix.\n" | 
					
						
							|  |  |  | "   :type modelview_matrix: :class:`mathutils.Matrix`\n" | 
					
						
							|  |  |  | "   :param projection_matrix: Projection Matrix.\n" | 
					
						
							|  |  |  | "   :type projection_matrix: :class:`mathutils.Matrix`\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const char *kwlist[] = {"scene", "view3d", "region", "projection_matrix", "modelview_matrix", NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MatrixObject *py_mat_modelview, *py_mat_projection; | 
					
						
							|  |  |  | 	PyObject *py_scene, *py_region, *py_view3d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Scene *scene; | 
					
						
							|  |  |  | 	View3D *v3d; | 
					
						
							|  |  |  | 	ARegion *ar; | 
					
						
							|  |  |  | 	GPUFX *fx; | 
					
						
							|  |  |  | 	GPUFXSettings fx_settings; | 
					
						
							| 
									
										
										
										
											2017-03-04 13:32:40 +11:00
										 |  |  | 	struct RV3DMatrixStore *rv3d_mats; | 
					
						
							| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTupleAndKeywords( | 
					
						
							|  |  |  | 	        args, kwds, "OOOO&O&:draw_view3d", (char **)(kwlist), | 
					
						
							|  |  |  | 	        &py_scene, &py_view3d, &py_region, | 
					
						
							|  |  |  | 	        pygpu_offscreen_check_matrix, &py_mat_projection, | 
					
						
							|  |  |  | 	        pygpu_offscreen_check_matrix, &py_mat_modelview) || | 
					
						
							|  |  |  | 	    (!(scene    = PyC_RNA_AsPointer(py_scene, "Scene")) || | 
					
						
							|  |  |  | 	     !(v3d      = PyC_RNA_AsPointer(py_view3d, "SpaceView3D")) || | 
					
						
							|  |  |  | 	     !(ar       = PyC_RNA_AsPointer(py_region, "Region")))) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fx = GPU_fx_compositor_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fx_settings = v3d->fx_settings;  /* full copy */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ED_view3d_draw_offscreen_init(scene, v3d); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 11:27:26 -02:00
										 |  |  | 	rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | 	GPU_offscreen_bind(self->ofs, true); /* bind */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ED_view3d_draw_offscreen( | 
					
						
							|  |  |  | 	        scene, v3d, ar, GPU_offscreen_width(self->ofs), GPU_offscreen_height(self->ofs), | 
					
						
							|  |  |  | 	        (float(*)[4])py_mat_modelview->matrix, (float(*)[4])py_mat_projection->matrix, | 
					
						
							|  |  |  | 	        false, true, true, "", | 
					
						
							|  |  |  | 	        fx, &fx_settings, | 
					
						
							|  |  |  | 	        self->ofs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_fx_compositor_destroy(fx); | 
					
						
							|  |  |  | 	GPU_offscreen_unbind(self->ofs, true); /* unbind */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 11:27:26 -02:00
										 |  |  | 	ED_view3d_mats_rv3d_restore(ar->regiondata, rv3d_mats); | 
					
						
							|  |  |  | 	MEM_freeN(rv3d_mats); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-20 01:03:00 -02:00
										 |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_free_doc, | 
					
						
							|  |  |  | "free()\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   Free the offscreen object\n" | 
					
						
							|  |  |  | "   The framebuffer, texture and render objects will no longer be accessible.\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_free(BPy_GPUOffScreen *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_offscreen_free(self->ofs); | 
					
						
							|  |  |  | 	self->ofs = NULL; | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void BPy_GPUOffScreen__tp_dealloc(BPy_GPUOffScreen *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->ofs) | 
					
						
							|  |  |  | 		GPU_offscreen_free(self->ofs); | 
					
						
							|  |  |  | 	Py_TYPE(self)->tp_free((PyObject *)self); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef bpy_gpu_offscreen_getseters[] = { | 
					
						
							|  |  |  | 	{(char *)"color_texture", (getter)pygpu_offscreen_color_texture_get, (setter)NULL, pygpu_offscreen_color_texture_doc, NULL}, | 
					
						
							|  |  |  | 	{(char *)"width", (getter)pygpu_offscreen_width_get, (setter)NULL, pygpu_offscreen_width_doc, NULL}, | 
					
						
							|  |  |  | 	{(char *)"height", (getter)pygpu_offscreen_height_get, (setter)NULL, pygpu_offscreen_height_doc, NULL}, | 
					
						
							|  |  |  | 	{NULL, NULL, NULL, NULL, NULL}  /* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef bpy_gpu_offscreen_methods[] = { | 
					
						
							|  |  |  | 	{"bind", (PyCFunction)pygpu_offscreen_bind, METH_VARARGS | METH_KEYWORDS, pygpu_offscreen_bind_doc}, | 
					
						
							|  |  |  | 	{"unbind", (PyCFunction)pygpu_offscreen_unbind, METH_VARARGS | METH_KEYWORDS, pygpu_offscreen_unbind_doc}, | 
					
						
							|  |  |  | 	{"draw_view3d", (PyCFunction)pygpu_offscreen_draw_view3d, METH_VARARGS | METH_KEYWORDS, pygpu_offscreen_draw_view3d_doc}, | 
					
						
							|  |  |  | 	{"free", (PyCFunction)pygpu_offscreen_free, METH_NOARGS, pygpu_offscreen_free_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(py_gpu_offscreen_doc, | 
					
						
							|  |  |  | ".. class:: GPUOffscreen" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   This object gives access to off screen buffers.\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyTypeObject BPy_GPUOffScreen_Type = { | 
					
						
							|  |  |  | 	PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  | 	"GPUOffScreen",                              /* tp_name */ | 
					
						
							|  |  |  | 	sizeof(BPy_GPUOffScreen),                      /* tp_basicsize */ | 
					
						
							|  |  |  | 	0,                                           /* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)BPy_GPUOffScreen__tp_dealloc,      /* tp_dealloc */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_print */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_getattr */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_setattr */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_compare */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_repr */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_as_number */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_as_sequence */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_as_mapping */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_hash */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_call */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_str */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_getattro */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_setattro */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_as_buffer */ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,                          /* tp_flags */ | 
					
						
							|  |  |  | 	py_gpu_offscreen_doc,                        /* Documentation string */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_traverse */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_clear */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_richcompare */ | 
					
						
							|  |  |  | 	0,                                           /* tp_weaklistoffset */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_iter */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_iternext */ | 
					
						
							|  |  |  | 	bpy_gpu_offscreen_methods,                   /* tp_methods */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_members */ | 
					
						
							|  |  |  | 	bpy_gpu_offscreen_getseters,                 /* tp_getset */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_base */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_dict */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_descr_get */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_descr_set */ | 
					
						
							|  |  |  | 	0,                                           /* tp_dictoffset */ | 
					
						
							|  |  |  | 	0,                                           /* tp_init */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_alloc */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_new */ | 
					
						
							|  |  |  | 	(freefunc)0,                                 /* tp_free */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_is_gc */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_bases */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_mro */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_cache */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_subclasses */ | 
					
						
							|  |  |  | 	NULL,                                        /* tp_weaklist */ | 
					
						
							|  |  |  | 	(destructor) NULL                            /* tp_del */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* GPU offscreen methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *BPy_GPU_OffScreen_CreatePyObject(GPUOffScreen *ofs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_GPUOffScreen *self; | 
					
						
							|  |  |  | 	self = PyObject_New(BPy_GPUOffScreen, &BPy_GPUOffScreen_Type); | 
					
						
							|  |  |  | 	self->ofs = ofs; | 
					
						
							|  |  |  | 	return (PyObject *)self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pygpu_offscreen_new_doc, | 
					
						
							|  |  |  | "new(width, height, samples=0)\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   Return a GPUOffScreen.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "   :param width: Horizontal dimension of the buffer.\n" | 
					
						
							|  |  |  | "   :type width: int`\n" | 
					
						
							|  |  |  | "   :param height: Vertical dimension of the buffer.\n" | 
					
						
							|  |  |  | "   :type height: int`\n" | 
					
						
							|  |  |  | "   :param samples: OpenGL samples to use for MSAA or zero to disable.\n" | 
					
						
							|  |  |  | "   :type samples: int\n" | 
					
						
							|  |  |  | "   :return: Newly created off-screen buffer.\n" | 
					
						
							|  |  |  | "   :rtype: :class:`gpu.GPUOffscreen`\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyObject *pygpu_offscreen_new(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const char *kwlist[] = {"width", "height", "samples", NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPUOffScreen *ofs; | 
					
						
							|  |  |  | 	int width, height, samples = 0; | 
					
						
							|  |  |  | 	char err_out[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTupleAndKeywords( | 
					
						
							|  |  |  | 	        args, kwds, "ii|i:new", (char **)(kwlist), | 
					
						
							|  |  |  | 	        &width, &height, &samples)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ofs = GPU_offscreen_create(width, height, samples, err_out); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ofs == NULL) { | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  | 		             "gpu.offscreen.new(...) failed with '%s'", | 
					
						
							|  |  |  | 		             err_out[0] ? err_out : "unknown error"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return BPy_GPU_OffScreen_CreatePyObject(ofs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef BPy_GPU_offscreen_methods[] = { | 
					
						
							|  |  |  | 	{"new", (PyCFunction)pygpu_offscreen_new, METH_VARARGS | METH_KEYWORDS, pygpu_offscreen_new_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(BPy_GPU_offscreen_doc, | 
					
						
							|  |  |  | "This module provides access to offscreen rendering functions." | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | static PyModuleDef BPy_GPU_offscreen_module_def = { | 
					
						
							|  |  |  | 	PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  | 	"gpu.offscreen",                             /* m_name */ | 
					
						
							|  |  |  | 	BPy_GPU_offscreen_doc,                       /* m_doc */ | 
					
						
							|  |  |  | 	0,                                           /* m_size */ | 
					
						
							|  |  |  | 	BPy_GPU_offscreen_methods,                   /* m_methods */ | 
					
						
							|  |  |  | 	NULL,                                        /* m_reload */ | 
					
						
							|  |  |  | 	NULL,                                        /* m_traverse */ | 
					
						
							|  |  |  | 	NULL,                                        /* m_clear */ | 
					
						
							|  |  |  | 	NULL,                                        /* m_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPyInit_gpu_offscreen(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *submodule; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Register the 'GPUOffscreen' class */ | 
					
						
							|  |  |  | 	if (PyType_Ready(&BPy_GPUOffScreen_Type)) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	submodule = PyModule_Create(&BPy_GPU_offscreen_module_def); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MODULE_TYPE_ADD(s, t) \
 | 
					
						
							|  |  |  | 	PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MODULE_TYPE_ADD(submodule, BPy_GPUOffScreen_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef MODULE_TYPE_ADD
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return submodule; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_GPU_OFFSCREEN_CHECK_OBJ
 |