32 #include "../generic/py_capi_utils.h"
33 #include "../generic/python_utildefines.h"
34 #include "../mathutils/mathutils.h"
61 const char *error_prefix)
66 PyErr_Format(PyExc_ValueError,
"%s: uniform %.32s not found", error_prefix, name);
83 const char *vertexcode;
90 static const char *_keywords[] = {
91 "vertexcode",
"fragcode",
"geocode",
"libcode",
"defines",
NULL};
93 static _PyArg_Parser _parser = {
"ss|$sss:GPUShader.__new__", _keywords, 0};
94 if (!_PyArg_ParseTupleAndKeywordsFast(args,
109 PyErr_SetString(PyExc_Exception,
"Shader Compile Error, see console for more details");
117 pygpu_shader_bind_doc,
118 ".. method:: bind()\n"
120 " Bind the shader object. Required to be able to change uniforms of this shader.\n");
128 ".. method:: uniform_from_name(name)\n"
130 " Get uniform location by name.\n"
132 " :param name: Name of the uniform variable whose location is to be queried.\n"
134 " :return: Location of the uniform variable.\n"
138 const char *name = PyUnicode_AsUTF8(arg);
144 self->shader, name,
"GPUShader.get_uniform");
150 return PyLong_FromLong(uniform);
154 pygpu_shader_uniform_block_from_name_doc,
155 ".. method:: uniform_block_from_name(name)\n"
157 " Get uniform block location by name.\n"
159 " :param name: Name of the uniform block variable whose location is to be queried.\n"
161 " :return: The location of the uniform block variable.\n"
165 const char *name = PyUnicode_AsUTF8(arg);
173 PyErr_Format(PyExc_ValueError,
"GPUShader.get_uniform_block: uniform %.32s not found", name);
177 return PyLong_FromLong(uniform);
185 Py_buffer *r_pybuffer)
190 if (!PyArg_ParseTuple(
191 args,
"iOi|i:GPUShader.uniform_vector_*", r_location, &
buffer, r_length, r_count)) {
195 if (PyObject_GetBuffer(
buffer, r_pybuffer, PyBUF_SIMPLE) == -1) {
200 if (r_pybuffer->len != (*r_length * *r_count * elem_size)) {
201 PyErr_SetString(PyExc_BufferError,
"GPUShader.uniform_vector_*: buffer size does not match.");
209 ".. method:: uniform_vector_float(location, buffer, length, count)\n"
211 " Set the buffer to fill the uniform.\n"
213 " :param location: Location of the uniform variable to be modified.\n"
214 " :type location: int\n"
215 " :param buffer: The data that should be set. Can support the buffer protocol.\n"
216 " :type buffer: sequence of floats\n"
217 " :param length: Size of the uniform data type:\n\n"
219 " - 2: vec2 or float[2]\n"
220 " - 3: vec3 or float[3]\n"
221 " - 4: vec4 or float[4]\n"
224 " :type length: int\n"
225 " :param count: Specifies the number of elements, vector or matrices that are to "
227 " :type count: int\n");
235 args,
sizeof(
float), &location, &
length, &
count, &pybuffer)) {
241 PyBuffer_Release(&pybuffer);
247 ".. method:: uniform_vector_int(location, buffer, length, count)\n"
249 " See GPUShader.uniform_vector_float(...) description.\n");
257 args,
sizeof(
int), &location, &
length, &
count, &pybuffer)) {
263 PyBuffer_Release(&pybuffer);
269 ".. method:: uniform_bool(name, seq)\n"
271 " Specify the value of a uniform variable for the current program object.\n"
273 " :param name: Name of the uniform variable whose value is to be changed.\n"
275 " :param seq: Value that will be used to update the specified uniform variable.\n"
276 " :type seq: sequence of bools\n");
279 const char *error_prefix =
"GPUShader.uniform_bool";
286 if (!PyArg_ParseTuple(args,
"sO:GPUShader.uniform_bool", &
params.id, &
params.seq)) {
294 PyObject *seq_fast = PySequence_Fast(
params.seq, error_prefix);
295 if (seq_fast ==
NULL) {
296 PyErr_Format(PyExc_TypeError,
297 "%s: expected a sequence, got %s",
299 Py_TYPE(
params.seq)->tp_name);
303 length = PySequence_Fast_GET_SIZE(seq_fast);
305 PyErr_Format(PyExc_TypeError,
306 "%s: invalid sequence length. expected 1..4, got %d",
323 if (location == -1) {
333 ".. method:: uniform_float(name, value)\n"
335 " Specify the value of a uniform variable for the current program object.\n"
337 " :param name: Name of the uniform variable whose value is to be changed.\n"
339 " :param value: Value that will be used to update the specified uniform variable.\n"
340 " :type value: single number or sequence of numbers\n");
343 const char *error_prefix =
"GPUShader.uniform_float";
350 if (!PyArg_ParseTuple(args,
"sO:GPUShader.uniform_float", &
params.id, &
params.seq)) {
357 if (PyFloat_Check(
params.seq)) {
361 else if (PyLong_Check(
params.seq)) {
371 PyErr_SetString(PyExc_ValueError,
"Expected 3x3 or 4x4 matrix");
375 memcpy(values, mat->matrix,
sizeof(
float) *
length);
385 PyErr_SetString(PyExc_TypeError,
386 "Expected a single float or a sequence of floats of length 1..4, 9 or 16.");
392 if (location == -1) {
402 ".. method:: uniform_int(name, seq)\n"
404 " Specify the value of a uniform variable for the current program object.\n"
406 " :param name: name of the uniform variable whose value is to be changed.\n"
408 " :param seq: Value that will be used to update the specified uniform variable.\n"
409 " :type seq: sequence of numbers\n");
412 const char *error_prefix =
"GPUShader.uniform_int";
419 if (!PyArg_ParseTuple(args,
"sO:GPUShader.uniform_int", &
params.id, &
params.seq)) {
427 if (PyLong_Check(
params.seq)) {
428 values[0] = PyC_Long_AsI32(
params.seq);
433 PyObject *seq_fast = PySequence_Fast(
params.seq, error_prefix);
434 if (seq_fast ==
NULL) {
435 PyErr_Format(PyExc_TypeError,
436 "%s: expected a sequence, got %s",
438 Py_TYPE(
params.seq)->tp_name);
442 length = PySequence_Fast_GET_SIZE(seq_fast);
444 PyErr_Format(PyExc_TypeError,
445 "%s: invalid sequence length. expected 1..4, got %d",
462 if (location == -1) {
472 ".. method:: uniform_sampler(name, texture)\n"
474 " Specify the value of a texture uniform variable for the current GPUShader.\n"
476 " :param name: name of the uniform variable whose texture is to be specified.\n"
478 " :param texture: Texture to attach.\n"
479 " :type texture: :class:`gpu.types.GPUTexture`\n");
484 if (!PyArg_ParseTuple(
497 pygpu_shader_uniform_block_doc,
498 ".. method:: uniform_block(name, ubo)\n"
500 " Specify the value of an uniform buffer object variable for the current GPUShader.\n"
502 " :param name: name of the uniform variable whose UBO is to be specified.\n"
504 " :param ubo: Uniform Buffer to attach.\n"
505 " :type texture: :class:`gpu.types.GPUUniformBuf`\n");
510 if (!PyArg_ParseTuple(
519 "GPUShader.uniform_buffer: uniform block not found, make sure the name is correct");
530 pygpu_shader_attr_from_name_doc,
531 ".. method:: attr_from_name(name)\n"
533 " Get attribute location by name.\n"
535 " :param name: The name of the attribute variable whose location is to be queried.\n"
537 " :return: The location of an attribute variable.\n"
541 const char *name = PyUnicode_AsUTF8(arg);
549 PyErr_Format(PyExc_ValueError,
"GPUShader.attr_from_name: attribute %.32s not found", name);
553 return PyLong_FromLong(attr);
557 ".. method:: calc_format()\n"
559 " Build a new format based on the attributes of the shader.\n"
561 " :return: vertex attribute format for the shader\n"
562 " :rtype: :class:`gpu.types.GPUVertFormat`\n");
567 return (PyObject *)
ret;
572 {
"uniform_from_name",
575 pygpu_shader_uniform_from_name_doc},
576 {
"uniform_block_from_name",
579 pygpu_shader_uniform_block_from_name_doc},
580 {
"uniform_vector_float",
583 pygpu_shader_uniform_vector_float_doc},
584 {
"uniform_vector_int",
587 pygpu_shader_uniform_vector_int_doc},
591 pygpu_shader_uniform_bool_doc},
595 pygpu_shader_uniform_float_doc},
599 pygpu_shader_uniform_int_doc},
603 pygpu_shader_uniform_sampler_doc},
607 pygpu_shader_uniform_block_doc},
611 pygpu_shader_attr_from_name_doc},
615 pygpu_shader_calc_format_doc},
620 pygpu_shader_program_doc,
621 "The name of the program object for use by the OpenGL API (read-only).\n\n:type: int");
634 if (
self->is_builtin ==
false) {
637 Py_TYPE(
self)->tp_free((PyObject *)
self);
641 pygpu_shader__tp_doc,
642 ".. class:: GPUShader(vertexcode, fragcode, geocode=None, libcode=None, defines=None)\n"
644 " GPUShader combines multiple GLSL shaders into a program used for drawing.\n"
645 " It must contain a vertex and fragment shaders, with an optional geometry shader.\n"
647 " The GLSL ``#version`` directive is automatically included at the top of shaders,\n"
648 " and set to 330. Some preprocessor directives are automatically added according to\n"
649 " the Operating System or availability: ``GPU_ATI``, ``GPU_NVIDIA`` and ``GPU_INTEL``.\n"
651 " The following extensions are enabled by default if supported by the GPU:\n"
652 " ``GL_ARB_texture_gather``, ``GL_ARB_texture_cube_map_array``\n"
653 " and ``GL_ARB_shader_draw_parameters``.\n"
655 " For drawing user interface elements and gizmos, use\n"
656 " ``fragOutput = blender_srgb_to_framebuffer_space(fragOutput)``\n"
657 " to transform the output sRGB colors to the frame-buffer color-space.\n"
659 " :param vertexcode: Vertex shader code.\n"
660 " :type vertexcode: str\n"
661 " :param fragcode: Fragment shader code.\n"
662 " :type value: str\n"
663 " :param geocode: Geometry shader code.\n"
664 " :type value: str\n"
665 " :param libcode: Code with functions and presets to be shared between shaders.\n"
666 " :type value: str\n"
667 " :param defines: Preprocessor directives.\n"
668 " :type value: str\n");
670 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUShader",
673 .tp_flags = Py_TPFLAGS_DEFAULT,
674 .tp_doc = pygpu_shader__tp_doc,
687 ".. function:: unbind()\n"
689 " Unbind the bound shader object.\n");
697 ".. function:: from_builtin(pygpu_shader_name)\n"
699 " Shaders that are embedded in the blender internal code.\n"
700 " They all read the uniform ``mat4 ModelViewProjectionMatrix``,\n"
701 " which can be edited by the :mod:`gpu.matrix` module.\n"
702 " For more details, you can check the shader code with the\n"
703 " :func:`gpu.shader.code_from_builtin` function.\n"
705 " :param pygpu_shader_name: One of these builtin shader names:\n\n"
706 " - ``2D_UNIFORM_COLOR``\n"
707 " - ``2D_FLAT_COLOR``\n"
708 " - ``2D_SMOOTH_COLOR``\n"
710 " - ``3D_UNIFORM_COLOR``\n"
711 " - ``3D_FLAT_COLOR``\n"
712 " - ``3D_SMOOTH_COLOR``\n"
713 " :type pygpu_shader_name: str\n"
714 " :return: Shader object corresponding to the given name.\n"
715 " :rtype: :class:`bpy.types.GPUShader`\n");
731 ".. function:: code_from_builtin(pygpu_shader_name)\n"
733 " Exposes the internal shader code for query.\n"
735 " :param pygpu_shader_name: One of these builtin shader names:\n\n"
736 " - ``2D_UNIFORM_COLOR``\n"
737 " - ``2D_FLAT_COLOR``\n"
738 " - ``2D_SMOOTH_COLOR``\n"
740 " - ``3D_UNIFORM_COLOR``\n"
741 " - ``3D_FLAT_COLOR``\n"
742 " - ``3D_SMOOTH_COLOR``\n"
743 " :type pygpu_shader_name: str\n"
744 " :return: Vertex, fragment and geometry shader codes.\n"
753 PyObject *item, *r_dict;
761 pygpu_bultinshader.
value_found, &vert, &frag, &geom, &defines);
763 r_dict = PyDict_New();
765 PyDict_SetItemString(r_dict,
"vertex_shader", item = PyUnicode_FromString(vert));
768 PyDict_SetItemString(r_dict,
"fragment_shader", item = PyUnicode_FromString(frag));
772 PyDict_SetItemString(r_dict,
"geometry_shader", item = PyUnicode_FromString(geom));
776 PyDict_SetItemString(r_dict,
"defines", item = PyUnicode_FromString(defines));
787 pygpu_shader_from_builtin_doc},
788 {
"code_from_builtin",
791 pygpu_shader_code_from_builtin_doc},
796 "This module provides access to GPUShader internal functions.\n"
798 ".. rubric:: Built-in shaders\n"
800 "All built-in shaders have the ``mat4 ModelViewProjectionMatrix`` uniform.\n"
801 "The value of it can only be modified using the :class:`gpu.matrix` module.\n"
804 " :Attributes: vec3 pos\n"
805 " :Uniforms: vec4 color\n"
807 " :Attributes: vec3 pos, vec4 color\n"
810 " :Attributes: vec3 pos, vec4 color\n"
813 " :Attributes: vec3 pos, vec2 texCoord\n"
814 " :Uniforms: sampler2D image\n"
816 " :Attributes: vec3 pos\n"
817 " :Uniforms: vec4 color\n"
819 " :Attributes: vec3 pos, vec4 color\n"
822 " :Attributes: vec3 pos, vec4 color\n"
823 " :Uniforms: none\n");
825 PyModuleDef_HEAD_INIT,
826 .m_name =
"gpu.shader",
827 .m_doc = pygpu_shader_module__tp_doc,
843 self->is_builtin = is_builtin;
845 return (PyObject *)
self;
typedef float(TangentPoint)[2]
_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
void GPU_shader_unbind(void)
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
void GPU_shader_uniform_vector_int(GPUShader *shader, int location, int length, int arraysize, const int *value)
struct GPUShader GPUShader
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, const float *value)
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
GPUShader * GPU_shader_create_from_python(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines)
int GPU_shader_get_program(GPUShader *shader)
GPUShader * GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_get_builtin_shader_code(eGPUBuiltinShader shader, const char **r_vert, const char **r_frag, const char **r_geom, const char **r_defines)
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
@ GPU_SHADER_3D_SMOOTH_COLOR
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
@ GPU_SHADER_2D_SMOOTH_COLOR
@ GPU_SHADER_2D_UNIFORM_COLOR
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
@ GPU_SHADER_2D_FLAT_COLOR
int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
void GPU_shader_free(GPUShader *shader)
void GPU_texture_bind(GPUTexture *tex, int unit)
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
static PyObject * pygpu_shader_bind(BPyGPUShader *self)
static PyObject * pygpu_shader_from_builtin(PyObject *UNUSED(self), PyObject *arg)
static PyObject * pygpu_shader__tp_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
static PyObject * pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
static struct PyMethodDef pygpu_shader__tp_methods[]
static PyObject * pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args)
static PyObject * pygpu_shader_program_get(BPyGPUShader *self, void *UNUSED(closure))
static PyObject * pygpu_shader_uniform_block_from_name(BPyGPUShader *self, PyObject *arg)
static PyObject * pygpu_shader_uniform_block(BPyGPUShader *self, PyObject *args)
static PyObject * pygpu_shader_uniform_int(BPyGPUShader *self, PyObject *args)
PyTypeObject BPyGPUShader_Type
static struct PyMethodDef pygpu_shader_module__tp_methods[]
static PyObject * pygpu_shader_uniform_from_name(BPyGPUShader *self, PyObject *arg)
static PyObject * pygpu_shader_attr_from_name(BPyGPUShader *self, PyObject *arg)
static PyObject * pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args)
static PyObject * pygpu_shader_calc_format(BPyGPUShader *self, PyObject *UNUSED(arg))
static bool pygpu_shader_uniform_vector_impl(PyObject *args, int elem_size, int *r_location, int *r_length, int *r_count, Py_buffer *r_pybuffer)
static PyObject * pygpu_shader_uniform_vector_int(BPyGPUShader *self, PyObject *args)
static PyObject * pygpu_shader_uniform_vector_float(BPyGPUShader *self, PyObject *args)
static void pygpu_shader__tp_dealloc(BPyGPUShader *self)
static PyObject * pygpu_shader_unbind(BPyGPUShader *UNUSED(self))
PyObject * bpygpu_shader_init(void)
PyObject * BPyGPUShader_CreatePyObject(GPUShader *shader, bool is_builtin)
static PyModuleDef pygpu_shader_module_def
PyDoc_STRVAR(pygpu_shader_bind_doc, ".. method:: bind()\n" "\n" " Bind the shader object. Required to be able to change uniforms of this shader.\n")
static const struct PyC_StringEnumItems pygpu_shader_builtin_items[]
static PyGetSetDef pygpu_shader__tp_getseters[]
static PyObject * pygpu_shader_code_from_builtin(BPyGPUShader *UNUSED(self), PyObject *arg)
static int pygpu_shader_uniform_location_get(GPUShader *shader, const char *name, const char *error_prefix)
struct BPyGPUShader BPyGPUShader
PyTypeObject BPyGPUTexture_Type
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
#define BaseMath_ReadCallback(_self)
#define MatrixObject_Check(v)
int PyC_ParseStringEnum(PyObject *o, void *p)
int PyC_AsArray_FAST(void *array, PyObject *value_fast, const Py_ssize_t length, const PyTypeObject *type, const bool is_double, const char *error_prefix)
PyObject_HEAD struct GPUTexture * tex