The goal is to solve confusion of the "All rights reserved" for licensing
code under an open-source license.
The phrase "All rights reserved" comes from a historical convention that
required this phrase for the copyright protection to apply. This convention
is no longer relevant.
However, even though the phrase has no meaning in establishing the copyright
it has not lost meaning in terms of licensing.
This change makes it so code under the Blender Foundation copyright does
not use "all rights reserved". This is also how the GPL license itself
states how to apply it to the source code:
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software ...
This change does not change copyright notice in cases when the copyright
is dual (BF and an author), or just an author of the code. It also does
mot change copyright which is inherited from NaN Holding BV as it needs
some further investigation about what is the proper way to handle it.
391 lines
12 KiB
C
391 lines
12 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2016 Blender Foundation */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_math.h"
|
|
#include "BLI_threads.h"
|
|
#include "BLI_utildefines.h"
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "GPU_batch.h"
|
|
#include "GPU_batch_presets.h" /* Own include. */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Local Structures
|
|
* \{ */
|
|
|
|
/* Struct to store 3D Batches and their format */
|
|
static struct {
|
|
struct {
|
|
GPUBatch *sphere_high;
|
|
GPUBatch *sphere_med;
|
|
GPUBatch *sphere_low;
|
|
GPUBatch *sphere_wire_low;
|
|
GPUBatch *sphere_wire_med;
|
|
} batch;
|
|
|
|
GPUVertFormat format;
|
|
|
|
struct {
|
|
uint pos, nor;
|
|
} attr_id;
|
|
|
|
ThreadMutex mutex;
|
|
} g_presets_3d = {{0}};
|
|
|
|
static struct {
|
|
struct {
|
|
GPUBatch *panel_drag_widget;
|
|
GPUBatch *quad;
|
|
} batch;
|
|
|
|
float panel_drag_widget_pixelsize;
|
|
float panel_drag_widget_width;
|
|
float panel_drag_widget_col_high[4];
|
|
float panel_drag_widget_col_dark[4];
|
|
|
|
GPUVertFormat format;
|
|
|
|
struct {
|
|
uint pos, col;
|
|
} attr_id;
|
|
} g_presets_2d = {{0}};
|
|
|
|
static ListBase presets_list = {NULL, NULL};
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name 3D Primitives
|
|
* \{ */
|
|
|
|
static GPUVertFormat *preset_3d_format(void)
|
|
{
|
|
if (g_presets_3d.format.attr_len == 0) {
|
|
GPUVertFormat *format = &g_presets_3d.format;
|
|
g_presets_3d.attr_id.pos = GPU_vertformat_attr_add(
|
|
format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
g_presets_3d.attr_id.nor = GPU_vertformat_attr_add(
|
|
format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
}
|
|
return &g_presets_3d.format;
|
|
}
|
|
|
|
static GPUVertFormat *preset_2d_format(void)
|
|
{
|
|
if (g_presets_2d.format.attr_len == 0) {
|
|
GPUVertFormat *format = &g_presets_2d.format;
|
|
g_presets_2d.attr_id.pos = GPU_vertformat_attr_add(
|
|
format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
g_presets_2d.attr_id.col = GPU_vertformat_attr_add(
|
|
format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
}
|
|
return &g_presets_2d.format;
|
|
}
|
|
|
|
static void batch_sphere_lat_lon_vert(GPUVertBufRaw *pos_step,
|
|
GPUVertBufRaw *nor_step,
|
|
float lat,
|
|
float lon)
|
|
{
|
|
float pos[3];
|
|
pos[0] = sinf(lat) * cosf(lon);
|
|
pos[1] = cosf(lat);
|
|
pos[2] = sinf(lat) * sinf(lon);
|
|
copy_v3_v3(GPU_vertbuf_raw_step(pos_step), pos);
|
|
copy_v3_v3(GPU_vertbuf_raw_step(nor_step), pos);
|
|
}
|
|
GPUBatch *GPU_batch_preset_sphere(int lod)
|
|
{
|
|
BLI_assert(lod >= 0 && lod <= 2);
|
|
BLI_assert(BLI_thread_is_main());
|
|
|
|
if (lod == 0) {
|
|
return g_presets_3d.batch.sphere_low;
|
|
}
|
|
if (lod == 1) {
|
|
return g_presets_3d.batch.sphere_med;
|
|
}
|
|
|
|
return g_presets_3d.batch.sphere_high;
|
|
}
|
|
|
|
GPUBatch *GPU_batch_preset_sphere_wire(int lod)
|
|
{
|
|
BLI_assert(lod >= 0 && lod <= 1);
|
|
BLI_assert(BLI_thread_is_main());
|
|
|
|
if (lod == 0) {
|
|
return g_presets_3d.batch.sphere_wire_low;
|
|
}
|
|
|
|
return g_presets_3d.batch.sphere_wire_med;
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Create Sphere (3D)
|
|
* \{ */
|
|
|
|
static GPUBatch *gpu_batch_sphere(int lat_res, int lon_res)
|
|
{
|
|
const float lon_inc = 2 * M_PI / lon_res;
|
|
const float lat_inc = M_PI / lat_res;
|
|
float lon, lat;
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_3d_format());
|
|
const uint vbo_len = (lat_res - 1) * lon_res * 6;
|
|
GPU_vertbuf_data_alloc(vbo, vbo_len);
|
|
|
|
GPUVertBufRaw pos_step, nor_step;
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step);
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step);
|
|
|
|
lon = 0.0f;
|
|
for (int i = 0; i < lon_res; i++, lon += lon_inc) {
|
|
lat = 0.0f;
|
|
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
|
|
if (j != lat_res - 1) { /* Pole */
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
|
|
}
|
|
|
|
if (j != 0) { /* Pole */
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon + lon_inc);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
|
|
}
|
|
}
|
|
}
|
|
|
|
BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step));
|
|
BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step));
|
|
|
|
return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
}
|
|
|
|
static GPUBatch *batch_sphere_wire(int lat_res, int lon_res)
|
|
{
|
|
const float lon_inc = 2 * M_PI / lon_res;
|
|
const float lat_inc = M_PI / lat_res;
|
|
float lon, lat;
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_3d_format());
|
|
const uint vbo_len = (lat_res * lon_res * 2) + ((lat_res - 1) * lon_res * 2);
|
|
GPU_vertbuf_data_alloc(vbo, vbo_len);
|
|
|
|
GPUVertBufRaw pos_step, nor_step;
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step);
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step);
|
|
|
|
lon = 0.0f;
|
|
for (int i = 0; i < lon_res; i++, lon += lon_inc) {
|
|
lat = 0.0f;
|
|
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat, lon);
|
|
|
|
if (j != lat_res - 1) { /* Pole */
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon + lon_inc);
|
|
batch_sphere_lat_lon_vert(&pos_step, &nor_step, lat + lat_inc, lon);
|
|
}
|
|
}
|
|
}
|
|
|
|
BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step));
|
|
BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step));
|
|
|
|
return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Panel Drag Widget
|
|
* \{ */
|
|
|
|
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])
|
|
{
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y1});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y1});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y2});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y1});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y2});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
|
|
copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y2});
|
|
copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
|
|
}
|
|
|
|
static GPUBatch *gpu_batch_preset_panel_drag_widget(float pixelsize,
|
|
const float col_high[4],
|
|
const float col_dark[4],
|
|
const float width)
|
|
{
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_2d_format());
|
|
const uint vbo_len = 4 * 2 * (6 * 2);
|
|
GPU_vertbuf_data_alloc(vbo, vbo_len);
|
|
|
|
GPUVertBufRaw pos_step, col_step;
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.pos, &pos_step);
|
|
GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.col, &col_step);
|
|
|
|
const int px = (int)pixelsize;
|
|
const int px_zoom = max_ii(round_fl_to_int(width / 22.0f), 1);
|
|
|
|
const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
|
|
const int box_size = max_ii(round_fl_to_int((width / 8.0f) - px), px);
|
|
|
|
const int y_ofs = max_ii(round_fl_to_int(width / 2.5f), px);
|
|
const int x_ofs = y_ofs;
|
|
int i_x, i_y;
|
|
|
|
for (i_x = 0; i_x < 4; i_x++) {
|
|
for (i_y = 0; i_y < 2; i_y++) {
|
|
const int x_co = (x_ofs) + (i_x * (box_size + box_margin));
|
|
const int y_co = (y_ofs) + (i_y * (box_size + box_margin));
|
|
|
|
gpu_batch_preset_rectf_tris_color_ex(&pos_step,
|
|
x_co - box_size,
|
|
y_co - px_zoom,
|
|
x_co,
|
|
(y_co + box_size) - px_zoom,
|
|
&col_step,
|
|
col_dark);
|
|
gpu_batch_preset_rectf_tris_color_ex(
|
|
&pos_step, x_co - box_size, y_co, x_co, y_co + box_size, &col_step, col_high);
|
|
}
|
|
}
|
|
return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
}
|
|
|
|
GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
|
|
const float col_high[4],
|
|
const float col_dark[4],
|
|
const float width)
|
|
{
|
|
const bool parameters_changed = (g_presets_2d.panel_drag_widget_pixelsize != pixelsize) ||
|
|
(g_presets_2d.panel_drag_widget_width != width) ||
|
|
!equals_v4v4(g_presets_2d.panel_drag_widget_col_high,
|
|
col_high) ||
|
|
!equals_v4v4(g_presets_2d.panel_drag_widget_col_dark, col_dark);
|
|
|
|
if (g_presets_2d.batch.panel_drag_widget && parameters_changed) {
|
|
gpu_batch_presets_unregister(g_presets_2d.batch.panel_drag_widget);
|
|
GPU_batch_discard(g_presets_2d.batch.panel_drag_widget);
|
|
g_presets_2d.batch.panel_drag_widget = NULL;
|
|
}
|
|
|
|
if (!g_presets_2d.batch.panel_drag_widget) {
|
|
g_presets_2d.batch.panel_drag_widget = gpu_batch_preset_panel_drag_widget(
|
|
pixelsize, col_high, col_dark, width);
|
|
gpu_batch_presets_register(g_presets_2d.batch.panel_drag_widget);
|
|
g_presets_2d.panel_drag_widget_pixelsize = pixelsize;
|
|
g_presets_2d.panel_drag_widget_width = width;
|
|
copy_v4_v4(g_presets_2d.panel_drag_widget_col_high, col_high);
|
|
copy_v4_v4(g_presets_2d.panel_drag_widget_col_dark, col_dark);
|
|
}
|
|
return g_presets_2d.batch.panel_drag_widget;
|
|
}
|
|
|
|
GPUBatch *GPU_batch_preset_quad(void)
|
|
{
|
|
if (!g_presets_2d.batch.quad) {
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_2d_format());
|
|
GPU_vertbuf_data_alloc(vbo, 4);
|
|
|
|
float pos_data[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}};
|
|
GPU_vertbuf_attr_fill(vbo, g_presets_2d.attr_id.pos, pos_data);
|
|
/* Don't fill the color. */
|
|
|
|
g_presets_2d.batch.quad = GPU_batch_create_ex(
|
|
GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
gpu_batch_presets_register(g_presets_2d.batch.quad);
|
|
}
|
|
return g_presets_2d.batch.quad;
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Preset Registration Management
|
|
* \{ */
|
|
|
|
void gpu_batch_presets_init(void)
|
|
{
|
|
BLI_mutex_init(&g_presets_3d.mutex);
|
|
|
|
/* Hard coded resolution */
|
|
g_presets_3d.batch.sphere_low = gpu_batch_sphere(8, 16);
|
|
gpu_batch_presets_register(g_presets_3d.batch.sphere_low);
|
|
|
|
g_presets_3d.batch.sphere_med = gpu_batch_sphere(16, 10);
|
|
gpu_batch_presets_register(g_presets_3d.batch.sphere_med);
|
|
|
|
g_presets_3d.batch.sphere_high = gpu_batch_sphere(32, 24);
|
|
gpu_batch_presets_register(g_presets_3d.batch.sphere_high);
|
|
|
|
g_presets_3d.batch.sphere_wire_low = batch_sphere_wire(6, 8);
|
|
gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_low);
|
|
|
|
g_presets_3d.batch.sphere_wire_med = batch_sphere_wire(8, 16);
|
|
gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_med);
|
|
}
|
|
|
|
void gpu_batch_presets_register(GPUBatch *preset_batch)
|
|
{
|
|
BLI_mutex_lock(&g_presets_3d.mutex);
|
|
BLI_addtail(&presets_list, BLI_genericNodeN(preset_batch));
|
|
BLI_mutex_unlock(&g_presets_3d.mutex);
|
|
}
|
|
|
|
bool gpu_batch_presets_unregister(GPUBatch *preset_batch)
|
|
{
|
|
BLI_mutex_lock(&g_presets_3d.mutex);
|
|
for (LinkData *link = presets_list.last; link; link = link->prev) {
|
|
if (preset_batch == link->data) {
|
|
BLI_remlink(&presets_list, link);
|
|
BLI_mutex_unlock(&g_presets_3d.mutex);
|
|
MEM_freeN(link);
|
|
return true;
|
|
}
|
|
}
|
|
BLI_mutex_unlock(&g_presets_3d.mutex);
|
|
return false;
|
|
}
|
|
|
|
void gpu_batch_presets_exit(void)
|
|
{
|
|
LinkData *link;
|
|
while ((link = BLI_pophead(&presets_list))) {
|
|
GPUBatch *preset = link->data;
|
|
GPU_batch_discard(preset);
|
|
MEM_freeN(link);
|
|
}
|
|
|
|
BLI_mutex_end(&g_presets_3d.mutex);
|
|
}
|
|
|
|
/** \} */
|