Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2018-10-04 05:34:27 +0300
committermano-wii <germano.costa@ig.com.br>2018-10-04 05:34:27 +0300
commitffa15f4b4ad6c0ff70dfc2801bc32989ad97d257 (patch)
treeaca6dc171aeac0bee64dbe6606da98a46efa5c12 /source/blender/python/gpu/gpu_py_shader.c
parent98a10fd7de609ca4b026c39c1b3ef3724c60d25e (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.c222
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",
+ &params.id, &params.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",
+ &params.id, &params.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",
+ &params.id, &params.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,