diff options
author | mano-wii <germano.costa@ig.com.br> | 2018-10-04 05:34:27 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2018-10-04 05:34:27 +0300 |
commit | ffa15f4b4ad6c0ff70dfc2801bc32989ad97d257 (patch) | |
tree | aca6dc171aeac0bee64dbe6606da98a46efa5c12 /source/blender/python/gpu/gpu_py_shader.c | |
parent | 98a10fd7de609ca4b026c39c1b3ef3724c60d25e (diff) |
Python GPU: GPUBatch and GPUShader refactor.
The changes are:
- The shader now is passed as a parameter of the batch `draw` method (batch.draw(shader)). Since the batch always has to set a shader before drawing;
- The batch methods to specify a value to a uniform have been removed. Uniforms are parameters of the program (here called shader). If you change a uniform, it changes in all batchs that use the same program;
- New methods were added to set uniforms by the shader;
- The `batch.program_set_builtin` was removed. It is a duplicate of `program_set` but without a shader object. We need the shader object to configure the uniform;
Differential Revision: https://developer.blender.org/D3752
Diffstat (limited to 'source/blender/python/gpu/gpu_py_shader.c')
-rw-r--r-- | source/blender/python/gpu/gpu_py_shader.c | 222 |
1 files changed, 190 insertions, 32 deletions
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 2fc5f5278f0..182ec289262 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -75,6 +75,18 @@ static int bpygpu_pyLong_as_shader_enum(PyObject *o) return (int)id; } +static int bpygpu_uniform_location_get(const GPUShaderInterface *shaderface, const char *name) +{ + const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shaderface, name); + + if (uniform == NULL) { + PyErr_SetString(PyExc_ValueError, "uniform not found"); + return -1; + } + + return uniform->location; +} + /** \} */ @@ -324,57 +336,200 @@ static PyObject *bpygpu_shader_uniform_vector_int( Py_RETURN_NONE; } +PyDoc_STRVAR(bpygpu_shader_uniform_bool_doc, +".. method:: uniform_bool(name, seq)\n" +"\n" +" Specify the value of a uniform variable for the current program object.\n" +"\n" +" :param name: name of the uniform variable whose location is to be queried.\n" +" :type name: `str`\n" +" :param seq: values that will be used to update the specified uniform variable.\n" +" :type seq: sequence of bools\n" +); +static PyObject *bpygpu_shader_uniform_bool( + BPyGPUShader *self, PyObject *args) +{ + const char *error_prefix = "GPUShader.uniform_bool"; + + struct { + const char *id; + PyObject *seq; + } params; + + if (!PyArg_ParseTuple( + args, "sO:GPUShader.uniform_bool", + ¶ms.id, ¶ms.seq)) + { + return NULL; + } + + int values[4]; + int length; + int ret; + { + PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix); + if (seq_fast == NULL) { + ret = -1; + } + else { + length = PySequence_Fast_GET_SIZE(params.seq); + if (length == 0 || length > 4) { + PyErr_Format(PyExc_TypeError, + "%s: invalid sequence length. expected 1..4, got %d", + error_prefix, length); + ret = -1; + } + else { + ret = PyC_AsArray_FAST( + values, seq_fast, length, &PyLong_Type, + false, error_prefix); + } + Py_DECREF(seq_fast); + } + } + if (ret == -1) { + return NULL; + } + + const int location = bpygpu_uniform_location_get(GPU_shader_get_interface(self->shader), params.id); + if (location == -1) { + return NULL; + } + + GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); + + Py_RETURN_NONE; +} + PyDoc_STRVAR(bpygpu_shader_uniform_float_doc, - ".. method:: uniform_float(location, value)\n" - "\n" - " Set uniform value.\n" - "\n" - " :param location: builtin identifier.\n" - " :type location: `int`\n" - " :param value: uniform value.\n" - " :type value: `float`\n" +".. method:: uniform_float(name, seq)\n" +"\n" +" Specify the value of a uniform variable for the current program object.\n" +"\n" +" :param name: name of the uniform variable whose location is to be queried.\n" +" :type name: `str`\n" +" :param seq: values that will be used to update the specified uniform variable.\n" +" :type seq: sequence of numbers\n" ); static PyObject *bpygpu_shader_uniform_float( - BPyGPUShader *self, PyObject *args) + BPyGPUShader *self, PyObject *args) { - int location; - float value; + const char *error_prefix = "GPUShader.uniform_float"; + + struct { + const char *id; + PyObject *seq; + } params; if (!PyArg_ParseTuple( - args, "if:GPUShader.uniform_float", - &location, &value)) + args, "sO:GPUShader.uniform_float", + ¶ms.id, ¶ms.seq)) + { + return NULL; + } + + float values[16]; + int length; + int ret; { + PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix); + if (seq_fast == NULL) { + ret = -1; + } + else { + length = PySequence_Fast_GET_SIZE(params.seq); + if ((length == 0) || (length > 16) || + (4 < length && length < 9) || + (9 < length && length < 16)) + { + PyErr_Format(PyExc_TypeError, + "%s: invalid sequence length. expected 1..4, 9 or 16, got %d", + error_prefix, length); + ret = -1; + } + else { + ret = PyC_AsArray_FAST( + values, seq_fast, length, &PyFloat_Type, + false, error_prefix); + } + Py_DECREF(seq_fast); + } + } + if (ret == -1) { + return NULL; + } + + const int location = bpygpu_uniform_location_get(GPU_shader_get_interface(self->shader), params.id); + if (location == -1) { return NULL; } - GPU_shader_uniform_float(self->shader, location, value); + GPU_shader_uniform_vector(self->shader, location, length, 1, values); Py_RETURN_NONE; } PyDoc_STRVAR(bpygpu_shader_uniform_int_doc, -".. method:: uniform_int(location, value)\n" +".. method:: uniform_int(name, seq)\n" "\n" -" Set uniform value.\n" +" Specify the value of a uniform variable for the current program object.\n" "\n" -" :param location: builtin identifier.\n" -" :type location: `int`\n" -" :param value: uniform value.\n" -" :type value: `int`\n" +" :param name: name of the uniform variable whose location is to be queried.\n" +" :type name: `str`\n" +" :param seq: values that will be used to update the specified uniform variable.\n" +" :type seq: sequence of numbers\n" ); static PyObject *bpygpu_shader_uniform_int( BPyGPUShader *self, PyObject *args) { - int location, value; + const char *error_prefix = "GPUShader.uniform_int"; + + struct { + const char *id; + PyObject *seq; + } params; if (!PyArg_ParseTuple( - args, "ii:GPUShader.uniform_int", - &location, &value)) + args, "sO:GPUShader.uniform_int", + ¶ms.id, ¶ms.seq)) { return NULL; } - GPU_shader_uniform_int(self->shader, location, value); + int values[4]; + int length; + int ret; + { + PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix); + if (seq_fast == NULL) { + ret = -1; + } + else { + length = PySequence_Fast_GET_SIZE(params.seq); + if (length == 0 || length > 4) { + PyErr_Format(PyExc_TypeError, + "%s: invalid sequence length. expected 1..4, got %d", + error_prefix, length); + ret = -1; + } + else { + ret = PyC_AsArray_FAST( + values, seq_fast, length, &PyLong_Type, + false, error_prefix); + } + Py_DECREF(seq_fast); + } + } + if (ret == -1) { + return NULL; + } + + const int location = bpygpu_uniform_location_get(GPU_shader_get_interface(self->shader), params.id); + if (location == -1) { + return NULL; + } + + GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); Py_RETURN_NONE; } @@ -408,14 +563,6 @@ static PyObject *bpygpu_shader_attr_from_name( return PyLong_FromLong(attrib); } -PyDoc_STRVAR(bpygpu_shader_program_doc, -"The name of the program object for use by the OpenGL API (read-only).\n\n:type: int" -); -static PyObject *bpygpu_shader_program_get(BPyGPUShader *self, void *UNUSED(closure)) -{ - return PyLong_FromLong(GPU_shader_get_program(self->shader)); -} - static struct PyMethodDef bpygpu_shader_methods[] = { {"bind", (PyCFunction)bpygpu_shader_bind, METH_NOARGS, bpygpu_shader_bind_doc}, @@ -437,6 +584,9 @@ static struct PyMethodDef bpygpu_shader_methods[] = { {"uniform_vector_int", (PyCFunction)bpygpu_shader_uniform_vector_int, METH_VARARGS, bpygpu_shader_uniform_vector_int_doc}, + {"uniform_bool", + (PyCFunction)bpygpu_shader_uniform_bool, + METH_VARARGS, bpygpu_shader_uniform_bool_doc}, {"uniform_float", (PyCFunction)bpygpu_shader_uniform_float, METH_VARARGS, bpygpu_shader_uniform_float_doc}, @@ -449,6 +599,14 @@ static struct PyMethodDef bpygpu_shader_methods[] = { {NULL, NULL, 0, NULL} }; +PyDoc_STRVAR(bpygpu_shader_program_doc, +"The name of the program object for use by the OpenGL API (read-only).\n\n:type: int" +); +static PyObject *bpygpu_shader_program_get(BPyGPUShader *self, void *UNUSED(closure)) +{ + return PyLong_FromLong(GPU_shader_get_program(self->shader)); +} + static PyGetSetDef bpygpu_shader_getseters[] = { {"program", (getter)bpygpu_shader_program_get, (setter)NULL, |