51 #include "../mathutils/mathutils.h"
53 #include "../generic/py_capi_utils.h"
59 #define BPYGPU_USE_GPUOBJ_FREE_METHOD
68 PyErr_SetString(PyExc_ReferenceError,
70 "GPU offscreen was freed, no further access is valid"
72 "GPU offscreen: internal error"
80 #define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu) \
82 if (UNLIKELY(pygpu_offscreen_valid_check(bpygpu) == -1)) { \
106 Py_DECREF(
self->py_offscreen);
114 if (!
self->is_explicitly_bound) {
115 if (
self->level != -1) {
116 PyErr_SetString(PyExc_RuntimeError,
"Already in use");
132 if (
self->level == -1) {
133 PyErr_SetString(PyExc_RuntimeError,
"Not yet in use\n");
138 if (level !=
self->level) {
140 PyExc_RuntimeError,
"Level of bind mismatch, expected %d, got %d\n",
self->level, level);
154 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUFrameBufferStackContext",
157 .tp_flags = Py_TPFLAGS_DEFAULT,
162 ".. function:: bind()\n"
164 " Context manager to ensure balanced bind calls, even in the case of an error.\n");
169 ret->py_offscreen =
self;
171 ret->is_explicitly_bound =
false;
175 ret->is_explicitly_bound =
true;
177 return (PyObject *)
ret;
181 ".. method:: unbind(restore=True)\n"
183 " Unbind the offscreen object.\n"
185 " :arg restore: Restore the OpenGL state, can only be used when the state has been "
187 " :type restore: bool\n");
194 static const char *_keywords[] = {
"restore",
NULL};
195 static _PyArg_Parser _parser = {
"|O&:unbind", _keywords, 0};
196 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser,
PyC_ParseBool, &restore)) {
221 static const char *_keywords[] = {
"width",
"height",
NULL};
222 static _PyArg_Parser _parser = {
"ii:GPUOffScreen.__new__", _keywords, 0};
223 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &
width, &
height)) {
231 STRNCPY(err_out,
"No active GPU context found");
235 PyErr_Format(PyExc_RuntimeError,
236 "gpu.offscreen.new(...) failed with '%s'",
237 err_out[0] ? err_out :
"unknown error");
244 PyDoc_STRVAR(pygpu_offscreen_width_doc,
"Width of the texture.\n\n:type: `int`");
251 PyDoc_STRVAR(pygpu_offscreen_height_doc,
"Height of the texture.\n\n:type: `int`");
259 "OpenGL bindcode for the color texture.\n\n:type: `int`");
268 pygpu_offscreen_draw_view3d_doc,
269 ".. method:: draw_view3d(scene, view_layer, view3d, region, view_matrix, projection_matrix, do_color_management=False)\n"
271 " Draw the 3d viewport in the offscreen object.\n"
273 " :arg scene: Scene to draw.\n"
274 " :type scene: :class:`bpy.types.Scene`\n"
275 " :arg view_layer: View layer to draw.\n"
276 " :type view_layer: :class:`bpy.types.ViewLayer`\n"
277 " :arg view3d: 3D View to get the drawing settings from.\n"
278 " :type view3d: :class:`bpy.types.SpaceView3D`\n"
279 " :arg region: Region of the 3D View (required as temporary draw target).\n"
280 " :type region: :class:`bpy.types.Region`\n"
281 " :arg view_matrix: View Matrix (e.g. ``camera.matrix_world.inverted()``).\n"
282 " :type view_matrix: :class:`mathutils.Matrix`\n"
283 " :arg projection_matrix: Projection Matrix (e.g. ``camera.calc_matrix_camera(...)``).\n"
284 " :type projection_matrix: :class:`mathutils.Matrix`\n"
285 " :arg do_color_management: Color manage the output.\n"
286 " :type do_color_management: bool\n");
290 PyObject *py_scene, *py_view_layer, *py_region, *py_view3d;
298 bool do_color_management =
false;
302 static const char *_keywords[] = {
303 "scene",
"view_layer",
"view3d",
"region",
"view_matrix",
"projection_matrix",
"do_color_management",
NULL};
305 static _PyArg_Parser _parser = {
"OOOOO&O&|$O&:draw_view3d", _keywords, 0};
306 if (!_PyArg_ParseTupleAndKeywordsFast(args,
318 &do_color_management) ||
345 (
const float(*)[4])py_mat_view->matrix,
346 (
const float(*)[4])py_mat_projection->matrix,
364 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
366 ".. method:: free()\n"
368 " Free the offscreen object.\n"
369 " The framebuffer, texture and render objects will no longer be accessible.\n");
385 Py_TYPE(
self)->tp_free((PyObject *)
self);
392 pygpu_offscreen_color_texture_doc,
403 METH_VARARGS | METH_KEYWORDS,
404 pygpu_offscreen_unbind_doc},
407 METH_VARARGS | METH_KEYWORDS,
408 pygpu_offscreen_draw_view3d_doc},
409 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
416 ".. class:: GPUOffScreen(width, height)\n"
418 " This object gives access to off screen buffers.\n"
420 " :arg width: Horizontal dimension of the buffer.\n"
421 " :type width: int\n"
422 " :arg height: Vertical dimension of the buffer.\n"
423 " :type height: int\n");
425 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUOffScreen",
428 .tp_flags = Py_TPFLAGS_DEFAULT,
429 .tp_doc = pygpu_offscreen__tp_doc,
448 return (PyObject *)
self;
453 #undef BPY_GPU_OFFSCREEN_CHECK_OBJ
bool BKE_id_is_in_global_main(struct ID *id)
struct Depsgraph * BKE_scene_ensure_depsgraph(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer)
#define STRNCPY(dst, src)
struct Depsgraph Depsgraph
void ED_view3d_draw_offscreen(struct Depsgraph *depsgraph, const struct Scene *scene, eDrawType drawtype, struct View3D *v3d, struct ARegion *region, int winx, int winy, const float viewmat[4][4], const float winmat[4][4], bool is_image_render, bool draw_background, const char *viewname, const bool do_color_management, const bool restore_rv3d_mats, struct GPUOffScreen *ofs, struct GPUViewport *viewport)
GPUContext * GPU_context_active_get(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
void GPU_apply_state(void)
struct GPUTexture GPUTexture
int GPU_texture_opengl_bindcode(const GPUTexture *tex)
Read Guarded memory(de)allocation.
const Depsgraph * depsgraph
uint GPU_framebuffer_stack_level_get(void)
void GPU_offscreen_free(GPUOffScreen *ofs)
void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool depth, bool high_bitdepth, char err_out[256])
int GPU_offscreen_width(const GPUOffScreen *ofs)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
GPUTexture * GPU_offscreen_color_texture(const GPUOffScreen *ofs)
int GPU_offscreen_height(const GPUOffScreen *ofs)
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
static PyMethodDef pygpu_offscreen_stack_context__tp_methods[]
PyDoc_STRVAR(pygpu_offscreen_bind_doc, ".. function:: bind()\n" "\n" " Context manager to ensure balanced bind calls, even in the case of an error.\n")
#define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu)
#define BPYGPU_USE_GPUOBJ_FREE_METHOD
static PyObject * pygpu_offscreen__tp_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
static int pygpu_offscreen_valid_check(BPyGPUOffScreen *py_ofs)
static PyObject * pygpu_offscreen_stack_context_exit(OffScreenStackContext *self, PyObject *UNUSED(args))
static struct PyMethodDef pygpu_offscreen__tp_methods[]
static PyObject * pygpu_offscreen_width_get(BPyGPUOffScreen *self, void *UNUSED(type))
static void BPyGPUOffScreen__tp_dealloc(BPyGPUOffScreen *self)
static PyObject * pygpu_offscreen_unbind(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
PyTypeObject BPyGPUOffScreen_Type
static PyObject * pygpu_offscreen_bind(BPyGPUOffScreen *self)
static PyObject * pygpu_offscreen_stack_context_enter(OffScreenStackContext *self)
static PyObject * pygpu_offscreen_height_get(BPyGPUOffScreen *self, void *UNUSED(type))
static PyObject * pygpu_offscreen_free(BPyGPUOffScreen *self)
static PyTypeObject PyGPUOffscreenStackContext_Type
static void pygpu_offscreen_stack_context__tp_dealloc(OffScreenStackContext *self)
static PyObject * pygpu_offscreen_color_texture_get(BPyGPUOffScreen *self, void *UNUSED(type))
static PyGetSetDef pygpu_offscreen__tp_getseters[]
PyObject * BPyGPUOffScreen_CreatePyObject(GPUOffScreen *ofs)
static PyObject * pygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
struct BPyGPUOffScreen BPyGPUOffScreen
int Matrix_Parse4x4(PyObject *o, void *p)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_ParseBool(PyObject *o, void *p)
PyObject_HEAD struct GPUOffScreen * ofs
PyObject_HEAD BPyGPUOffScreen * py_offscreen