DRW: API for own versions of builtin GPU shaders
DRW_shader_get_builtin_shader can replace GPU_shader_get_builtin_shader when we need to support clipping. Use this for loose point & wire drawing in object mode, clips edges in lattice edit mode.
This commit is contained in:
parent
1d908bffdd
commit
04d18b117c
|
@ -55,6 +55,7 @@ set(INC_SYS
|
|||
set(SRC
|
||||
intern/draw_anim_viz.c
|
||||
intern/draw_armature.c
|
||||
intern/draw_builtin_shader.c
|
||||
intern/draw_cache.c
|
||||
intern/draw_cache_impl_curve.c
|
||||
intern/draw_cache_impl_displist.c
|
||||
|
@ -133,6 +134,7 @@ set(SRC
|
|||
|
||||
DRW_engine.h
|
||||
intern/DRW_render.h
|
||||
intern/draw_builtin_shader.h
|
||||
intern/draw_cache.h
|
||||
intern/draw_cache_impl.h
|
||||
intern/draw_common.h
|
||||
|
@ -323,6 +325,8 @@ data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC)
|
|||
data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/sculpt_mask_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/drw_shader_3D_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/drw_shader_3D_smooth_color_vert.glsl SRC)
|
||||
|
||||
data_to_c_simple(engines/gpencil/shaders/gpencil_fill_vert.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/gpencil_fill_frag.glsl SRC)
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file draw_armature.c
|
||||
* \ingroup draw
|
||||
* Draw manager versions of #eGPUBuiltinShader, see #GPU_shader_get_builtin_shader.
|
||||
*
|
||||
* Allows for modifications to shaders (currently only clipping support).
|
||||
* Follow GPU_shader.h conventions to avoid annoyance.
|
||||
*/
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "draw_builtin_shader.h" /* own include */
|
||||
|
||||
|
||||
extern char datatoc_common_world_clip_lib_glsl[];
|
||||
|
||||
extern char datatoc_drw_shader_3D_vert_glsl[];
|
||||
extern char datatoc_drw_shader_3D_smooth_color_vert_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
|
||||
|
||||
|
||||
/* cache of built-in shaders (each is created on first use) */
|
||||
static struct {
|
||||
GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS];
|
||||
} g_sh_data[DRW_SHADER_SLOT_LEN - 1] = {{{NULL}}};
|
||||
|
||||
static GPUShader *drw_shader_get_builtin_shader_clipped(eGPUBuiltinShader shader_id, bool *r_test_only)
|
||||
{
|
||||
const char *world_clip_lib = datatoc_common_world_clip_lib_glsl;
|
||||
const char *world_clip_def = "#define USE_WORLD_CLIP_PLANES\n";
|
||||
|
||||
if (r_test_only) {
|
||||
*r_test_only = true;
|
||||
}
|
||||
|
||||
GPUShader *shader = NULL;
|
||||
switch (shader_id) {
|
||||
case GPU_SHADER_3D_UNIFORM_COLOR:
|
||||
if (r_test_only) {
|
||||
break;
|
||||
}
|
||||
shader = DRW_shader_create_from_arrays({
|
||||
.vert = (const char *[]){world_clip_lib, datatoc_drw_shader_3D_vert_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
|
||||
.defs = (const char *[]){world_clip_def, NULL}});
|
||||
break;
|
||||
case GPU_SHADER_3D_SMOOTH_COLOR:
|
||||
if (r_test_only) {
|
||||
break;
|
||||
}
|
||||
shader = DRW_shader_create_from_arrays({
|
||||
.vert = (const char *[]){world_clip_lib, datatoc_drw_shader_3D_smooth_color_vert_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL},
|
||||
.defs = (const char *[]){world_clip_def, NULL}});
|
||||
break;
|
||||
default:
|
||||
/* Unsupported, caller asserts. */
|
||||
if (r_test_only) {
|
||||
*r_test_only = false;
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
static bool drw_shader_get_builtin_shader_test_all(eGPUBuiltinShader shader_id)
|
||||
{
|
||||
bool test = false;
|
||||
drw_shader_get_builtin_shader_clipped(shader_id, &test);
|
||||
return test;
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_get_builtin_shader(eGPUBuiltinShader shader_id, eDRW_ShaderSlot slot)
|
||||
{
|
||||
BLI_assert(drw_shader_get_builtin_shader_test_all(shader_id));
|
||||
if (slot == DRW_SHADER_SLOT_DEFAULT) {
|
||||
return GPU_shader_get_builtin_shader(shader_id);
|
||||
}
|
||||
|
||||
GPUShader **builtin_shaders = g_sh_data[slot - 1].builtin_shaders;
|
||||
|
||||
if (builtin_shaders[shader_id] != NULL) {
|
||||
return builtin_shaders[shader_id];
|
||||
}
|
||||
|
||||
if (slot == DRW_SHADER_SLOT_CLIPPED) {
|
||||
builtin_shaders[shader_id] = drw_shader_get_builtin_shader_clipped(shader_id, NULL);
|
||||
return builtin_shaders[shader_id];
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_shader_free_builtin_shaders(void)
|
||||
{
|
||||
for (int j = 0; j < (DRW_SHADER_SLOT_LEN - 1); j++) {
|
||||
GPUShader **builtin_shaders = g_sh_data[j].builtin_shaders;
|
||||
for (int i = 0; i < GPU_NUM_BUILTIN_SHADERS; i++) {
|
||||
if (builtin_shaders[i]) {
|
||||
GPU_shader_free(builtin_shaders[i]);
|
||||
builtin_shaders[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file draw_builtin_shader.h
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#ifndef __DRAW_BUILTIN_SHADER_H__
|
||||
#define __DRAW_BUILTIN_SHADER_H__
|
||||
|
||||
struct GPUShader;
|
||||
|
||||
struct GPUShader *DRW_shader_get_builtin_shader(eGPUBuiltinShader shader_id, eDRW_ShaderSlot slot);
|
||||
void DRW_shader_free_builtin_shaders(void);
|
||||
|
||||
#endif /* __DRAW_BUILTIN_SHADER_H__ */
|
|
@ -82,6 +82,7 @@
|
|||
#include "draw_cache_impl.h"
|
||||
|
||||
#include "draw_mode_engines.h"
|
||||
#include "draw_builtin_shader.h"
|
||||
#include "engines/eevee/eevee_engine.h"
|
||||
#include "engines/basic/basic_engine.h"
|
||||
#include "engines/workbench/workbench_engine.h"
|
||||
|
@ -2610,6 +2611,7 @@ void DRW_engines_free(void)
|
|||
DRW_shape_cache_free();
|
||||
DRW_stats_free();
|
||||
DRW_globals_free();
|
||||
DRW_shader_free_builtin_shaders();
|
||||
|
||||
DrawEngineType *next;
|
||||
for (DrawEngineType *type = DRW_engines.first; type; type = next) {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "draw_common.h"
|
||||
|
||||
#include "draw_mode_engines.h"
|
||||
#include "draw_builtin_shader.h"
|
||||
|
||||
extern char datatoc_common_world_clip_lib_glsl[];
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
|
@ -154,7 +155,7 @@ static void EDIT_LATTICE_engine_init(void *vedata)
|
|||
const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
|
||||
|
||||
if (!sh_data->wire) {
|
||||
sh_data->wire = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
|
||||
sh_data->wire = DRW_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR, draw_ctx->shader_slot);
|
||||
}
|
||||
|
||||
if (!sh_data->overlay_vert) {
|
||||
|
@ -194,6 +195,9 @@ static void EDIT_LATTICE_cache_init(void *vedata)
|
|||
"Lattice Wire",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
|
||||
stl->g_data->wire_shgrp = DRW_shgroup_create(sh_data->wire, psl->wire_pass);
|
||||
if (rv3d->rflag & RV3D_CLIPPING) {
|
||||
DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->wire_shgrp, rv3d);
|
||||
}
|
||||
|
||||
psl->vert_pass = DRW_pass_create(
|
||||
"Lattice Verts",
|
||||
|
|
|
@ -79,9 +79,11 @@
|
|||
#include "draw_mode_engines.h"
|
||||
#include "draw_manager_text.h"
|
||||
#include "draw_common.h"
|
||||
#include "draw_builtin_shader.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
extern char datatoc_common_world_clip_lib_glsl[];
|
||||
extern char datatoc_object_outline_prepass_vert_glsl[];
|
||||
extern char datatoc_object_outline_prepass_geom_glsl[];
|
||||
extern char datatoc_object_outline_prepass_frag_glsl[];
|
||||
|
@ -103,6 +105,7 @@ extern char datatoc_gpu_shader_flat_color_frag_glsl[];
|
|||
extern char datatoc_gpu_shader_flat_id_frag_glsl[];
|
||||
extern char datatoc_common_fullscreen_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
|
||||
extern char datatoc_drw_shader_3D_vert_glsl[];
|
||||
|
||||
/* *********** LISTS *********** */
|
||||
typedef struct OBJECT_PassList {
|
||||
|
@ -409,6 +412,10 @@ static void OBJECT_engine_init(void *vedata)
|
|||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
|
||||
|
||||
const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
|
||||
const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
|
||||
const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
|
||||
|
||||
if (!sh_data->outline_resolve) {
|
||||
/* Outline */
|
||||
sh_data->outline_prepass = DRW_shader_create_3D(datatoc_object_outline_prepass_frag_glsl, NULL);
|
||||
|
@ -484,7 +491,10 @@ static void OBJECT_engine_init(void *vedata)
|
|||
datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_flat_id_frag_glsl, NULL);
|
||||
|
||||
/* Loose Points */
|
||||
sh_data->loose_points = DRW_shader_create_3D(datatoc_object_loose_points_frag_glsl, NULL);
|
||||
sh_data->loose_points = DRW_shader_create_from_arrays({
|
||||
.vert = (const char *[]){world_clip_lib_or_empty, datatoc_drw_shader_3D_vert_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_object_loose_points_frag_glsl, NULL},
|
||||
.defs = (const char *[]){world_clip_def_or_empty, NULL}});
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -664,21 +674,27 @@ static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader
|
|||
}
|
||||
|
||||
/* currently same as 'shgroup_outline', new function to avoid confustion */
|
||||
static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh)
|
||||
static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh, eDRW_ShaderSlot shader_slot)
|
||||
{
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_vec4(grp, "color", col, 1);
|
||||
|
||||
if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
|
||||
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
|
||||
/* currently same as 'shgroup_outline', new function to avoid confustion */
|
||||
static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUShader *sh)
|
||||
static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUShader *sh, eDRW_ShaderSlot shader_slot)
|
||||
{
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_vec4(grp, "color", col, 1);
|
||||
DRW_shgroup_uniform_vec4(grp, "innerColor", G_draw.block.colorEditMeshMiddle, 1);
|
||||
|
||||
if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
|
||||
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
|
||||
|
@ -1252,24 +1268,24 @@ static void OBJECT_cache_init(void *vedata)
|
|||
sgl->texspace = shgroup_instance(sgl->non_meshes, geom);
|
||||
|
||||
/* Wires (for loose edges) */
|
||||
sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
sgl->wire = shgroup_wire(sgl->non_meshes, gb->colorWire, sh);
|
||||
sgl->wire_select = shgroup_wire(sgl->non_meshes, gb->colorSelect, sh);
|
||||
sgl->wire_transform = shgroup_wire(sgl->non_meshes, gb->colorTransform, sh);
|
||||
sgl->wire_active = shgroup_wire(sgl->non_meshes, gb->colorActive, sh);
|
||||
sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR, draw_ctx->shader_slot);
|
||||
sgl->wire = shgroup_wire(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_slot);
|
||||
sgl->wire_select = shgroup_wire(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_slot);
|
||||
sgl->wire_transform = shgroup_wire(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_slot);
|
||||
sgl->wire_active = shgroup_wire(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_slot);
|
||||
/* Wire (duplicator) */
|
||||
sgl->wire_dupli = shgroup_wire(sgl->non_meshes, gb->colorDupli, sh);
|
||||
sgl->wire_dupli_select = shgroup_wire(sgl->non_meshes, gb->colorDupliSelect, sh);
|
||||
sgl->wire_dupli = shgroup_wire(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_slot);
|
||||
sgl->wire_dupli_select = shgroup_wire(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_slot);
|
||||
|
||||
/* Points (loose points) */
|
||||
sh = sh_data->loose_points;
|
||||
sgl->points = shgroup_points(sgl->non_meshes, gb->colorWire, sh);
|
||||
sgl->points_select = shgroup_points(sgl->non_meshes, gb->colorSelect, sh);
|
||||
sgl->points_transform = shgroup_points(sgl->non_meshes, gb->colorTransform, sh);
|
||||
sgl->points_active = shgroup_points(sgl->non_meshes, gb->colorActive, sh);
|
||||
sgl->points = shgroup_points(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_slot);
|
||||
sgl->points_select = shgroup_points(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_slot);
|
||||
sgl->points_transform = shgroup_points(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_slot);
|
||||
sgl->points_active = shgroup_points(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_slot);
|
||||
/* Points (duplicator) */
|
||||
sgl->points_dupli = shgroup_points(sgl->non_meshes, gb->colorDupli, sh);
|
||||
sgl->points_dupli_select = shgroup_points(sgl->non_meshes, gb->colorDupliSelect, sh);
|
||||
sgl->points_dupli = shgroup_points(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_slot);
|
||||
sgl->points_dupli_select = shgroup_points(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_slot);
|
||||
DRW_shgroup_state_disable(sgl->points, DRW_STATE_BLEND);
|
||||
DRW_shgroup_state_disable(sgl->points_select, DRW_STATE_BLEND);
|
||||
DRW_shgroup_state_disable(sgl->points_transform, DRW_STATE_BLEND);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* Keep 'gpu_shader_3D_smooth_color_vert.glsl' compatible. */
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform mat4 ModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
finalColor = color;
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Keep 'gpu_shader_3D_vert.glsl' compatible. */
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform mat4 ModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue