Blender V4.3
gpu_batch_presets.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_listbase.h"
11#include "BLI_threads.h"
12#include "BLI_utildefines.h"
13
14#include "MEM_guardedalloc.h"
15
16#include "GPU_batch.hh"
17#include "GPU_batch_presets.hh" /* Own include. */
18
19/* -------------------------------------------------------------------- */
22
23/* Struct to store 3D Batches and their format */
24static struct {
25 struct {
26 blender::gpu::Batch *sphere_high;
27 blender::gpu::Batch *sphere_med;
28 blender::gpu::Batch *sphere_low;
29 blender::gpu::Batch *sphere_wire_low;
30 blender::gpu::Batch *sphere_wire_med;
32
34
35 struct {
38
40} g_presets_3d = {{nullptr}};
41
42static struct {
43 struct {
44 blender::gpu::Batch *panel_drag_widget;
45 blender::gpu::Batch *quad;
46 } batch;
47
52
54
55 struct {
57 } attr_id;
58} g_presets_2d = {{nullptr}};
59
60static ListBase presets_list = {nullptr, nullptr};
61
63
64/* -------------------------------------------------------------------- */
67
69{
70 if (g_presets_3d.format.attr_len == 0) {
76 }
77 return g_presets_3d.format;
78}
79
81{
82 if (g_presets_2d.format.attr_len == 0) {
87 format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
88 }
89 return g_presets_2d.format;
90}
91
93 GPUVertBufRaw *nor_step,
94 float lat,
95 float lon)
96{
97 float pos[3];
98 pos[0] = sinf(lat) * cosf(lon);
99 pos[1] = cosf(lat);
100 pos[2] = sinf(lat) * sinf(lon);
101 copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), pos);
102 copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(nor_step)), pos);
103}
104blender::gpu::Batch *GPU_batch_preset_sphere(int lod)
105{
106 BLI_assert(lod >= 0 && lod <= 2);
108
109 if (lod == 0) {
110 return g_presets_3d.batch.sphere_low;
111 }
112 if (lod == 1) {
113 return g_presets_3d.batch.sphere_med;
114 }
115
116 return g_presets_3d.batch.sphere_high;
117}
118
119blender::gpu::Batch *GPU_batch_preset_sphere_wire(int lod)
120{
121 BLI_assert(lod >= 0 && lod <= 1);
123
124 if (lod == 0) {
125 return g_presets_3d.batch.sphere_wire_low;
126 }
127
128 return g_presets_3d.batch.sphere_wire_med;
129}
130
132
133/* -------------------------------------------------------------------- */
136
137static blender::gpu::Batch *gpu_batch_sphere(int lat_res, int lon_res)
138{
139 const float lon_inc = 2 * M_PI / lon_res;
140 const float lat_inc = M_PI / lat_res;
141 float lon, lat;
142
144 const uint vbo_len = (lat_res - 1) * lon_res * 6;
145 GPU_vertbuf_data_alloc(*vbo, vbo_len);
146
147 GPUVertBufRaw pos_step, nor_step;
148 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step);
149 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step);
150
151 lon = 0.0f;
152 for (int i = 0; i < lon_res; i++, lon += lon_inc) {
153 lat = 0.0f;
154 for (int j = 0; j < lat_res; j++, lat += lat_inc) {
155 if (j != lat_res - 1) { /* Pole */
156 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
157 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
158 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
159 }
160
161 if (j != 0) { /* Pole */
162 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon + lon_inc);
163 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
164 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
165 }
166 }
167 }
168
169 BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step));
170 BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step));
171
173}
174
175static blender::gpu::Batch *batch_sphere_wire(int lat_res, int lon_res)
176{
177 const float lon_inc = 2 * M_PI / lon_res;
178 const float lat_inc = M_PI / lat_res;
179 float lon, lat;
180
182 const uint vbo_len = (lat_res * lon_res * 2) + ((lat_res - 1) * lon_res * 2);
183 GPU_vertbuf_data_alloc(*vbo, vbo_len);
184
185 GPUVertBufRaw pos_step, nor_step;
186 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step);
187 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step);
188
189 lon = 0.0f;
190 for (int i = 0; i < lon_res; i++, lon += lon_inc) {
191 lat = 0.0f;
192 for (int j = 0; j < lat_res; j++, lat += lat_inc) {
193 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
194 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
195
196 if (j != lat_res - 1) { /* Pole */
197 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
198 batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
199 }
200 }
201 }
202
203 BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step));
204 BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step));
205
207}
208
210
211/* -------------------------------------------------------------------- */
214
216 float x1,
217 float y1,
218 float x2,
219 float y2,
220 GPUVertBufRaw *col_step,
221 const float color[4])
222{
223 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x1, y1});
224 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
225
226 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x2, y1});
227 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
228
229 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x2, y2});
230 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
231
232 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x1, y1});
233 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
234
235 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x2, y2});
236 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
237
238 copy_v2_v2(static_cast<float *>(GPU_vertbuf_raw_step(pos_step)), blender::float2{x1, y2});
239 copy_v4_v4(static_cast<float *>(GPU_vertbuf_raw_step(col_step)), color);
240}
241
242static blender::gpu::Batch *gpu_batch_preset_panel_drag_widget(float pixelsize,
243 const float col_high[4],
244 const float col_dark[4],
245 const float width)
246{
248 const uint vbo_len = 4 * 2 * (6 * 2);
249 GPU_vertbuf_data_alloc(*vbo, vbo_len);
250
251 GPUVertBufRaw pos_step, col_step;
252 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.pos, &pos_step);
253 GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.col, &col_step);
254
255 const int px = int(pixelsize);
256 const int px_zoom = max_ii(round_fl_to_int(width / 22.0f), 1);
257
258 const int box_margin = max_ii(round_fl_to_int(float(px_zoom * 2.0f)), px);
259 const int box_size = max_ii(round_fl_to_int((width / 8.0f) - px), px);
260
261 const int y_ofs = max_ii(round_fl_to_int(width / 2.5f), px);
262 const int x_ofs = y_ofs;
263 int i_x, i_y;
264
265 for (i_x = 0; i_x < 4; i_x++) {
266 for (i_y = 0; i_y < 2; i_y++) {
267 const int x_co = (x_ofs) + (i_x * (box_size + box_margin));
268 const int y_co = (y_ofs) + (i_y * (box_size + box_margin));
269
271 x_co - box_size,
272 y_co - px_zoom,
273 x_co,
274 (y_co + box_size) - px_zoom,
275 &col_step,
276 col_dark);
278 &pos_step, x_co - box_size, y_co, x_co, y_co + box_size, &col_step, col_high);
279 }
280 }
282}
283
284blender::gpu::Batch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
285 const float col_high[4],
286 const float col_dark[4],
287 const float width)
288{
289 const bool parameters_changed = (g_presets_2d.panel_drag_widget_pixelsize != pixelsize) ||
290 (g_presets_2d.panel_drag_widget_width != width) ||
291 !equals_v4v4(g_presets_2d.panel_drag_widget_col_high,
292 col_high) ||
293 !equals_v4v4(g_presets_2d.panel_drag_widget_col_dark, col_dark);
294
295 if (g_presets_2d.batch.panel_drag_widget && parameters_changed) {
296 gpu_batch_presets_unregister(g_presets_2d.batch.panel_drag_widget);
297 GPU_batch_discard(g_presets_2d.batch.panel_drag_widget);
298 g_presets_2d.batch.panel_drag_widget = nullptr;
299 }
300
301 if (!g_presets_2d.batch.panel_drag_widget) {
302 g_presets_2d.batch.panel_drag_widget = gpu_batch_preset_panel_drag_widget(
303 pixelsize, col_high, col_dark, width);
304 gpu_batch_presets_register(g_presets_2d.batch.panel_drag_widget);
305 g_presets_2d.panel_drag_widget_pixelsize = pixelsize;
306 g_presets_2d.panel_drag_widget_width = width;
307 copy_v4_v4(g_presets_2d.panel_drag_widget_col_high, col_high);
308 copy_v4_v4(g_presets_2d.panel_drag_widget_col_dark, col_dark);
309 }
310 return g_presets_2d.batch.panel_drag_widget;
311}
312
313blender::gpu::Batch *GPU_batch_preset_quad()
314{
315 if (!g_presets_2d.batch.quad) {
317 GPU_vertbuf_data_alloc(*vbo, 4);
318
319 float pos_data[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}};
320 GPU_vertbuf_attr_fill(vbo, g_presets_2d.attr_id.pos, pos_data);
321 /* Don't fill the color. */
322
325
327 }
328 return g_presets_2d.batch.quad;
329}
330
332
333/* -------------------------------------------------------------------- */
336
338{
340
341 /* Hard coded resolution */
342 g_presets_3d.batch.sphere_low = gpu_batch_sphere(8, 16);
344
345 g_presets_3d.batch.sphere_med = gpu_batch_sphere(16, 10);
347
348 g_presets_3d.batch.sphere_high = gpu_batch_sphere(32, 24);
349 gpu_batch_presets_register(g_presets_3d.batch.sphere_high);
350
351 g_presets_3d.batch.sphere_wire_low = batch_sphere_wire(6, 8);
352 gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_low);
353
354 g_presets_3d.batch.sphere_wire_med = batch_sphere_wire(8, 16);
355 gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_med);
356}
357
358void gpu_batch_presets_register(blender::gpu::Batch *preset_batch)
359{
363}
364
365bool gpu_batch_presets_unregister(blender::gpu::Batch *preset_batch)
366{
369 if (preset_batch == link->data) {
372 MEM_freeN(link);
373 return true;
374 }
375 }
377 return false;
378}
379
381{
382 while (LinkData *link = static_cast<LinkData *>(BLI_pophead(&presets_list))) {
383 blender::gpu::Batch *preset = static_cast<blender::gpu::Batch *>(link->data);
384 GPU_batch_discard(preset);
385 MEM_freeN(link);
386 }
387
388 /* Reset pointers to null for subsequent initializations after tear-down. */
389 g_presets_2d = {{nullptr}};
390 g_presets_3d = {{nullptr}};
391 presets_list = {nullptr, nullptr};
392
394}
395
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
struct LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:909
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:251
MINLINE int round_fl_to_int(float a)
MINLINE int max_ii(int a, int b)
#define M_PI
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
void BLI_mutex_end(ThreadMutex *mutex)
Definition threads.cc:360
void BLI_mutex_init(ThreadMutex *mutex)
Definition threads.cc:340
int BLI_thread_is_main(void)
Definition threads.cc:179
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:83
ThreadMutex mutex
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
Definition gpu_batch.cc:56
void GPU_batch_discard(blender::gpu::Batch *batch)
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:42
@ GPU_PRIM_LINES
@ GPU_PRIM_TRI_STRIP
@ GPU_PRIM_TRIS
void GPU_vertbuf_attr_get_raw_data(blender::gpu::VertBuf *, uint a_idx, GPUVertBufRaw *access)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
GPU_INLINE uint GPU_vertbuf_raw_used(const GPUVertBufRaw *a)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
#define sinf(x)
#define cosf(x)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static blender::gpu::Batch * batch_sphere_wire(int lat_res, int lon_res)
blender::gpu::Batch * panel_drag_widget
blender::gpu::Batch * sphere_high
static ListBase presets_list
blender::gpu::Batch * GPU_batch_preset_quad()
float panel_drag_widget_width
static GPUVertFormat & preset_3d_format()
static GPUVertFormat & preset_2d_format()
bool gpu_batch_presets_unregister(blender::gpu::Batch *preset_batch)
void gpu_batch_presets_register(blender::gpu::Batch *preset_batch)
void gpu_batch_presets_init()
static void batch_sphere_lat_lon_vert(GPUVertBufRaw *pos_step, GPUVertBufRaw *nor_step, float lat, float lon)
blender::gpu::Batch * sphere_wire_low
static struct @157336070235062372277311340362362342103123126032 g_presets_3d
static struct @173166146123024354131051042022317337175111041006 g_presets_2d
static blender::gpu::Batch * gpu_batch_sphere(int lat_res, int lon_res)
blender::gpu::Batch * quad
float panel_drag_widget_col_high[4]
blender::gpu::Batch * sphere_low
blender::gpu::Batch * GPU_batch_preset_panel_drag_widget(const float pixelsize, const float col_high[4], const float col_dark[4], const float width)
uint col
float panel_drag_widget_pixelsize
static void gpu_batch_preset_rectf_tris_color_ex(GPUVertBufRaw *pos_step, float x1, float y1, float x2, float y2, GPUVertBufRaw *col_step, const float color[4])
blender::gpu::Batch * sphere_wire_med
static blender::gpu::Batch * gpu_batch_preset_panel_drag_widget(float pixelsize, const float col_high[4], const float col_dark[4], const float width)
blender::gpu::Batch * GPU_batch_preset_sphere_wire(int lod)
blender::gpu::Batch * GPU_batch_preset_sphere(int lod)
void gpu_batch_presets_exit()
blender::gpu::Batch * sphere_med
struct @157336070235062372277311340362362342103123126032::@132215023242101136103363133227133264017254024241 attr_id
struct @157336070235062372277311340362362342103123126032::@262166344314164341202215145112231240022370055142 batch
float panel_drag_widget_col_dark[4]
format
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
VecBase< float, 2 > float2
Frequency::GEOMETRY nor[]