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_FlagSet pygpu_texture_samplerstate_items[] = { | static const struct PyC_StringEnumItems pygpu_samplerstate_filter_items[] = { | ||||
| {GPU_SAMPLER_DEFAULT, "DEFAULT"}, | {0, "NEAREST"}, | ||||
| {GPU_SAMPLER_FILTER, "FILTER"}, | {1, "LINEAR"}, | ||||
| {GPU_SAMPLER_MIPMAP, "MIPMAP"}, | {2, "ANISO"}, | ||||
fclem: I think it wouldn't hurt to have the full name here. | |||||
| {GPU_SAMPLER_REPEAT_S, "REPEAT_S"}, | |||||
| {GPU_SAMPLER_REPEAT_T, "REPEAT_T"}, | |||||
| {GPU_SAMPLER_REPEAT_R, "REPEAT_R"}, | |||||
| {GPU_SAMPLER_CLAMP_BORDER, "CLAMP_BORDER"}, | |||||
| {GPU_SAMPLER_COMPARE, "COMPARE"}, | |||||
| {GPU_SAMPLER_ANISO, "ANISO"}, | |||||
| {GPU_SAMPLER_ICON, "ICON"}, | |||||
| {GPU_SAMPLER_REPEAT, "REPEAT"}, | |||||
| {0, NULL}, | {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); | ||||
| ▲ Show 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | static PyObject *pygpu_shader_uniform_int(BPyGPUShader *self, PyObject *args) | ||||
| } | } | ||||
| 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(pygpu_shader_uniform_sampler_doc, | ||||
| ".. method:: uniform_sampler(name, texture, state={'DEFAULT'})\n" | ".. 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 texture and state for an uniform sampler in 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" | ||||
| " :param state: set of values in:\n" | " :param filter: filtering option which can be 'NEAREST', 'LINEAR' or 'ANISO'.\n" | ||||
| "\n" | " :type filter: str\n" | ||||
| " - ``DEFAULT``\n" | " :param repeat: Three-dimensional array specifying the addressing mode for " | ||||
| " - ``FILTER``\n" | "outside [0..1] range for U, V and W coordinates.\n" | ||||
| " - ``MIPMAP``\n" | " :type repeat: sequence\n" | ||||
| " - ``REPEAT_S``\n" | " :param use_mipmap: specify the mipmap filter to apply to lookups.\n" | ||||
| " - ``REPEAT_T``\n" | " :type use_mipmap: bool\n" | ||||
| " - ``REPEAT_R``\n" | " :param clamp_to_border_color: clamp to border color instead of border texel.\n" | ||||
| " - ``CLAMP_BORDER``\n" | " :type clamp_to_border_color: bool\n" | ||||
| " - ``COMPARE``\n" | " :param compare_enabled: compare mode for depth formats.\n" | ||||
| " - ``ANISO``\n" | " :type compare_enabled: bool\n"); | ||||
| " - ``ICON``\n" | |||||
| " - ``REPEAT``\n" | |||||
| " :type state: set\n"); | |||||
| static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args, PyObject *kwds) | static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args, PyObject *kwds) | ||||
| { | { | ||||
| const char *name; | const char *name; | ||||
| BPyGPUTexture *py_texture; | BPyGPUTexture *py_texture; | ||||
| PyObject *py_samplerstate = NULL; | struct PyC_StringEnum pygpu_filter = {pygpu_shader_config_items, 0}; | ||||
| 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; | |||||
| } | |||||
| static const char *_keywords[] = {"name", "texture", "state", NULL}; | if (py_repeat && PyC_AsArray(repeat, 1, py_repeat, 3, &PyBool_Type, "uniform_sampler") == -1) { | ||||
| static _PyArg_Parser _parser = {"sO!|$O:uniform_sampler", _keywords, 0}; | |||||
| if (!_PyArg_ParseTupleAndKeywordsFast( | |||||
| args, kwds, &_parser, &name, &BPyGPUTexture_Type, &py_texture, &py_samplerstate)) { | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| int sampler_state = GPU_SAMPLER_DEFAULT; | eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT; | ||||
| if (py_samplerstate) { | if (compare_enabled) { | ||||
| if (PyC_FlagSet_ToBitfield(pygpu_texture_samplerstate_items, | if (!GPU_texture_depth(py_texture->tex)) { | ||||
| py_samplerstate, | PyErr_SetString(PyExc_AttributeError, | ||||
| &sampler_state, | "GPUShader.uniform_sampler: Only depth formats does support compare mode."); | ||||
| "shader.uniform_sampler") == -1) { | |||||
| return NULL; | 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_ex(py_texture->tex, (eGPUSamplerState)sampler_state, slot, false); | 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 369 Lines • Show Last 20 Lines | |||||
I think it wouldn't hurt to have the full name here.