Skip to content

Commit 6d52cab

Browse files
authored
Merge pull request scp-fs2open#1627 from asarium/fix/lineDrawList
Add a mechanism for batching line draw calls
2 parents aa60a63 + 2e0253e commit 6d52cab

14 files changed

Lines changed: 281 additions & 89 deletions

code/graphics/2d.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ struct vertex_format_data
216216
SCREEN_POS,
217217
COLOR3,
218218
COLOR4,
219+
COLOR4F,
219220
TEX_COORD2,
220221
TEX_COORD3,
221222
NORMAL,

code/graphics/line_draw_list.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
//
3+
4+
#include "line_draw_list.h"
5+
#include "2d.h"
6+
#include "material.h"
7+
#include "tracing/tracing.h"
8+
9+
namespace graphics {
10+
11+
line_draw_list::line_draw_list() {
12+
}
13+
void line_draw_list::add_line(int x1, int y1, int x2, int y2, int resize_mode) {
14+
add_vertex(x1, y1, resize_mode, &gr_screen.current_color);
15+
add_vertex(x2, y2, resize_mode, &gr_screen.current_color);
16+
}
17+
void line_draw_list::add_gradient(int x1, int y1, int x2, int y2, int resize_mode) {
18+
add_vertex(x1, y1, resize_mode, &gr_screen.current_color);
19+
20+
color endColor = gr_screen.current_color;
21+
endColor.alpha = 0;
22+
add_vertex(x2, y2, resize_mode, &endColor);
23+
}
24+
void line_draw_list::flush() {
25+
if (_line_vertices.empty()) {
26+
// Nothing to do here...
27+
return;
28+
}
29+
30+
GR_DEBUG_SCOPE("Line draw list flush");
31+
TRACE_SCOPE(tracing::LineDrawListFlush);
32+
33+
material line_mat;
34+
line_mat.set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
35+
line_mat.set_depth_mode(ZBUFFER_TYPE_NONE);
36+
line_mat.set_cull_mode(false);
37+
line_mat.set_color(1.0f, 1.0f, 1.0f, 1.0f); // Color is handled by the vertices
38+
39+
40+
vertex_layout layout;
41+
layout.add_vertex_component(vertex_format_data::POSITION2, sizeof(line_vertex), offsetof(line_vertex, position));
42+
layout.add_vertex_component(vertex_format_data::COLOR4F, sizeof(line_vertex), offsetof(line_vertex, color));
43+
44+
gr_render_primitives_2d_immediate(&line_mat,
45+
PRIM_TYPE_LINES,
46+
&layout,
47+
static_cast<int>(_line_vertices.size()),
48+
_line_vertices.data(),
49+
_line_vertices.size() * sizeof(line_vertex));
50+
51+
_line_vertices.clear();
52+
}
53+
void line_draw_list::add_vertex(int x, int y, int resize_mode, const color* color) {
54+
line_vertex vtx{};
55+
vtx.position.x = i2fl(x);
56+
vtx.position.y = i2fl(y);
57+
58+
gr_resize_screen_posf(&vtx.position.x, &vtx.position.y, nullptr, nullptr, resize_mode);
59+
vtx.color.xyzw.x = color->red / 255.f;
60+
vtx.color.xyzw.y = color->green / 255.f;
61+
vtx.color.xyzw.z = color->blue / 255.f;
62+
vtx.color.xyzw.w = color->is_alphacolor ? color->alpha / 255.f : 1.f;
63+
64+
_line_vertices.push_back(vtx);
65+
}
66+
67+
}

code/graphics/line_draw_list.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
#include "globalincs/pstypes.h"
4+
#include "2d.h"
5+
6+
namespace graphics {
7+
8+
/**
9+
* @brief A class for batching multiple line draw operations together
10+
*
11+
* This should be used when a lot of lines are going to be rendered together. The actual rendering operation will only
12+
* be done once flush() is called so the lines may overlap other objects that were rendered after the line was added to
13+
* this class.
14+
*/
15+
class line_draw_list {
16+
struct line_vertex {
17+
vec2d position;
18+
vec4 color;
19+
};
20+
SCP_vector<line_vertex> _line_vertices;
21+
22+
void add_vertex(int x, int y, int resize_mode, const color* color);
23+
public:
24+
line_draw_list();
25+
26+
/**
27+
* @brief Adds a line to this draw list. The coordinates are screen pixel positions.
28+
* @param x1 Start X-Coordinate of the line
29+
* @param y1 Start Y-Coordinate of the line
30+
* @param x2 End X-Coordinate of the line
31+
* @param y2 End Y-Coordinate of the line
32+
* @param resize_mode The resize mode of the screen position
33+
*/
34+
void add_line(int x1, int y1, int x2, int y2, int resize_mode = GR_RESIZE_FULL);
35+
36+
/**
37+
* @brief Adds a gradient to this draw list. The coordinates are screen pixel positions.
38+
*
39+
* A gradient is like a normal line but line will fade out towards the end of the line.
40+
*
41+
* @param x1 Start X-Coordinate of the line
42+
* @param y1 Start Y-Coordinate of the line
43+
* @param x2 End X-Coordinate of the line
44+
* @param y2 End Y-Coordinate of the line
45+
* @param resize_mode The resize mode of the screen position
46+
*/
47+
void add_gradient(int x1, int y1, int x2, int y2, int resize_mode = GR_RESIZE_FULL);
48+
49+
/**
50+
* @brief Flushes the stored line draws
51+
*
52+
* This will clear al previously drawn line segments so after this is called the instance can be filled with new
53+
* line draws.
54+
*/
55+
void flush();
56+
};
57+
58+
}
59+

code/graphics/opengl/gropengltnl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static opengl_vertex_bind GL_array_binding_data[] =
7575
{ vertex_format_data::SCREEN_POS, 2, GL_INT, GL_FALSE, opengl_vert_attrib::POSITION },
7676
{ vertex_format_data::COLOR3, 3, GL_UNSIGNED_BYTE, GL_TRUE,opengl_vert_attrib::COLOR },
7777
{ vertex_format_data::COLOR4, 4, GL_UNSIGNED_BYTE, GL_TRUE, opengl_vert_attrib::COLOR },
78+
{ vertex_format_data::COLOR4F, 4, GL_FLOAT, GL_FALSE, opengl_vert_attrib::COLOR },
7879
{ vertex_format_data::TEX_COORD2, 2, GL_FLOAT, GL_FALSE, opengl_vert_attrib::TEXCOORD },
7980
{ vertex_format_data::TEX_COORD3, 3, GL_FLOAT, GL_FALSE, opengl_vert_attrib::TEXCOORD },
8081
{ vertex_format_data::NORMAL, 3, GL_FLOAT, GL_FALSE, opengl_vert_attrib::NORMAL },

code/graphics/paths/NanoVGRenderer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// This code was adapted from the original NanoVG OpenGL renderer to work with the FreeSpace Open graphics API
2020

2121
#include "NanoVGRenderer.h"
22+
#include "tracing/tracing.h"
2223

2324
namespace {
2425
using namespace graphics::paths;
@@ -386,7 +387,9 @@ void NanoVGRenderer::renderFlush() {
386387
return;
387388
}
388389

390+
TRACE_SCOPE(tracing::NanoVGFlushFrame);
389391
GR_DEBUG_SCOPE("NanoVG flush");
392+
390393
gr_set_viewport(0, 0, gr_screen.max_w, gr_screen.max_h);
391394

392395
_uniformBuffer = gr_get_uniform_buffer(uniform_block_type::NanoVGData);
@@ -616,6 +619,7 @@ NanoVGRenderer::Image* NanoVGRenderer::getTexture(int id) {
616619

617620
void NanoVGRenderer::drawTriangles(const DrawCall& call) {
618621
GR_DEBUG_SCOPE("Draw triangles");
622+
TRACE_SCOPE(tracing::NanoVGDrawTriangles);
619623

620624
auto mat = _trianglesMaterial;
621625
materialSetTexture(mat, call.image);
@@ -629,6 +633,7 @@ void NanoVGRenderer::drawTriangles(const DrawCall& call) {
629633
}
630634
void NanoVGRenderer::drawFill(const DrawCall& call) {
631635
GR_DEBUG_SCOPE("Draw fill");
636+
TRACE_SCOPE(tracing::NanoVGDrawFill);
632637

633638
auto mat = _fillShapeMaterial;
634639
mat.set_texture_map(TM_BASE_TYPE, -1);
@@ -672,6 +677,7 @@ void NanoVGRenderer::drawFill(const DrawCall& call) {
672677
}
673678
void NanoVGRenderer::drawConvexFill(const DrawCall& call) {
674679
GR_DEBUG_SCOPE("Draw convex fill");
680+
TRACE_SCOPE(tracing::NanoVGDrawConvexFill);
675681

676682
auto mat = _triangleFillMaterial;
677683
materialSetTexture(mat, call.image);
@@ -704,6 +710,7 @@ void NanoVGRenderer::drawConvexFill(const DrawCall& call) {
704710
}
705711
void NanoVGRenderer::drawStroke(const DrawCall& call) {
706712
GR_DEBUG_SCOPE("Draw stroke");
713+
TRACE_SCOPE(tracing::NanoVGDrawStroke);
707714

708715
auto mat = _strokeFillMaterial;
709716
materialSetTexture(mat, call.image);

0 commit comments

Comments
 (0)