44#define BPYGPU_USE_GPUOBJ_FREE_METHOD
51 {int(blender::gpu::TextureFormat::UNORM_8_8_8_8),
"RGBA8"},
52 {int(blender::gpu::TextureFormat::UNORM_16_16_16_16),
"RGBA16"},
53 {int(blender::gpu::TextureFormat::SFLOAT_16_16_16_16),
"RGBA16F"},
54 {int(blender::gpu::TextureFormat::SFLOAT_32_32_32_32),
"RGBA32F"},
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)) { \
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)) {
288 int(blender::gpu::TextureFormat::UNORM_8_8_8_8)};
291 static const char *_keywords[] = {
"width",
"height",
"format",
nullptr};
292 static _PyArg_Parser _parser = {
298 ":GPUOffScreen.__new__",
302 if (!_PyArg_ParseTupleAndKeywordsFast(
321 if (ofs ==
nullptr) {
322 PyErr_Format(PyExc_RuntimeError,
323 "gpu.offscreen.new(...) failed with '%s'",
324 err_out[0] ? err_out :
"unknown error");
333 pygpu_offscreen_width_doc,
334 "Width of the texture.\n"
345 pygpu_offscreen_height_doc,
346 "Height of the texture.\n"
357 pygpu_offscreen_texture_color_doc,
358 "The color texture attached.\n"
360 ":type: :class:`gpu.types.GPUTexture`\n");
370 pygpu_offscreen_draw_view3d_doc,
371 ".. method:: draw_view3d(scene, view_layer, view3d, region, view_matrix, projection_matrix, "
372 "*, do_color_management=False, draw_background=True)\n"
374 " Draw the 3d viewport in the offscreen object.\n"
376 " :arg scene: Scene to draw.\n"
377 " :type scene: :class:`bpy.types.Scene`\n"
378 " :arg view_layer: View layer to draw.\n"
379 " :type view_layer: :class:`bpy.types.ViewLayer`\n"
380 " :arg view3d: 3D View to get the drawing settings from.\n"
381 " :type view3d: :class:`bpy.types.SpaceView3D`\n"
382 " :arg region: Region of the 3D View (required as temporary draw target).\n"
383 " :type region: :class:`bpy.types.Region`\n"
384 " :arg view_matrix: View Matrix (e.g. ``camera.matrix_world.inverted()``).\n"
385 " :type view_matrix: :class:`mathutils.Matrix`\n"
386 " :arg projection_matrix: Projection Matrix (e.g. ``camera.calc_matrix_camera(...)``).\n"
387 " :type projection_matrix: :class:`mathutils.Matrix`\n"
388 " :arg do_color_management: Color manage the output.\n"
389 " :type do_color_management: bool\n"
390 " :arg draw_background: Draw background.\n"
391 " :type draw_background: bool\n");
395 PyObject *py_scene, *py_view_layer, *py_region, *py_view3d;
403 bool do_color_management =
false;
408 static const char *_keywords[] = {
415 "do_color_management",
419 static _PyArg_Parser _parser = {
434 if (!_PyArg_ParseTupleAndKeywordsFast(args,
446 &do_color_management,
460 PyErr_SetString(PyExc_RuntimeError,
"Nested off-screen drawing not supported");
472 if (!
self->viewport) {
486 (
const float (*)[4])py_mat_view->matrix,
487 (
const float (*)[4])py_mat_projection->matrix,
501#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
504 pygpu_offscreen_free_doc,
505 ".. method:: free()\n"
507 " Free the offscreen object.\n"
508 " The framebuffer, texture and render objects will no longer be accessible.\n");
513 if (
self->viewport) {
515 self->viewport =
nullptr;
526 if (
self->viewport) {
532 Py_TYPE(
self)->tp_free((PyObject *)
self);
539 pygpu_offscreen_texture_color_doc,
544 pygpu_offscreen_width_doc,
549 pygpu_offscreen_height_doc,
551 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
556# pragma clang diagnostic push
557# pragma clang diagnostic ignored "-Wcast-function-type"
559# pragma GCC diagnostic push
560# pragma GCC diagnostic ignored "-Wcast-function-type"
568 METH_VARARGS | METH_KEYWORDS,
569 pygpu_offscreen_unbind_doc},
572 METH_VARARGS | METH_KEYWORDS,
573 pygpu_offscreen_draw_view3d_doc},
574#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
577 {
nullptr,
nullptr, 0,
nullptr},
582# pragma clang diagnostic pop
584# pragma GCC diagnostic pop
590 pygpu_offscreen__tp_doc,
591 ".. class:: GPUOffScreen(width, height, *, format='RGBA8')\n"
593 " This object gives access to off screen buffers.\n"
595 " :arg width: Horizontal dimension of the buffer.\n"
596 " :type width: int\n"
597 " :arg height: Vertical dimension of the buffer.\n"
598 " :type height: int\n"
599 " :arg format: Internal data format inside GPU memory for color attachment "
600 "texture. Possible values are:\n"
605 " :type format: str\n");
607 PyVarObject_HEAD_INIT(
nullptr, 0)
627 pygpu_offscreen__tp_doc,
670 self->viewport =
nullptr;
672 return (PyObject *)
self;
677#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)
#define STRNCPY_UTF8(dst, 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()
blender::gpu::Texture * GPU_offscreen_color_texture(const GPUOffScreen *offscreen)
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, blender::gpu::TextureFormat format, eGPUTextureUsage usage, bool clear, char err_out[256])
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
@ 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
#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")
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(blender::gpu::Texture *tex, bool shared_reference)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
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)