Refactor: DRW: Move color ramp texture creation to Overlay::Instance class

Rel #134690
This commit is contained in:
Clément Foucault
2025-02-18 17:51:59 +01:00
parent cd1c1b1e95
commit 500ebdfc2f
6 changed files with 88 additions and 94 deletions

View File

@@ -6,6 +6,7 @@
* \ingroup overlay
*/
#include "BKE_colorband.hh"
#include "DEG_depsgraph_query.hh"
#include "ED_view3d.hh"
@@ -109,7 +110,9 @@ void Instance::init()
/* TODO(fclem): Remove DRW global usage. */
resources.globals_buf = G_draw.block_ubo;
resources.theme_settings = G_draw.block;
resources.weight_ramp_tx.wrap(G_draw.weight_ramp);
ensure_weight_ramp_texture();
{
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ;
if (resources.dummy_depth_tx.ensure_2d(GPU_DEPTH_COMPONENT32F, int2(1, 1), usage)) {
@@ -119,6 +122,82 @@ void Instance::init()
}
}
void Instance::ensure_weight_ramp_texture()
{
/* Weight Painting color ramp texture */
bool user_weight_ramp = (U.flag & USER_CUSTOM_RANGE) != 0;
auto is_equal = [](const ColorBand &a, const ColorBand &b) {
if (a.tot != b.tot || a.cur != b.cur || a.ipotype != b.ipotype ||
a.ipotype_hue != b.ipotype_hue || a.color_mode != b.color_mode)
{
return false;
}
auto is_equal_cbd = [](const CBData &a, const CBData &b) {
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a && a.pos == b.pos &&
a.cur == b.cur;
};
for (int i = 0; i < ARRAY_SIZE(a.data); i++) {
if (!is_equal_cbd(a.data[i], b.data[i])) {
return false;
}
}
return true;
};
if (assign_if_different(resources.weight_ramp_custom, user_weight_ramp)) {
resources.weight_ramp_tx.free();
}
if (user_weight_ramp && !is_equal(resources.weight_ramp_copy, U.coba_weight)) {
resources.weight_ramp_copy = U.coba_weight;
resources.weight_ramp_tx.free();
}
if (resources.weight_ramp_tx.is_valid()) {
/* Only recreate on updates. */
return;
}
auto evaluate_weight_to_color = [&](const float weight, float result[4]) {
if (user_weight_ramp) {
BKE_colorband_evaluate(&U.coba_weight, weight, result);
}
else {
/* Use gamma correction to even out the color bands:
* increasing widens yellow/cyan vs red/green/blue.
* Gamma 1.0 produces the original 2.79 color ramp. */
const float gamma = 1.5f;
const float hsv[3] = {
(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)};
hsv_to_rgb_v(hsv, result);
for (int i = 0; i < 3; i++) {
result[i] = pow(result[i], 1.0f / gamma);
}
}
};
constexpr int res = 256;
float pixels[res][4];
for (int i = 0; i < res; i++) {
evaluate_weight_to_color(i / 255.0f, pixels[i]);
pixels[i][3] = 1.0f;
}
uchar4 pixels_ubyte[res];
for (int i = 0; i < res; i++) {
unit_float_to_uchar_clamp_v4(pixels_ubyte[i], pixels[i]);
}
resources.weight_ramp_tx.ensure_1d(GPU_SRGB8_A8, res, GPU_TEXTURE_USAGE_SHADER_READ);
GPU_texture_update(resources.weight_ramp_tx, GPU_DATA_UBYTE, pixels_ubyte);
}
void Instance::begin_sync()
{
/* TODO(fclem): Against design. Should not sync depending on view. */

View File

@@ -158,6 +158,8 @@ class Instance {
void draw_node(Manager &manager, View &view);
void draw_v2d(Manager &manager, View &view);
void draw_v3d(Manager &manager, View &view);
void ensure_weight_ramp_texture();
};
} // namespace blender::draw::overlay

View File

