Changeset View
Changeset View
Standalone View
Standalone View
source/blender/python/gpu/gpu_py_shader.c
| Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
| }; | }; | ||||
| static const struct PyC_StringEnumItems pygpu_shader_config_items[] = { | static const struct PyC_StringEnumItems pygpu_shader_config_items[] = { | ||||
| {GPU_SHADER_CFG_DEFAULT, "DEFAULT"}, | {GPU_SHADER_CFG_DEFAULT, "DEFAULT"}, | ||||
| {GPU_SHADER_CFG_CLIPPED, "CLIPPED"}, | {GPU_SHADER_CFG_CLIPPED, "CLIPPED"}, | ||||
| {0, NULL}, | {0, NULL}, | ||||
| }; | }; | ||||
| static const struct PyC_StringEnumItems pygpu_samplerstate_filter_items[] = { | |||||
| {0, "NEAREST"}, | |||||
| {1, "LINEAR"}, | |||||
| {2, "ANISOTROPIC"}, | |||||
fclem: I think it wouldn't hurt to have the full name here. | |||||
| {0, NULL}, | |||||
| }; | |||||
| static int pygpu_shader_uniform_location_get(GPUShader *shader, | static int pygpu_shader_uniform_location_get(GPUShader *shader, | ||||
| const char *name, | const char *name, | ||||
| const char *error_prefix) | const char *error_prefix) | ||||
| { | { | ||||
| const int uniform = GPU_shader_get_uniform(shader, name); | const int uniform = GPU_shader_get_uniform(shader, name); | ||||
| if (uniform == -1) { | if (uniform == -1) { | ||||
| PyErr_Format(PyExc_ValueError, "%s: uniform %.32s not found", error_prefix, name); | PyErr_Format(PyExc_ValueError, "%s: uniform %.32s not found", error_prefix, name); | ||||
| ▲ Show 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | if (location == -1) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); | GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); | ||||
| Py_RETURN_NONE; | Py_RETURN_NONE; | ||||
| } | } | ||||
| PyDoc_STRVAR(pygpu_shader_uniform_sampler_doc, | PyDoc_STRVAR( | ||||
| ".. method:: uniform_sampler(name, texture)\n" | pygpu_shader_uniform_sampler_doc, | ||||
| ".. method:: uniform_sampler(name, texture, " | |||||
| "filter='NEAREST', " | |||||
| "repeat=[False, False, False], " | |||||
| "use_mipmap=False, " | |||||
| "clamp_to_border_color=False, " | |||||
| "compare_enabled=False)\n" | |||||
| "\n" | "\n" | ||||
| " Specify the value of a texture uniform variable for the current GPUShader.\n" | " Specify the texture and state for an uniform sampler in the current GPUShader.\n" | ||||
| "\n" | "\n" | ||||
| " :param name: name of the uniform variable whose texture is to be specified.\n" | " :param name: name of the uniform variable whose texture is to be specified.\n" | ||||
| " :type name: str\n" | " :type name: str\n" | ||||
| " :param texture: Texture to attach.\n" | " :param texture: texture to attach.\n" | ||||
| " :type texture: :class:`gpu.types.GPUTexture`\n"); | " :type texture: :class:`gpu.types.GPUTexture`\n" | ||||
| static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args) | " :param filter: filtering option which can be 'NEAREST', 'LINEAR' or 'ANISOTROPIC'.\n" | ||||
| " :type filter: str\n" | |||||
| " :param repeat: Three-dimensional array specifying the addressing mode for " | |||||
| "outside [0..1] range for U, V and W coordinates.\n" | |||||
| " :type repeat: sequence\n" | |||||
| " :param use_mipmap: specify the mipmap filter to apply to lookups.\n" | |||||
| " :type use_mipmap: bool\n" | |||||
| " :param clamp_to_border_color: clamp to border color instead of border texel.\n" | |||||
| " :type clamp_to_border_color: bool\n" | |||||
| " :param compare_enabled: compare mode for depth formats.\n" | |||||
| " :type compare_enabled: bool\n"); | |||||
| static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args, PyObject *kwds) | |||||
| { | { | ||||
| const char *name; | const char *name; | ||||
| BPyGPUTexture *py_texture; | BPyGPUTexture *py_texture; | ||||
| if (!PyArg_ParseTuple( | struct PyC_StringEnum pygpu_filter = {pygpu_samplerstate_filter_items, 0}; | ||||
| args, "sO!:GPUShader.uniform_sampler", &name, &BPyGPUTexture_Type, &py_texture)) { | int repeat[3] = {0, 0, 0}; | ||||
| bool use_mipmap = false; | |||||
| bool clamp_to_border_color = false; | |||||
| bool compare_enabled = false; | |||||
| PyObject *py_repeat = NULL; | |||||
| static const char *_keywords[] = {"name", | |||||
| "texture", | |||||
| "filter", | |||||
| "repeat", | |||||
| "use_mipmap", | |||||
| "clamp_to_border_color", | |||||
| "compare_enabled", | |||||
| NULL}; | |||||
| static _PyArg_Parser _parser = {"sO!|$O&OO&O&O&:uniform_sampler", _keywords, 0}; | |||||
| if (!_PyArg_ParseTupleAndKeywordsFast(args, | |||||
| kwds, | |||||
| &_parser, | |||||
| &name, | |||||
| &BPyGPUTexture_Type, | |||||
| &py_texture, | |||||
| PyC_ParseStringEnum, | |||||
| &pygpu_filter, | |||||
| &py_repeat, | |||||
| PyC_ParseBool, | |||||
| &use_mipmap, | |||||
| PyC_ParseBool, | |||||
| &clamp_to_border_color, | |||||
| PyC_ParseBool, | |||||
| &compare_enabled)) { | |||||
| return NULL; | |||||
| } | |||||
| if (py_repeat && PyC_AsArray(repeat, 1, py_repeat, 3, &PyBool_Type, "uniform_sampler") == -1) { | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT; | |||||
| if (compare_enabled) { | |||||
| if (!GPU_texture_depth(py_texture->tex)) { | |||||
| PyErr_SetString(PyExc_AttributeError, | |||||
| "GPUShader.uniform_sampler: Only depth formats does support compare mode."); | |||||
| return NULL; | |||||
| } | |||||
| sampler_state |= GPU_SAMPLER_COMPARE; | |||||
| } | |||||
| if (pygpu_filter.value_found == 1) { | |||||
| sampler_state |= GPU_SAMPLER_FILTER; | |||||
| } | |||||
| else if (pygpu_filter.value_found == 2) { | |||||
| sampler_state |= GPU_SAMPLER_FILTER | GPU_SAMPLER_ANISO; | |||||
| } | |||||
| if (repeat[0]) { | |||||
| sampler_state |= GPU_SAMPLER_REPEAT_S; | |||||
| } | |||||
| if (repeat[1]) { | |||||
| sampler_state |= GPU_SAMPLER_REPEAT_T; | |||||
| } | |||||
| if (repeat[2]) { | |||||
| sampler_state |= GPU_SAMPLER_REPEAT_R; | |||||
| } | |||||
| if (use_mipmap) { | |||||
| sampler_state |= GPU_SAMPLER_MIPMAP; | |||||
| } | |||||
| if (clamp_to_border_color) { | |||||
| sampler_state |= GPU_SAMPLER_CLAMP_BORDER; | |||||
| } | |||||
| int slot = GPU_shader_get_texture_binding(self->shader, name); | int slot = GPU_shader_get_texture_binding(self->shader, name); | ||||
| GPU_texture_bind(py_texture->tex, slot); | GPU_texture_bind_ex(py_texture->tex, sampler_state, slot, false); | ||||
| GPU_shader_uniform_1i(self->shader, name, slot); | GPU_shader_uniform_1i(self->shader, name, slot); | ||||
| Py_RETURN_NONE; | Py_RETURN_NONE; | ||||
| } | } | ||||
| PyDoc_STRVAR( | PyDoc_STRVAR( | ||||
| pygpu_shader_uniform_block_doc, | pygpu_shader_uniform_block_doc, | ||||
| ".. method:: uniform_block(name, ubo)\n" | ".. method:: uniform_block(name, ubo)\n" | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | static struct PyMethodDef pygpu_shader__tp_methods[] = { | ||||
| METH_VARARGS, | METH_VARARGS, | ||||
| pygpu_shader_uniform_float_doc}, | pygpu_shader_uniform_float_doc}, | ||||
| {"uniform_int", | {"uniform_int", | ||||
| (PyCFunction)pygpu_shader_uniform_int, | (PyCFunction)pygpu_shader_uniform_int, | ||||
| METH_VARARGS, | METH_VARARGS, | ||||
| pygpu_shader_uniform_int_doc}, | pygpu_shader_uniform_int_doc}, | ||||
| {"uniform_sampler", | {"uniform_sampler", | ||||
| (PyCFunction)pygpu_shader_uniform_sampler, | (PyCFunction)pygpu_shader_uniform_sampler, | ||||
| METH_VARARGS, | METH_VARARGS | METH_KEYWORDS, | ||||
| pygpu_shader_uniform_sampler_doc}, | pygpu_shader_uniform_sampler_doc}, | ||||
| {"uniform_block", | {"uniform_block", | ||||
| (PyCFunction)pygpu_shader_uniform_block, | (PyCFunction)pygpu_shader_uniform_block, | ||||
| METH_VARARGS, | METH_VARARGS, | ||||
| pygpu_shader_uniform_block_doc}, | pygpu_shader_uniform_block_doc}, | ||||
| {"attr_from_name", | {"attr_from_name", | ||||
| (PyCFunction)pygpu_shader_attr_from_name, | (PyCFunction)pygpu_shader_attr_from_name, | ||||
| METH_O, | METH_O, | ||||
| ▲ Show 20 Lines • Show All 257 Lines • Show Last 20 Lines | |||||
I think it wouldn't hurt to have the full name here.