GPU_batch: Add GPU_batch_wire_from_poly_2d_encoded
Draws wire around polygon shapes: better visibility w/ any background color.
This commit is contained in:
parent
e969ac6413
commit
a3716f5945
|
@ -69,7 +69,7 @@ typedef struct ButtonManipulator2D {
|
|||
bool is_init;
|
||||
/* Use an icon or shape */
|
||||
int icon;
|
||||
Gwn_Batch *shape_batch;
|
||||
Gwn_Batch *shape_batch[2];
|
||||
} ButtonManipulator2D;
|
||||
|
||||
#define CIRCLE_RESOLUTION 32
|
||||
|
@ -114,7 +114,8 @@ static void button2d_draw_intern(
|
|||
/* We shouldn't need the +1, but a NULL char is set. */
|
||||
char *polys = MEM_mallocN(polys_len + 1, __func__);
|
||||
RNA_property_string_get(mpr->ptr, prop, polys);
|
||||
button->shape_batch = GPU_batch_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
|
||||
button->shape_batch[0] = GPU_batch_tris_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
|
||||
button->shape_batch[1] = GPU_batch_wire_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
|
||||
MEM_freeN(polys);
|
||||
}
|
||||
}
|
||||
|
@ -131,11 +132,21 @@ static void button2d_draw_intern(
|
|||
glEnable(GL_BLEND);
|
||||
|
||||
if (select == false) {
|
||||
if (button->shape_batch != NULL) {
|
||||
if (button->shape_batch[0] != NULL) {
|
||||
glEnable(GL_POLYGON_SMOOTH);
|
||||
GWN_batch_program_set_builtin(button->shape_batch, GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
GWN_batch_uniform_4f(button->shape_batch, "color", UNPACK4(color));
|
||||
GWN_batch_draw(button->shape_batch);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.0f);
|
||||
for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) {
|
||||
GWN_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
GWN_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
|
||||
GWN_batch_draw(button->shape_batch[i]);
|
||||
if (i == 0) {
|
||||
/* Invert line color. */
|
||||
color[0] = 1.0f - color[0];
|
||||
color[1] = 1.0f - color[1];
|
||||
color[2] = 1.0f - color[2];
|
||||
}
|
||||
}
|
||||
glDisable(GL_POLYGON_SMOOTH);
|
||||
gpuPopMatrix();
|
||||
}
|
||||
|
@ -203,7 +214,10 @@ static int manipulator_button2d_cursor_get(wmManipulator *UNUSED(mpr))
|
|||
static void manipulator_button2d_free(wmManipulator *mpr)
|
||||
{
|
||||
ButtonManipulator2D *shape = (ButtonManipulator2D *)mpr;
|
||||
GWN_BATCH_DISCARD_SAFE(shape->shape_batch);
|
||||
|
||||
for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) {
|
||||
GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -201,6 +201,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmManipulatorG
|
|||
mpr->ptr, prop,
|
||||
(const char *)info->shape, info->shape_size);
|
||||
/* don't fade icons so much */
|
||||
copy_v3_fl(mpr->color, 0.0f);
|
||||
mpr->color[3] = 0.5f;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,10 @@ struct rctf;
|
|||
/* gpu_batch.c */
|
||||
void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id) ATTR_NONNULL(1);
|
||||
|
||||
Gwn_Batch *GPU_batch_from_poly_2d_encoded(
|
||||
Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded(
|
||||
const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect
|
||||
) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded(
|
||||
const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect
|
||||
) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "BLI_rect.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_polyfill2d.h"
|
||||
#include "BLI_sort_utils.h"
|
||||
|
||||
|
||||
#include "GPU_batch.h" /* own include */
|
||||
|
@ -67,11 +68,11 @@ void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id)
|
|||
* \param polys_flat_len: Length of the array (must be an even number).
|
||||
* \param rect: Optional region to map the byte 0..255 coords to. When not set use -1..1.
|
||||
*/
|
||||
Gwn_Batch *GPU_batch_from_poly_2d_encoded(
|
||||
Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded(
|
||||
const uchar *polys_flat, uint polys_flat_len, const rctf *rect)
|
||||
{
|
||||
uchar (*polys)[2] = (void *)polys_flat;
|
||||
uint polys_len = polys_flat_len / 2;
|
||||
const uchar (*polys)[2] = (const void *)polys_flat;
|
||||
const uint polys_len = polys_flat_len / 2;
|
||||
BLI_assert(polys_flat_len == polys_len * 2);
|
||||
|
||||
/* Over alloc in both cases */
|
||||
|
@ -100,10 +101,10 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
|
|||
if (polys[i_poly - 1][0] == polys[i_poly][0] &&
|
||||
polys[i_poly - 1][1] == polys[i_poly][1])
|
||||
{
|
||||
const uint verts_len = (&verts[i_vert]) - verts_step;
|
||||
BLI_assert(verts_len >= 3);
|
||||
const uint tris_len = (verts_len - 2);
|
||||
BLI_polyfill_calc(verts_step, verts_len, -1, tris_step);
|
||||
const uint verts_step_len = (&verts[i_vert]) - verts_step;
|
||||
BLI_assert(verts_step_len >= 3);
|
||||
const uint tris_len = (verts_step_len - 2);
|
||||
BLI_polyfill_calc(verts_step, verts_step_len, -1, tris_step);
|
||||
/* offset indices */
|
||||
if (verts_step != verts) {
|
||||
uint *t = tris_step[0];
|
||||
|
@ -115,8 +116,8 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
|
|||
}
|
||||
BLI_assert(t == tris_step[tris_len]);
|
||||
}
|
||||
verts_step += verts_len;
|
||||
tris_step += (verts_len - 2);
|
||||
verts_step += verts_step_len;
|
||||
tris_step += tris_len;
|
||||
i_poly++;
|
||||
/* ignore the duplicate point */
|
||||
}
|
||||
|
@ -157,6 +158,108 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
|
|||
GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
|
||||
}
|
||||
|
||||
Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded(
|
||||
const uchar *polys_flat, uint polys_flat_len, const rctf *rect)
|
||||
{
|
||||
const uchar (*polys)[2] = (const void *)polys_flat;
|
||||
const uint polys_len = polys_flat_len / 2;
|
||||
BLI_assert(polys_flat_len == polys_len * 2);
|
||||
|
||||
/* Over alloc */
|
||||
int32_t *lines = MEM_mallocN(sizeof(*lines) * polys_len, __func__);
|
||||
int32_t *lines_step = lines;
|
||||
|
||||
const float range_uchar[2] = {
|
||||
(rect ? (rect->xmax - rect->xmin) : 2.0f) / 255.0f,
|
||||
(rect ? (rect->ymax - rect->ymin) : 2.0f) / 255.0f,
|
||||
};
|
||||
const float min_uchar[2] = {
|
||||
(rect ? rect->xmin : -1.0f),
|
||||
(rect ? rect->ymin : -1.0f),
|
||||
};
|
||||
|
||||
const bool hide_lines = true;
|
||||
|
||||
uint i_poly_prev = 0;
|
||||
uint i_poly = 0;
|
||||
while (i_poly != polys_len) {
|
||||
i_poly++;
|
||||
if (polys[i_poly - 1][0] == polys[i_poly][0] &&
|
||||
polys[i_poly - 1][1] == polys[i_poly][1])
|
||||
{
|
||||
const uchar (*polys_step)[2] = polys + i_poly_prev;
|
||||
const uint polys_step_len = i_poly - i_poly_prev;
|
||||
BLI_assert(polys_step_len >= 2);
|
||||
for (uint i_prev = polys_step_len - 1, i = 0; i < polys_step_len; i_prev = i++) {
|
||||
union {
|
||||
uint8_t as_u8[4];
|
||||
uint16_t as_u16[2];
|
||||
uint32_t as_u32;
|
||||
} data;
|
||||
data.as_u16[0] = *((const uint16_t *)polys_step[i_prev]);
|
||||
data.as_u16[1] = *((const uint16_t *)polys_step[i]);
|
||||
if (data.as_u16[0] > data.as_u16[1]) {
|
||||
SWAP(uint16_t, data.as_u16[0], data.as_u16[1]);
|
||||
}
|
||||
*lines_step = data.as_u32;
|
||||
lines_step++;
|
||||
}
|
||||
i_poly++;
|
||||
i_poly_prev = i_poly;
|
||||
/* ignore the duplicate point */
|
||||
}
|
||||
}
|
||||
|
||||
uint lines_len = (lines_step - lines);
|
||||
uint lines_hide_len = 0;
|
||||
if (hide_lines) {
|
||||
qsort(lines, lines_len, sizeof(int32_t), BLI_sortutil_cmp_int);
|
||||
for (uint i_prev = 0, i = 1; i < lines_len; i_prev = i++) {
|
||||
if ((lines[i] == lines[i_prev])) {
|
||||
lines_hide_len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We have vertices and tris, make a batch from this. */
|
||||
static Gwn_VertFormat format = {0};
|
||||
static struct { uint pos; } attr_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
|
||||
GWN_vertbuf_data_alloc(vbo, (lines_len - lines_hide_len) * 2);
|
||||
|
||||
Gwn_VertBufRaw pos_step;
|
||||
GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
|
||||
|
||||
for (uint i = 0; i < lines_len; i++) {
|
||||
if (hide_lines) {
|
||||
if ((i + 1 != lines_len) && (lines[i + 1] == lines[i])) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
union {
|
||||
uint8_t as_u8_pair[2][2];
|
||||
uint32_t as_u32;
|
||||
} data;
|
||||
data.as_u32 = lines[i];
|
||||
for (uint k = 0; k < 2; k++) {
|
||||
float *pos_v2 = GWN_vertbuf_raw_step(&pos_step);
|
||||
for (uint j = 0; j < 2; j++) {
|
||||
pos_v2[j] = min_uchar[j] + ((float)data.as_u8_pair[k][j] * range_uchar[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MEM_freeN(lines);
|
||||
return GWN_batch_create_ex(
|
||||
GWN_PRIM_LINES, vbo,
|
||||
NULL,
|
||||
GWN_BATCH_OWNS_VBO);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue