37 if (!
self->batch->shader) {
38 PyErr_SetString(PyExc_RuntimeError,
"batch does not have any program assigned to it");
54 const char *exc_str_missing_arg =
"GPUBatch.__new__() missing required argument '%s' (pos %d)";
60 static const char *_keywords[] = {
"type",
"buf",
"elem",
nullptr};
61 static _PyArg_Parser _parser = {
71 if (!_PyArg_ParseTupleAndKeywordsFast(args,
86 PyErr_WarnEx(PyExc_DeprecationWarning,
87 "'LINE_LOOP' is deprecated. Please use 'LINE_STRIP' and close the segment.",
92 PyExc_DeprecationWarning,
93 "'TRI_FAN' is deprecated. Please use 'TRI_STRIP' or 'TRIS' and try modifying your "
94 "vertices or indices to match the topology.",
98 if (py_vertbuf ==
nullptr) {
99 PyErr_Format(PyExc_TypeError, exc_str_missing_arg, _keywords[1], 2);
105 py_indexbuf ? py_indexbuf->
elem :
nullptr);
109#ifdef USE_GPU_PY_REFERENCES
111 PyList_SET_ITEM(
ret->references, 0, (PyObject *)py_vertbuf);
112 Py_INCREF(py_vertbuf);
114 if (py_indexbuf !=
nullptr) {
115 PyList_SET_ITEM(
ret->references, 1, (PyObject *)py_indexbuf);
116 Py_INCREF(py_indexbuf);
120 PyObject_GC_Track(
ret);
123 return (PyObject *)
ret;
128 pygpu_batch_vertbuf_add_doc,
".. method:: vertbuf_add(buf)\n"
130" Add another vertex buffer to the Batch.\n"
131" It is not possible to add more vertices to the batch using this method.\n"
132" Instead it can be used to add more attributes to the existing vertices.\n"
133" A good use case would be when you have a separate\n"
134" vertex buffer for vertex positions and vertex normals.\n"
137" :arg buf: The vertex buffer that will be added to the batch.\n"
138" :type buf: :class:`gpu.types.GPUVertBuf`\n"
143 PyErr_Format(PyExc_TypeError,
"Expected a GPUVertBuf, got %s", Py_TYPE(py_buf)->tp_name);
149 PyErr_Format(PyExc_TypeError,
150 "Expected %d length, got %d",
163#ifdef USE_GPU_PY_REFERENCES
165 PyList_Append(
self->references, (PyObject *)py_buf);
174 pygpu_batch_program_set_doc,
175 ".. method:: program_set(program)\n"
177 " Assign a shader to this batch that will be used for drawing when not overwritten later.\n"
178 " Note: This method has to be called in the draw context that the batch will be drawn in.\n"
179 " This function does not need to be called when you always\n"
180 " set the shader when calling :meth:`gpu.types.GPUBatch.draw`.\n"
182 " :arg program: The program/shader the batch will use in future draw calls.\n"
183 " :type program: :class:`gpu.types.GPUShader`\n");
186 static bool deprecation_warning_issued =
false;
189 if (!deprecation_warning_issued) {
190 PyErr_WarnEx(PyExc_DeprecationWarning,
191 "Calls to GPUBatch.program_set are deprecated."
192 "Please set the shader via the 'program' parameter when calling "
193 "GPUBatch.draw/draw_instanced/draw_range.",
195 deprecation_warning_issued =
true;
199 PyErr_Format(PyExc_TypeError,
"Expected a GPUShader, got %s", Py_TYPE(py_shader)->tp_name);
206#ifdef USE_GPU_PY_REFERENCES
208 int i = PyList_GET_SIZE(
self->references);
210 PyObject *py_shader_test = PyList_GET_ITEM(
self->references, i);
212 PyList_SET_ITEM(
self->references, i, (PyObject *)py_shader);
213 Py_INCREF(py_shader);
214 Py_DECREF(py_shader_test);
220 PyList_Append(
self->references, (PyObject *)py_shader);
229 pygpu_batch_draw_doc,
230 ".. method:: draw(program=None)\n"
232 " Run the drawing program with the parameters assigned to the batch.\n"
234 " :arg program: Program that performs the drawing operations.\n"
235 " If ``None`` is passed, the last program set to this batch will run.\n"
236 " :type program: :class:`gpu.types.GPUShader`\n");
239 static bool deprecation_warning_issued =
false;
243 if (!PyArg_ParseTuple(args,
"|O!:GPUBatch.draw", &
BPyGPUShader_Type, &py_program)) {
246 if (py_program ==
nullptr) {
248 if (!deprecation_warning_issued) {
251 PyErr_WarnEx(PyExc_DeprecationWarning,
252 "Calling GPUBatch.draw without specifying a program is deprecated. "
253 "Please provide a valid GPUShader as the 'program' parameter.",
255 deprecation_warning_issued =
true;
262 else if (
self->batch->shader != py_program->
shader) {
272 pygpu_batch_draw_instanced_doc,
273 ".. method:: draw_instanced(program, *, instance_start=0, instance_count=0)\n"
275 " Draw multiple instances of the drawing program with the parameters assigned\n"
276 " to the batch. In the vertex shader, `gl_InstanceID` will contain the instance\n"
277 " number being drawn.\n"
279 " :arg program: Program that performs the drawing operations.\n"
280 " :type program: :class:`gpu.types.GPUShader`\n"
281 " :arg instance_start: Number of the first instance to draw.\n"
282 " :type instance_start: int\n"
283 " :arg instance_count: Number of instances to draw. When not provided or set to 0\n"
284 " the number of instances will be determined by the number of rows in the first\n"
286 " :type instance_count: int\n");
290 int instance_start = 0;
291 int instance_count = 0;
293 static const char *_keywords[] = {
"program",
"instance_start",
"instance_count",
nullptr};
294 static _PyArg_Parser _parser = {
300 ":GPUBatch.draw_instanced",
304 if (!_PyArg_ParseTupleAndKeywordsFast(
305 args, kw, &_parser, &
BPyGPUShader_Type, &py_program, &instance_start, &instance_count))
317 pygpu_batch_draw_range_doc,
318 ".. method:: draw_range(program, *, elem_start=0, elem_count=0)\n"
320 " Run the drawing program with the parameters assigned to the batch. "
321 "Only draw the ``elem_count`` elements of the index buffer starting at ``elem_start``.\n"
323 " :arg program: Program that performs the drawing operations.\n"
324 " :type program: :class:`gpu.types.GPUShader`\n"
325 " :arg elem_start: First index to draw. When not provided or set to 0 drawing\n"
326 " will start from the first element of the index buffer.\n"
327 " :type elem_start: int\n"
328 " :arg elem_count: Number of elements of the index buffer to draw. When not\n"
329 " provided or set to 0 all elements from ``elem_start`` to the end of the\n"
330 " index buffer will be drawn.\n"
331 " :type elem_count: int\n");
338 static const char *_keywords[] = {
"program",
"elem_start",
"elem_count",
nullptr};
339 static _PyArg_Parser _parser = {
345 ":GPUBatch.draw_range",
349 if (!_PyArg_ParseTupleAndKeywordsFast(
378#if (defined(__GNUC__) && !defined(__clang__))
379# pragma GCC diagnostic push
380# pragma GCC diagnostic ignored "-Wcast-function-type"
386 {
"draw", (PyCFunction)
pygpu_batch_draw, METH_VARARGS, pygpu_batch_draw_doc},
389 METH_VARARGS | METH_KEYWORDS,
390 pygpu_batch_draw_instanced_doc},
393 METH_VARARGS | METH_KEYWORDS,
394 pygpu_batch_draw_range_doc},
397 {
nullptr,
nullptr, 0,
nullptr},
400#if (defined(__GNUC__) && !defined(__clang__))
401# pragma GCC diagnostic pop
404#ifdef USE_GPU_PY_REFERENCES
408 Py_VISIT(
self->references);
414 Py_CLEAR(
self->references);
420 return self->references !=
nullptr;
429#ifdef USE_GPU_PY_REFERENCES
430 PyObject_GC_UnTrack(
self);
431 if (
self->references) {
433 Py_XDECREF(
self->references);
443 ".. class:: GPUBatch(type, buf, elem=None)\n"
445 " Reusable container for drawable geometry.\n"
447 " :arg type: The primitive type of geometry to be drawn.\n"
448 " Possible values are `POINTS`, `LINES`, `TRIS`, `LINE_STRIP`, `LINE_LOOP`, `TRI_STRIP`, "
449 "`TRI_FAN`, `LINES_ADJ`, `TRIS_ADJ` and `LINE_STRIP_ADJ`.\n"
451 " :arg buf: Vertex buffer containing all or some of the attributes required for drawing.\n"
452 " :type buf: :class:`gpu.types.GPUVertBuf`\n"
453 " :arg elem: An optional index buffer.\n"
454 " :type elem: :class:`gpu.types.GPUIndexBuf`\n");
456 PyVarObject_HEAD_INIT(
nullptr, 0)
475#ifdef USE_GPU_PY_REFERENCES
476 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
481#ifdef USE_GPU_PY_REFERENCES
507#ifdef USE_GPU_PY_REFERENCES
533#ifdef USE_GPU_PY_REFERENCES
542 return (PyObject *)
self;
547#undef BPY_GPU_BATCH_CHECK_OBJ
void GPU_batch_discard(blender::gpu::Batch *batch)
#define GPU_batch_create(primitive_type, vertex_buf, index_buf)
void GPU_batch_draw_instance_range(blender::gpu::Batch *batch, int instance_first, int instance_count)
int GPU_batch_vertbuf_add(blender::gpu::Batch *batch, blender::gpu::VertBuf *vertex_buf, bool own_vbo)
#define GPU_BATCH_VBO_MAX_LEN
void GPU_batch_set_shader(blender::gpu::Batch *batch, GPUShader *shader)
void GPU_batch_draw(blender::gpu::Batch *batch)
void GPU_batch_draw_range(blender::gpu::Batch *batch, int vertex_first, int vertex_count)
void GPU_shader_bind(GPUShader *shader)
uint GPU_vertbuf_get_vertex_len(const blender::gpu::VertBuf *verts)
struct GPUShader GPUShader
PyC_StringEnumItems bpygpu_primtype_items[]
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
static PyObject * pygpu_batch_draw(BPyGPUBatch *self, PyObject *args)
static int pygpu_batch__tp_clear(BPyGPUBatch *self)
PyObject * BPyGPUBatch_CreatePyObject(blender::gpu::Batch *batch)
static PyObject * pygpu_batch_program_use_begin(BPyGPUBatch *self)
static int pygpu_batch__tp_traverse(BPyGPUBatch *self, visitproc visit, void *arg)
static PyObject * pygpu_batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_shader)
static PyObject * pygpu_batch__tp_new(PyTypeObject *, PyObject *args, PyObject *kwds)
static PyObject * pygpu_batch_program_use_end(BPyGPUBatch *self)
static void pygpu_batch__tp_dealloc(BPyGPUBatch *self)
static bool pygpu_batch_is_program_or_error(BPyGPUBatch *self)
static PyObject * pygpu_batch_draw_instanced(BPyGPUBatch *self, PyObject *args, PyObject *kw)
static PyMethodDef pygpu_batch__tp_methods[]
static PyObject * pygpu_batch_draw_range(BPyGPUBatch *self, PyObject *args, PyObject *kw)
static int pygpu_batch__tp_is_gc(BPyGPUBatch *self)
PyTypeObject BPyGPUBatch_Type
PyDoc_STRVAR(pygpu_batch_vertbuf_add_doc, ".. method:: vertbuf_add(buf)\n" "\n" " Add another vertex buffer to the Batch.\n" " It is not possible to add more vertices to the batch using this method.\n" " Instead it can be used to add more attributes to the existing vertices.\n" " A good use case would be when you have a separate\n" " vertex buffer for vertex positions and vertex normals.\n" " Current a batch can have at most " STRINGIFY(GPU_BATCH_VBO_MAX_LEN) " vertex buffers.\n" "\n" " :arg buf: The vertex buffer that will be added to the batch.\n" " :type buf: :class:`gpu.types.GPUVertBuf`\n")
static PyObject * pygpu_batch_vertbuf_add(BPyGPUBatch *self, BPyGPUVertBuf *py_buf)
#define USE_GPU_PY_REFERENCES
PyTypeObject BPyGPUIndexBuf_Type
PyTypeObject BPyGPUShader_Type
#define BPyGPUShader_Check(v)
PyTypeObject BPyGPUVertBuf_Type
#define BPyGPUVertBuf_Check(v)
int PyC_ParseStringEnum(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
PyObject_VAR_HEAD blender::gpu::IndexBuf * elem
PyObject_VAR_HEAD struct GPUShader * shader
PyObject_VAR_HEAD blender::gpu::VertBuf * buf