@@ -665,7 +665,6 @@ struct Resources : public select::SelectMap {
GlobalsUboStorage theme_settings;
/* References, not owned. */
GPUUniformBuf *globals_buf;
TextureRef weight_ramp_tx;
/* Wrappers around #DefaultTextureList members. */
TextureRef depth_in_front_tx;
TextureRef color_overlay_tx;
@@ -686,6 +685,12 @@ struct Resources : public select::SelectMap {
TextureRef depth_target_tx;
TextureRef depth_target_in_front_tx;
/** Copy of the settings the current texture was generated with. Used to detect updates. */
bool weight_ramp_custom = false;
ColorBand weight_ramp_copy = {};
/** Baked color ramp texture from theme and user settings. Maps weight [0..1] to color. */
Texture weight_ramp_tx = {"weight_ramp"};
Vector<MovieClip *> bg_movie_clips;
const ShapeCache &shapes;

View File

@@ -226,89 +226,4 @@ void DRW_globals_update()
}
GPU_uniformbuf_update(G_draw.block_ubo, gb);
if (!G_draw.ramp) {
ColorBand ramp = {0};
float *colors;
int col_size;
ramp.tot = 3;
ramp.data[0].a = 1.0f;
ramp.data[0].b = 1.0f;
ramp.data[0].pos = 0.0f;
ramp.data[1].a = 1.0f;
ramp.data[1].g = 1.0f;
ramp.data[1].pos = 0.5f;
ramp.data[2].a = 1.0f;
ramp.data[2].r = 1.0f;
ramp.data[2].pos = 1.0f;
BKE_colorband_evaluate_table_rgba(&ramp, &colors, &col_size);
G_draw.ramp = GPU_texture_create_1d(
"ramp", col_size, 1, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, colors);
MEM_freeN(colors);
}
/* Weight Painting color ramp texture */
bool user_weight_ramp = (U.flag & USER_CUSTOM_RANGE) != 0;
if (weight_ramp_custom != user_weight_ramp ||
(user_weight_ramp && memcmp(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand)) != 0))
{
GPU_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
}
if (G_draw.weight_ramp == nullptr) {
weight_ramp_custom = user_weight_ramp;
memcpy(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand));
G_draw.weight_ramp = DRW_create_weight_colorramp_texture();
}
}
/* ********************************* SHGROUP ************************************* */
void DRW_globals_free() {}
/* ******************************************** COLOR UTILS ************************************ */
static void DRW_evaluate_weight_to_color(const float weight, float result[4])
{
if (U.flag & USER_CUSTOM_RANGE) {
BKE_colorband_evaluate(&U.coba_weight, weight, result);
}
else {
/* Use gamma correction to even out the color bands:
* increasing widens yellow/cyan vs red/green/blue.
* Gamma 1.0 produces the original 2.79 color ramp. */
const float gamma = 1.5f;
const float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)};
hsv_to_rgb_v(hsv, result);
for (int i = 0; i < 3; i++) {
result[i] = pow(result[i], 1.0f / gamma);
}
}
}
static GPUTexture *DRW_create_weight_colorramp_texture()
{
float pixels[256][4];
for (int i = 0; i < 256; i++) {
DRW_evaluate_weight_to_color(i / 255.0f, pixels[i]);
pixels[i][3] = 1.0f;
}
uchar4 pixels_ubyte[256];
for (int i = 0; i < 256; i++) {
unit_float_to_uchar_clamp_v4(pixels_ubyte[i], pixels[i]);
}
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ;
GPUTexture *tx = GPU_texture_create_1d("weight_ramp", 256, 1, GPU_SRGB8_A8, usage, nullptr);
GPU_texture_update(tx, GPU_DATA_UBYTE, pixels_ubyte);
return tx;
}

View File

@@ -34,7 +34,6 @@ class CurvesModule;
BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)
void DRW_globals_update();
void DRW_globals_free();
/* draw_hair.cc */
@@ -99,8 +98,5 @@ struct DRW_Global {
GlobalsUboStorage block;
/** Define "globalsBlock" uniform for 'block'. */
GPUUniformBuf *block_ubo;
GPUTexture *ramp;
GPUTexture *weight_ramp;
};
extern DRW_Global G_draw;

View File

@@ -2860,14 +2860,11 @@ void DRW_engines_free()
DRW_shaders_free();
DRW_pointcloud_free();
DRW_volume_free();
DRW_globals_free();
drw_debug_module_free(DST.debug);
DST.debug = nullptr;
GPU_UBO_FREE_SAFE(G_draw.block_ubo);
GPU_TEXTURE_FREE_SAFE(G_draw.ramp);
GPU_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
DRW_gpu_context_disable();
}