44#define BPYGPU_USE_GPUOBJ_FREE_METHOD
61 PyErr_SetString(PyExc_ReferenceError,
63 "GPU offscreen was freed, no further access is valid"
65 "GPU offscreen: internal error"
73#define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu) \
75 if (UNLIKELY(pygpu_offscreen_valid_check(bpygpu) == -1)) { \
99 Py_DECREF(
self->py_offscreen);
109 if (!
self->is_explicitly_bound) {
110 if (
self->level != -1) {
111 PyErr_SetString(PyExc_RuntimeError,
"Already in use");
129 if (
self->level == -1) {
130 PyErr_SetString(PyExc_RuntimeError,
"Not yet in use\n");
135 if (level !=
self->level) {
137 PyExc_RuntimeError,
"Level of bind mismatch, expected %d, got %d\n",
self->level, level);
146# pragma clang diagnostic push
147# pragma clang diagnostic ignored "-Wcast-function-type"
149# pragma GCC diagnostic push
150# pragma GCC diagnostic ignored "-Wcast-function-type"
162# pragma clang diagnostic pop
164# pragma GCC diagnostic pop
169 PyVarObject_HEAD_INIT(
nullptr, 0)
170 "GPUFrameBufferStackContext",
222 pygpu_offscreen_bind_doc,
223 ".. function:: bind()\n"
225 " Context manager to ensure balanced bind calls, even in the case of an error.\n");
232 ret->is_explicitly_bound =
false;
236 ret->is_explicitly_bound =
true;
238 return (PyObject *)
ret;
243 pygpu_offscreen_unbind_doc,
244 ".. method:: unbind(restore=True)\n"
246 " Unbind the offscreen object.\n"
248 " :arg restore: Restore the OpenGL state, can only be used when the state has been "
250 " :type restore: bool\n");
257 static const char *_keywords[] = {
"restore",
nullptr};
258 static _PyArg_Parser _parser = {
266 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser,
PyC_ParseBool, &restore)) {
290 static const char *_keywords[] = {
"width",
"height",
"format",
nullptr};
291 static _PyArg_Parser _parser = {
297 ":GPUOffScreen.__new__",
301 if (!_PyArg_ParseTupleAndKeywordsFast(
317 STRNCPY(err_out,
"No active GPU context found");
320 if (ofs ==
nullptr) {
321 PyErr_Format(PyExc_RuntimeError,
322 "gpu.offscreen.new(...) failed with '%s'",
323 err_out[0] ? err_out :
"unknown error");
332 pygpu_offscreen_width_doc,
333 "Width of the texture.\n"
344 pygpu_offscreen_height_doc,
345 "Height of the texture.\n"
356 pygpu_offscreen_color_texture_doc,
357 "OpenGL bindcode for the color texture.\n"
369 pygpu_offscreen_texture_color_doc,
370 "The color texture attached.\n"
372 ":type: :class:`gpu.types.GPUTexture`");
382 pygpu_offscreen_draw_view3d_doc,
383 ".. method:: draw_view3d(scene, view_layer, view3d, region, view_matrix, projection_matrix, "
384 "do_color_management=False, draw_background=True)\n"
386 " Draw the 3d viewport in the offscreen object.\n"
388 " :arg scene: Scene to draw.\n"
389 " :type scene: :class:`bpy.types.Scene`\n"
390 " :arg view_layer: View layer to draw.\n"
391 " :type view_layer: :class:`bpy.types.ViewLayer`\n"
392 " :arg view3d: 3D View to get the drawing settings from.\n"
393 " :type view3d: :class:`bpy.types.SpaceView3D`\n"
394 " :arg region: Region of the 3D View (required as temporary draw target).\n"
395 " :type region: :class:`bpy.types.Region`\n"
396 " :arg view_matrix: View Matrix (e.g. ``camera.matrix_world.inverted()``).\n"
397 " :type view_matrix: :class:`mathutils.Matrix`\n"
398 " :arg projection_matrix: Projection Matrix (e.g. ``camera.calc_matrix_camera(...)``).\n"
399 " :type projection_matrix: :class:`mathutils.Matrix`\n"
400 " :arg do_color_management: Color manage the output.\n"
401 " :type do_color_management: bool\n"
402 " :arg draw_background: Draw background.\n"
403 " :type draw_background: bool\n");
407 PyObject *py_scene, *py_view_layer, *py_region, *py_view3d;
415 bool do_color_management =
false;
420 static const char *_keywords[] = {
427 "do_color_management",
431 static _PyArg_Parser _parser = {
446 if (!_PyArg_ParseTupleAndKeywordsFast(args,
458 &do_color_management,
472 PyErr_SetString(PyExc_RuntimeError,
"Nested off-screen drawing not supported");
490 if (!
self->viewport) {
504 (
const float(*)[4])py_mat_view->matrix,
505 (
const float(*)[4])py_mat_projection->matrix,
523#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
526 pygpu_offscreen_free_doc,
527 ".. method:: free()\n"
529 " Free the offscreen object.\n"
530 " The framebuffer, texture and render objects will no longer be accessible.\n");
535 if (
self->viewport) {
537 self->viewport =
nullptr;
548 if (
self->viewport) {
554 Py_TYPE(
self)->tp_free((PyObject *)
self);
561 pygpu_offscreen_color_texture_doc,
566 pygpu_offscreen_texture_color_doc,
571 pygpu_offscreen_width_doc,
576 pygpu_offscreen_height_doc,
578 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
583# pragma clang diagnostic push
584# pragma clang diagnostic ignored "-Wcast-function-type"
586# pragma GCC diagnostic push
587# pragma GCC diagnostic ignored "-Wcast-function-type"
595 METH_VARARGS | METH_KEYWORDS,
596 pygpu_offscreen_unbind_doc},
599 METH_VARARGS | METH_KEYWORDS,
600 pygpu_offscreen_draw_view3d_doc},
601#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
604 {
nullptr,
nullptr, 0,
nullptr},
609# pragma clang diagnostic pop
611# pragma GCC diagnostic pop
617 pygpu_offscreen__tp_doc,
618 ".. class:: GPUOffScreen(width, height, *, format='RGBA8')\n"
620 " This object gives access to off screen buffers.\n"
622 " :arg width: Horizontal dimension of the buffer.\n"
623 " :type width: int\n"
624 " :arg height: Vertical dimension of the buffer.\n"
625 " :type height: int\n"
626 " :arg format: Internal data format inside GPU memory for color attachment "
627 "texture. Possible values are:\n"
632 " :type format: str\n");
634 PyVarObject_HEAD_INIT(
nullptr, 0)
654 pygpu_offscreen__tp_doc,
697 self->viewport =
nullptr;
699 return (PyObject *)
self;
704#undef BPY_GPU_OFFSCREEN_CHECK_OBJ
bool BKE_id_is_in_global_main(ID *id)
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
char * STRNCPY(char(&dst)[N], const char *src)
bool ED_view3d_draw_offscreen_check_nested()
void ED_view3d_draw_offscreen(Depsgraph *depsgraph, const Scene *scene, eDrawType drawtype, View3D *v3d, 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, bool do_color_management, bool restore_rv3d_mats, GPUOffScreen *ofs, GPUViewport *viewport)
GPUContext * GPU_context_active_get()
int GPU_offscreen_width(const GPUOffScreen *offscreen)
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
uint GPU_framebuffer_stack_level_get()
int GPU_offscreen_height(const GPUOffScreen *offscreen)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool with_depth_buffer, eGPUTextureFormat format, eGPUTextureUsage usage, bool clear, char err_out[256])
GPUTexture * GPU_offscreen_color_texture(const GPUOffScreen *offscreen)
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
int GPU_texture_opengl_bindcode(const GPUTexture *texture)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_HOST_READ
GPUViewport * GPU_viewport_create()
void GPU_viewport_free(GPUViewport *viewport)
void GPU_viewport_tag_update(GPUViewport *viewport)
BPy_StructRNA * depsgraph
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
static PyMethodDef pygpu_offscreen_stack_context__tp_methods[]
static PyObject * pygpu_offscreen_color_texture_get(BPyGPUOffScreen *self, void *)
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")
PyObject * BPyGPUOffScreen_CreatePyObject(GPUOffScreen *ofs)
#define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu)
static PyMethodDef pygpu_offscreen__tp_methods[]
#define BPYGPU_USE_GPUOBJ_FREE_METHOD
static int pygpu_offscreen_valid_check(BPyGPUOffScreen *py_ofs)
static void BPyGPUOffScreen__tp_dealloc(BPyGPUOffScreen *self)
static PyObject * pygpu_offscreen_texture_color_get(BPyGPUOffScreen *self, void *)
PyTypeObject BPyGPUOffScreen_Type
static PyObject * pygpu_offscreen_width_get(BPyGPUOffScreen *self, void *)
static PyObject * pygpu_offscreen__tp_new(PyTypeObject *, PyObject *args, PyObject *kwds)
static PyObject * pygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
static PyObject * pygpu_offscreen_bind(BPyGPUOffScreen *self)
static PyTypeObject PyGPUOffscreenStackContext_Type
static void pygpu_offscreen_stack_context__tp_dealloc(OffScreenStackContext *self)
static PyObject * pygpu_offscreen_unbind(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
static PyObject * pygpu_offscreen_free(BPyGPUOffScreen *self)
static PyObject * pygpu_offscreen_height_get(BPyGPUOffScreen *self, void *)
static PyGetSetDef pygpu_offscreen__tp_getseters[]
static const PyC_StringEnumItems pygpu_framebuffer_color_texture_formats[]
static PyObject * pygpu_offscreen_stack_context_enter(OffScreenStackContext *self)
static PyObject * pygpu_offscreen_stack_context_exit(OffScreenStackContext *self, PyObject *)
PyObject * BPyGPUTexture_CreatePyObject(GPUTexture *tex, bool shared_reference)
int Matrix_Parse4x4(PyObject *o, void *p)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_ParseStringEnum(PyObject *o, void *p)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
PyObject_HEAD GPUOffScreen * ofs
PyObject_HEAD BPyGPUOffScreen * py_offscreen
static void draw_background(const rcti *rect)