diff --git a/doc/python_api/examples/gpu.1.py b/doc/python_api/examples/gpu.1.py index 7dad7c8c50e..20798df9e60 100644 --- a/doc/python_api/examples/gpu.1.py +++ b/doc/python_api/examples/gpu.1.py @@ -77,7 +77,8 @@ Typically multiple shaders are linked together into a *Program*. However, in the Blender Python API the term *Shader* refers to an OpenGL Program. Every :class:`gpu.types.GPUShader` consists of a vertex shader, a fragment shader and an optional geometry shader. For common drawing tasks there are some built-in shaders accessible from :class:`gpu.shader.from_builtin` -with an identifier such as ``UNIFORM_COLOR`` or ``FLAT_COLOR``. +with an identifier such as ``UNIFORM_COLOR`` or ``FLAT_COLOR``. There are specific builtin shaders for +drawing triangles, lines and points. Every shader defines a set of attributes and uniforms that have to be set in order to use the shader. Attributes are properties that are set using a vertex buffer and can be different for individual vertices. @@ -140,6 +141,29 @@ To try these examples, just copy them into Blenders text editor and execute them To keep the examples relatively small, they just register a draw function that can't easily be removed anymore. Blender has to be restarted in order to delete the draw handlers. +3D Points with Single Color +""" + +import bpy +import gpu +from gpu_extras.batch import batch_for_shader + +coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)] +shader = gpu.shader.from_builtin('POINT_UNIFORM_COLOR') +batch = batch_for_shader(shader, 'POINTS', {"pos": coords}) + + +def draw(): + shader.uniform_float("color", (1, 1, 0, 1)) + gpu.state.point_size_set(4.5) + batch.draw(shader) + + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') + + +""" + 3D Lines with Single Color -------------------------- """ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index b43d6c0bdb0..83d0fde2039 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -505,6 +505,7 @@ set(GLSL_SRC shaders/gpu_shader_point_varying_color_frag.glsl shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl + shaders/gpu_shader_3D_point_flat_color_vert.glsl shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl diff --git a/source/blender/gpu/GPU_shader_builtin.hh b/source/blender/gpu/GPU_shader_builtin.hh index b9b8ff478f1..cbb43a7bba3 100644 --- a/source/blender/gpu/GPU_shader_builtin.hh +++ b/source/blender/gpu/GPU_shader_builtin.hh @@ -104,6 +104,8 @@ enum eGPUBuiltinShader { */ GPU_SHADER_3D_FLAT_COLOR, GPU_SHADER_3D_POLYLINE_FLAT_COLOR, + GPU_SHADER_3D_POINT_FLAT_COLOR, + /** * Take a 3D position and color for each vertex with perspective correct interpolation. * @@ -112,6 +114,7 @@ enum eGPUBuiltinShader { */ GPU_SHADER_3D_SMOOTH_COLOR, GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR, + /** * Take a single color for all the vertices and a 3D position for each vertex. * @@ -120,6 +123,8 @@ enum eGPUBuiltinShader { */ GPU_SHADER_3D_UNIFORM_COLOR, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, + GPU_SHADER_3D_POINT_UNIFORM_COLOR, + /** * Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex. * diff --git a/source/blender/gpu/intern/gpu_shader_builtin.cc b/source/blender/gpu/intern/gpu_shader_builtin.cc index 57b7c1049f8..6c8ddce8b53 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.cc +++ b/source/blender/gpu/intern/gpu_shader_builtin.cc @@ -74,6 +74,10 @@ static const char *builtin_shader_create_info_name(eGPUBuiltinShader shader) return "gpu_shader_3D_point_varying_size_varying_color"; case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA: return "gpu_shader_3D_point_uniform_size_uniform_color_aa"; + case GPU_SHADER_3D_POINT_FLAT_COLOR: + return "gpu_shader_3D_point_flat_color"; + case GPU_SHADER_3D_POINT_UNIFORM_COLOR: + return "gpu_shader_3D_point_uniform_color"; case GPU_SHADER_2D_AREA_BORDERS: return "gpu_shader_2D_area_borders"; case GPU_SHADER_2D_WIDGET_BASE: diff --git a/source/blender/gpu/shaders/CMakeLists.txt b/source/blender/gpu/shaders/CMakeLists.txt index ade3d1bb52f..afc99ea987d 100644 --- a/source/blender/gpu/shaders/CMakeLists.txt +++ b/source/blender/gpu/shaders/CMakeLists.txt @@ -31,6 +31,7 @@ set(SRC_GLSL_VERT gpu_shader_3D_normal_vert.glsl gpu_shader_3D_point_uniform_size_aa_vert.glsl gpu_shader_3D_point_varying_size_varying_color_vert.glsl + gpu_shader_3D_point_flat_color_vert.glsl gpu_shader_3D_smooth_color_vert.glsl gpu_shader_display_fallback_vert.glsl gpu_shader_gpencil_stroke_vert.glsl diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_flat_color_vert.glsl new file mode 100644 index 00000000000..3eb5aa31b39 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_flat_color_vert.glsl @@ -0,0 +1,21 @@ +/* SPDX-FileCopyrightText: 2016-2022 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "infos/gpu_shader_3D_flat_color_info.hh" + +#include "gpu_shader_cfg_world_clip_lib.glsl" + +VERTEX_SHADER_CREATE_INFO(gpu_shader_3D_flat_color) + +void main() +{ + float4 pos_4d = float4(pos, 1.0f); + gl_Position = ModelViewProjectionMatrix * pos_4d; + gl_PointSize = size; + finalColor = color; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((clipPlanes.ClipModelMatrix * pos_4d).xyz); +#endif +} diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh index 00d23f04b06..4a6b9316d71 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh @@ -48,3 +48,29 @@ ADDITIONAL_INFO(gpu_shader_3D_point_uniform_size_uniform_color_aa) ADDITIONAL_INFO(gpu_clip_planes) DO_STATIC_COMPILATION() GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_flat_color) +VERTEX_IN(0, float3, pos) +VERTEX_IN(1, float4, color) +VERTEX_OUT(flat_color_iface) +FRAGMENT_OUT(0, float4, fragColor) +PUSH_CONSTANT(float4x4, ModelViewProjectionMatrix) +PUSH_CONSTANT(float, size) +VERTEX_SOURCE("gpu_shader_3D_point_flat_color_vert.glsl") +FRAGMENT_SOURCE("gpu_shader_flat_color_frag.glsl") +ADDITIONAL_INFO(gpu_srgb_to_framebuffer_space) +DO_STATIC_COMPILATION() +GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_uniform_color) +VERTEX_IN(0, float3, pos) +VERTEX_OUT(flat_color_iface) +FRAGMENT_OUT(0, float4, fragColor) +PUSH_CONSTANT(float4x4, ModelViewProjectionMatrix) +PUSH_CONSTANT(float4, color) +PUSH_CONSTANT(float, size) +VERTEX_SOURCE("gpu_shader_3D_point_flat_color_vert.glsl") +FRAGMENT_SOURCE("gpu_shader_flat_color_frag.glsl") +ADDITIONAL_INFO(gpu_srgb_to_framebuffer_space) +DO_STATIC_COMPILATION() +GPU_SHADER_CREATE_END() diff --git a/source/blender/python/gpu/gpu_py_batch.cc b/source/blender/python/gpu/gpu_py_batch.cc index 60bfbc2254d..f55fe3ad0da 100644 --- a/source/blender/python/gpu/gpu_py_batch.cc +++ b/source/blender/python/gpu/gpu_py_batch.cc @@ -352,6 +352,33 @@ static PyObject *pygpu_batch_draw(BPyGPUBatch *self, PyObject *args) } } + /* Emit a warning when trying to draw points with a regular shader as it is too late to + * automatically switch to a point shader. */ + if (py_shader && py_shader->is_builtin && self->batch->prim_type == GPU_PRIM_POINTS) { + GPUShader *shader = py_shader->shader; + if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR)) { + PyErr_WarnEx(PyExc_DeprecationWarning, + "Calling GPUBatch.draw to draw points with " + "GPU_SHADER_3D_FLAT_COLOR is deprecated. " + "Use GPU_SHADER_3D_POINT_FLAT_COLOR instead.", + 1); + } + else if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR)) { + PyErr_WarnEx(PyExc_DeprecationWarning, + "Calling GPUBatch.draw to draw points with " + "GPU_SHADER_3D_SMOOTH_COLOR is deprecated. " + "Use GPU_SHADER_3D_POINT_FLAT_COLOR instead.", + 1); + } + else if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR)) { + PyErr_WarnEx(PyExc_DeprecationWarning, + "Calling GPUBatch.draw to draw points with " + "GPU_SHADER_3D_UNIFORM_COLOR is deprecated. " + "Use GPU_SHADER_3D_POINT_SMOOTH_COLOR instead.", + 1); + } + } + if (const char *error = pygpu_shader_check_compatibility(self->batch)) { PyErr_SetString(PyExc_RuntimeError, error); return nullptr; diff --git a/source/blender/python/gpu/gpu_py_shader.cc b/source/blender/python/gpu/gpu_py_shader.cc index 28a1278f00d..85f5ecc9062 100644 --- a/source/blender/python/gpu/gpu_py_shader.cc +++ b/source/blender/python/gpu/gpu_py_shader.cc @@ -59,7 +59,13 @@ " :Uniforms: vec2 viewportSize, float lineWidth\n" \ "``POLYLINE_UNIFORM_COLOR``\n" \ " :Attributes: vec3 pos\n" \ - " :Uniforms: vec2 viewportSize, float lineWidth\n" + " :Uniforms: vec2 viewportSize, float lineWidth\n" \ + "``POINT_FLAT_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: float size\n" \ + "``POLYLINE_UNIFORM_COLOR``\n" \ + " :Attributes: vec3 pos\n" \ + " :Uniforms: vec4 color, float size\n" static const PyC_StringEnumItems pygpu_shader_builtin_items[] = { {GPU_SHADER_3D_FLAT_COLOR, "FLAT_COLOR"}, @@ -70,6 +76,8 @@ static const PyC_StringEnumItems pygpu_shader_builtin_items[] = { {GPU_SHADER_3D_POLYLINE_FLAT_COLOR, "POLYLINE_FLAT_COLOR"}, {GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR, "POLYLINE_SMOOTH_COLOR"}, {GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, "POLYLINE_UNIFORM_COLOR"}, + {GPU_SHADER_3D_POINT_FLAT_COLOR, "POINT_FLAT_COLOR"}, + {GPU_SHADER_3D_POINT_UNIFORM_COLOR, "POINT_UNIFORM_COLOR"}, {0, nullptr}, };