Metal: GPU_PRIM_LINE_LOOP alternative implementations.
Prefer using immVertex3f when 3D shaders are used for 2D rendering due to overhead of vertex padding in hardware. CPU overhead is negligible. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D14494
This commit is contained in:
parent
e28f07b5c8
commit
8f0e06a0ca
Notes:
blender-bot
2023-02-14 01:11:05 +01:00
Referenced by issue #96261, Metal Viewport
|
@ -524,6 +524,15 @@ MINLINE uint max_uu(uint a, uint b)
|
|||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
MINLINE unsigned long long min_ulul(unsigned long long a, unsigned long long b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
MINLINE unsigned long long max_ulul(unsigned long long a, unsigned long long b)
|
||||
{
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
MINLINE float min_fff(float a, float b, float c)
|
||||
{
|
||||
return min_ff(min_ff(a, b), c);
|
||||
|
|
|
@ -82,9 +82,35 @@ void wm_gizmo_vec_draw(
|
|||
const float color[4], const float (*verts)[3], uint vert_count, uint pos, uint primitive_type)
|
||||
{
|
||||
immUniformColor4fv(color);
|
||||
immBegin(primitive_type, vert_count);
|
||||
for (int i = 0; i < vert_count; i++) {
|
||||
immVertex3fv(pos, verts[i]);
|
||||
|
||||
if (primitive_type == GPU_PRIM_LINE_LOOP) {
|
||||
/* Line loop alternative for Metal/Vulkan. */
|
||||
immBegin(GPU_PRIM_LINES, vert_count * 2);
|
||||
immVertex3fv(pos, verts[0]);
|
||||
for (int i = 1; i < vert_count; i++) {
|
||||
immVertex3fv(pos, verts[i]);
|
||||
immVertex3fv(pos, verts[i]);
|
||||
}
|
||||
immVertex3fv(pos, verts[0]);
|
||||
immEnd();
|
||||
}
|
||||
else if (primitive_type == GPU_PRIM_TRI_FAN) {
|
||||
/* Note(Metal): Tri-fan alternative for Metal. Triangle List is more efficient for small
|
||||
* primitive counts. */
|
||||
int tri_count = vert_count - 2;
|
||||
immBegin(GPU_PRIM_TRIS, tri_count * 3);
|
||||
for (int i = 0; i < tri_count; i++) {
|
||||
immVertex3fv(pos, verts[0]);
|
||||
immVertex3fv(pos, verts[i + 1]);
|
||||
immVertex3fv(pos, verts[i + 2]);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
immBegin(primitive_type, vert_count);
|
||||
for (int i = 0; i < vert_count; i++) {
|
||||
immVertex3fv(pos, verts[i]);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
|
|
@ -74,20 +74,21 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
|
|||
GPU_viewport_size_get_f(viewport);
|
||||
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
/* Note(Metal): Prefer 3D coordinate for 2D rendering when using 3D shader. */
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
/* TODO: other draw styles. */
|
||||
if (color[3] == 1.0 && fill_alpha == 1.0 && select == false) {
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(color);
|
||||
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
|
||||
immUnbindProgram();
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
immUniform2fv("viewportSize", &viewport[2]);
|
||||
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
|
||||
immUniformColor4fv(color);
|
||||
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
|
||||
immUnbindProgram();
|
||||
}
|
||||
else {
|
||||
|
@ -96,7 +97,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
|
|||
const float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]};
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(fill_color);
|
||||
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
|
|||
immUniform2fv("viewportSize", &viewport[2]);
|
||||
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
|
||||
immUniformColor4fv(color);
|
||||
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
|
||||
immUnbindProgram();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,8 @@ static void cage2d_draw_box_corners(const rctf *r,
|
|||
const float color[3],
|
||||
const float line_width)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
/* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
immUniformColor3fv(color);
|
||||
|
@ -112,25 +113,25 @@ static void cage2d_draw_box_corners(const rctf *r,
|
|||
|
||||
immBegin(GPU_PRIM_LINES, 16);
|
||||
|
||||
immVertex2f(pos, r->xmin, r->ymin + margin[1]);
|
||||
immVertex2f(pos, r->xmin, r->ymin);
|
||||
immVertex2f(pos, r->xmin, r->ymin);
|
||||
immVertex2f(pos, r->xmin + margin[0], r->ymin);
|
||||
immVertex3f(pos, r->xmin, r->ymin + margin[1], 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmin + margin[0], r->ymin, 0.0f);
|
||||
|
||||
immVertex2f(pos, r->xmax, r->ymin + margin[1]);
|
||||
immVertex2f(pos, r->xmax, r->ymin);
|
||||
immVertex2f(pos, r->xmax, r->ymin);
|
||||
immVertex2f(pos, r->xmax - margin[0], r->ymin);
|
||||
immVertex3f(pos, r->xmax, r->ymin + margin[1], 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmax - margin[0], r->ymin, 0.0f);
|
||||
|
||||
immVertex2f(pos, r->xmax, r->ymax - margin[1]);
|
||||
immVertex2f(pos, r->xmax, r->ymax);
|
||||
immVertex2f(pos, r->xmax, r->ymax);
|
||||
immVertex2f(pos, r->xmax - margin[0], r->ymax);
|
||||
immVertex3f(pos, r->xmax, r->ymax - margin[1], 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmax - margin[0], r->ymax, 0.0f);
|
||||
|
||||
immVertex2f(pos, r->xmin, r->ymax - margin[1]);
|
||||
immVertex2f(pos, r->xmin, r->ymax);
|
||||
immVertex2f(pos, r->xmin, r->ymax);
|
||||
immVertex2f(pos, r->xmin + margin[0], r->ymax);
|
||||
immVertex3f(pos, r->xmin, r->ymax - margin[1], 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmin + margin[0], r->ymax, 0.0f);
|
||||
|
||||
immEnd();
|
||||
|
||||
|
@ -440,12 +441,35 @@ static void cage2d_draw_box_interaction(const float color[4],
|
|||
static void imm_draw_point_aspect_2d(
|
||||
uint pos, float x, float y, float rad_x, float rad_y, bool solid)
|
||||
{
|
||||
immBegin(solid ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
|
||||
immVertex2f(pos, x - rad_x, y - rad_y);
|
||||
immVertex2f(pos, x - rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y - rad_y);
|
||||
immEnd();
|
||||
if (solid) {
|
||||
/* Note(Metal/AMD): Small Triangle-list primitives more optimal for GPU HW than Trianglestrip.
|
||||
*/
|
||||
immBegin(GPU_PRIM_TRIS, 6);
|
||||
immVertex2f(pos, x - rad_x, y - rad_y);
|
||||
immVertex2f(pos, x - rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y + rad_y);
|
||||
|
||||
immVertex2f(pos, x - rad_x, y - rad_y);
|
||||
immVertex2f(pos, x + rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y - rad_y);
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
/* Note(Metal/AMD): Small Line-list primitives more optimal for GPU HW than Linestrip. */
|
||||
immBegin(GPU_PRIM_LINES, 8);
|
||||
immVertex2f(pos, x - rad_x, y - rad_y);
|
||||
immVertex2f(pos, x - rad_x, y + rad_y);
|
||||
|
||||
immVertex2f(pos, x - rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y + rad_y);
|
||||
|
||||
immVertex2f(pos, x + rad_x, y + rad_y);
|
||||
immVertex2f(pos, x + rad_x, y - rad_y);
|
||||
|
||||
immVertex2f(pos, x + rad_x, y - rad_y);
|
||||
immVertex2f(pos, x - rad_x, y - rad_y);
|
||||
immEnd();
|
||||
}
|
||||
}
|
||||
|
||||
static void cage2d_draw_circle_wire(const rctf *r,
|
||||
|
@ -455,7 +479,9 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
const int draw_options,
|
||||
const float line_width)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
/* Note(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's.
|
||||
*/
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
immUniformColor3fv(color);
|
||||
|
@ -465,17 +491,28 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
immUniform2fv("viewportSize", &viewport[2]);
|
||||
immUniform1f("lineWidth", line_width * U.pixelsize);
|
||||
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
immVertex2f(pos, r->xmin, r->ymin);
|
||||
immVertex2f(pos, r->xmax, r->ymin);
|
||||
immVertex2f(pos, r->xmax, r->ymax);
|
||||
immVertex2f(pos, r->xmin, r->ymax);
|
||||
/* Small 'lines' primitives more efficient for hardware processing than linestrip. */
|
||||
immBegin(GPU_PRIM_LINES, 8);
|
||||
immVertex3f(pos, r->xmin, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymin, 0.0f);
|
||||
|
||||
immVertex3f(pos, r->xmax, r->ymin, 0.0f);
|
||||
immVertex3f(pos, r->xmax, r->ymax, 0.0f);
|
||||
|
||||
immVertex3f(pos, r->xmax, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymax, 0.0f);
|
||||
|
||||
immVertex3f(pos, r->xmin, r->ymax, 0.0f);
|
||||
immVertex3f(pos, r->xmin, r->ymin, 0.0f);
|
||||
immEnd();
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 2);
|
||||
immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax);
|
||||
immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]);
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
|
||||
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
|
@ -485,10 +522,10 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
|
||||
immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
|
||||
immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
|
||||
immVertex2f(pos, center[0] - rad[0], center[1] + rad[1]);
|
||||
immVertex3f(pos, center[0] - rad[0], center[1] - rad[1], 0.0f);
|
||||
immVertex3f(pos, center[0] + rad[0], center[1] + rad[1], 0.0f);
|
||||
immVertex3f(pos, center[0] + rad[0], center[1] - rad[1], 0.0f);
|
||||
immVertex3f(pos, center[0] - rad[0], center[1] + rad[1], 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,8 @@ static void dial_geom_draw(const float color[4],
|
|||
ED_GIZMO_DIAL_DRAW_FLAG_FILL)));
|
||||
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
/* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
if (clip_plane) {
|
||||
immBindBuiltinProgram(filled ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR :
|
||||
|
@ -114,18 +115,19 @@ static void dial_geom_draw(const float color[4],
|
|||
if (filled) {
|
||||
if (arc_partial_angle == 0.0f) {
|
||||
if (arc_inner_factor == 0.0f) {
|
||||
imm_draw_circle_fill_2d(pos, 0, 0, 1.0, DIAL_RESOLUTION);
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
|
||||
}
|
||||
else {
|
||||
imm_draw_disk_partial_fill_2d(
|
||||
pos, 0, 0, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
|
||||
imm_draw_disk_partial_fill_3d(
|
||||
pos, 0.0f, 0.0f, 0.0f, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
|
||||
imm_draw_disk_partial_fill_2d(pos,
|
||||
0,
|
||||
0,
|
||||
imm_draw_disk_partial_fill_3d(pos,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
arc_inner_factor,
|
||||
1.0f,
|
||||
DIAL_RESOLUTION,
|
||||
|
@ -140,15 +142,15 @@ static void dial_geom_draw(const float color[4],
|
|||
immUniform1f("lineWidth", line_width * U.pixelsize);
|
||||
|
||||
if (arc_partial_angle == 0.0f) {
|
||||
imm_draw_circle_wire_2d(pos, 0, 0, 1.0, DIAL_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
|
||||
if (arc_inner_factor != 0.0f) {
|
||||
imm_draw_circle_wire_2d(pos, 0, 0, arc_inner_factor, DIAL_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, arc_inner_factor, DIAL_RESOLUTION);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
|
||||
imm_draw_circle_partial_wire_2d(
|
||||
pos, 0, 0, 1.0, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
|
||||
imm_draw_circle_partial_wire_3d(
|
||||
pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
|
||||
# if 0
|
||||
if (arc_inner_factor != 0.0f) {
|
||||
BLI_assert(0);
|
||||
|
@ -186,7 +188,7 @@ static void dial_ghostarc_draw_helpline(const float angle,
|
|||
immUniformColor4fv(color);
|
||||
|
||||
immBegin(GPU_PRIM_LINE_STRIP, 2);
|
||||
immVertex3f(pos, 0.0f, 0, 0.0f);
|
||||
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
|
||||
immVertex3fv(pos, co_outer);
|
||||
immEnd();
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ static void move_geom_draw(const wmGizmo *gz,
|
|||
ED_GIZMO_MOVE_DRAW_FLAG_FILL)));
|
||||
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
/* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(filled ? GPU_SHADER_3D_UNIFORM_COLOR :
|
||||
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
|
@ -115,20 +116,20 @@ static void move_geom_draw(const wmGizmo *gz,
|
|||
|
||||
if (draw_style == ED_GIZMO_MOVE_STYLE_RING_2D) {
|
||||
if (filled) {
|
||||
imm_draw_circle_fill_2d(pos, 0, 0, radius, DIAL_RESOLUTION);
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
|
||||
}
|
||||
else {
|
||||
imm_draw_circle_wire_2d(pos, 0, 0, radius, DIAL_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
|
||||
}
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_MOVE_STYLE_CROSS_2D) {
|
||||
const float radius_diag = M_SQRT1_2 * radius;
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
immVertex2f(pos, radius_diag, radius_diag);
|
||||
immVertex2f(pos, -radius_diag, -radius_diag);
|
||||
immVertex3f(pos, radius_diag, radius_diag, 0.0f);
|
||||
immVertex3f(pos, -radius_diag, -radius_diag, 0.0f);
|
||||
|
||||
immVertex2f(pos, -radius_diag, radius_diag);
|
||||
immVertex2f(pos, radius_diag, -radius_diag);
|
||||
immVertex3f(pos, -radius_diag, radius_diag, 0.0f);
|
||||
immVertex3f(pos, radius_diag, -radius_diag, 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -80,6 +80,8 @@ void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegm
|
|||
*/
|
||||
void imm_draw_circle_partial_wire_2d(
|
||||
uint pos, float x, float y, float radius, int nsegments, float start, float sweep);
|
||||
void imm_draw_circle_partial_wire_3d(
|
||||
uint pos, float x, float y, float z, float radius, int nsegments, float start, float sweep);
|
||||
|
||||
/**
|
||||
* Draw a filled arc with the given inner and outer radius.
|
||||
|
@ -104,6 +106,15 @@ void imm_draw_disk_partial_fill_2d(uint pos,
|
|||
int nsegments,
|
||||
float start,
|
||||
float sweep);
|
||||
void imm_draw_disk_partial_fill_3d(uint pos,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
float rad_inner,
|
||||
float rad_outer,
|
||||
int nsegments,
|
||||
float start,
|
||||
float sweep);
|
||||
|
||||
/**
|
||||
* Draw a lined box.
|
||||
|
|
|
@ -142,12 +142,27 @@ static void imm_draw_circle(GPUPrimType prim_type,
|
|||
float radius_y,
|
||||
int nsegments)
|
||||
{
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
const float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
|
||||
if (prim_type == GPU_PRIM_LINE_LOOP) {
|
||||
/* Note(Metal/AMD): For small primitives, line list more efficient than line strip.. */
|
||||
immBegin(GPU_PRIM_LINES, nsegments * 2);
|
||||
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(0.0f)), y + (radius_y * sinf(0.0f)));
|
||||
for (int i = 1; i < nsegments; i++) {
|
||||
const float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
|
||||
}
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(0.0f)), y + (radius_y * sinf(0.0f)));
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
const float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
|
||||
|
@ -194,12 +209,42 @@ static void imm_draw_circle_partial(GPUPrimType prim_type,
|
|||
immEnd();
|
||||
}
|
||||
|
||||
static void imm_draw_circle_partial_3d(GPUPrimType prim_type,
|
||||
uint pos,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
float rad,
|
||||
int nsegments,
|
||||
float start,
|
||||
float sweep)
|
||||
{
|
||||
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
|
||||
const float angle_start = -(DEG2RADF(start)) + (float)(M_PI / 2);
|
||||
const float angle_end = -(DEG2RADF(sweep) - angle_start);
|
||||
nsegments += 1;
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
const float angle = interpf(angle_start, angle_end, ((float)i / (float)(nsegments - 1)));
|
||||
const float angle_sin = sinf(angle);
|
||||
const float angle_cos = cosf(angle);
|
||||
immVertex3f(pos, x + rad * angle_cos, y + rad * angle_sin, z);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_circle_partial_wire_2d(
|
||||
uint pos, float x, float y, float radius, int nsegments, float start, float sweep)
|
||||
{
|
||||
imm_draw_circle_partial(GPU_PRIM_LINE_STRIP, pos, x, y, radius, nsegments, start, sweep);
|
||||
}
|
||||
|
||||
void imm_draw_circle_partial_wire_3d(
|
||||
uint pos, float x, float y, float z, float rad, int nsegments, float start, float sweep)
|
||||
{
|
||||
imm_draw_circle_partial_3d(GPU_PRIM_LINE_STRIP, pos, x, y, z, rad, nsegments, start, sweep);
|
||||
}
|
||||
|
||||
static void imm_draw_disk_partial(GPUPrimType prim_type,
|
||||
uint pos,
|
||||
float x,
|
||||
|
@ -229,6 +274,36 @@ static void imm_draw_disk_partial(GPUPrimType prim_type,
|
|||
immEnd();
|
||||
}
|
||||
|
||||
static void imm_draw_disk_partial_3d(GPUPrimType prim_type,
|
||||
uint pos,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
float rad_inner,
|
||||
float rad_outer,
|
||||
int nsegments,
|
||||
float start,
|
||||
float sweep)
|
||||
{
|
||||
/* to avoid artifacts */
|
||||
const float max_angle = 3 * 360;
|
||||
CLAMP(sweep, -max_angle, max_angle);
|
||||
|
||||
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
|
||||
const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
|
||||
const float angle_end = -(DEG2RADF(sweep) - angle_start);
|
||||
nsegments += 1;
|
||||
immBegin(prim_type, nsegments * 2);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
const float angle = interpf(angle_start, angle_end, ((float)i / (float)(nsegments - 1)));
|
||||
const float angle_sin = sinf(angle);
|
||||
const float angle_cos = cosf(angle);
|
||||
immVertex3f(pos, x + rad_inner * angle_cos, y + rad_inner * angle_sin, z);
|
||||
immVertex3f(pos, x + rad_outer * angle_cos, y + rad_outer * angle_sin, z);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_disk_partial_fill_2d(uint pos,
|
||||
float x,
|
||||
float y,
|
||||
|
@ -241,16 +316,44 @@ void imm_draw_disk_partial_fill_2d(uint pos,
|
|||
imm_draw_disk_partial(
|
||||
GPU_PRIM_TRI_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep);
|
||||
}
|
||||
void imm_draw_disk_partial_fill_3d(uint pos,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
float rad_inner,
|
||||
float rad_outer,
|
||||
int nsegments,
|
||||
float start,
|
||||
float sweep)
|
||||
{
|
||||
imm_draw_disk_partial_3d(
|
||||
GPU_PRIM_TRI_STRIP, pos, x, y, z, rad_inner, rad_outer, nsegments, start, sweep);
|
||||
}
|
||||
|
||||
static void imm_draw_circle_3D(
|
||||
GPUPrimType prim_type, uint pos, float x, float y, float radius, int nsegments)
|
||||
{
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
||||
if (prim_type == GPU_PRIM_LINE_LOOP) {
|
||||
/* Note(Metal/AMD): For small primitives, line list more efficient than line strip. */
|
||||
immBegin(GPU_PRIM_LINES, nsegments * 2);
|
||||
|
||||
immVertex3f(pos, x + radius * cosf(0.0f), y + radius * sinf(0.0f), 0.0f);
|
||||
for (int i = 1; i < nsegments; i++) {
|
||||
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
||||
}
|
||||
immVertex3f(pos, x + radius * cosf(0.0f), y + radius * sinf(0.0f), 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||
|
@ -270,22 +373,38 @@ void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegm
|
|||
|
||||
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
/* Note(Metal/AMD): For small primitives, line list more efficient than line-strip. */
|
||||
immBegin(GPU_PRIM_LINES, 8);
|
||||
immVertex2f(pos, x1, y1);
|
||||
immVertex2f(pos, x1, y2);
|
||||
|
||||
immVertex2f(pos, x1, y2);
|
||||
immVertex2f(pos, x2, y2);
|
||||
|
||||
immVertex2f(pos, x2, y2);
|
||||
immVertex2f(pos, x2, y1);
|
||||
|
||||
immVertex2f(pos, x2, y1);
|
||||
immVertex2f(pos, x1, y1);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
/* use this version when GPUVertFormat has a vec3 position */
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
/* Note(Metal/AMD): For small primitives, line list more efficient than line-strip. */
|
||||
immBegin(GPU_PRIM_LINES, 8);
|
||||
immVertex3f(pos, x1, y1, 0.0f);
|
||||
immVertex3f(pos, x1, y2, 0.0f);
|
||||
|
||||
immVertex3f(pos, x1, y2, 0.0f);
|
||||
immVertex3f(pos, x2, y2, 0.0f);
|
||||
|
||||
immVertex3f(pos, x2, y2, 0.0f);
|
||||
immVertex3f(pos, x2, y1, 0.0f);
|
||||
|
||||
immVertex3f(pos, x2, y1, 0.0f);
|
||||
immVertex3f(pos, x1, y1, 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue