Skip to content

Commit

Permalink
Added the hint SDL_HINT_RENDER_LINE_METHOD to select the line renderi…
Browse files Browse the repository at this point in the history
…ng method
  • Loading branch information
slouken committed Jan 8, 2022
1 parent 836a4ec commit 09ece86
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
13 changes: 13 additions & 0 deletions include/SDL_hints.h
Expand Up @@ -1059,6 +1059,19 @@ extern "C" {
*/
#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING"

/**
* \brief A variable controlling how the 2D render API renders lines
*
* This variable can be set to the following values:
* "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20)
* "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points)
* "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20)
* "3" - Use the driver geometry API (correct, draws thicker diagonal lines)
*
* This variable should be set when the renderer is created.
*/
#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD"

/**
* \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer.
*
Expand Down
42 changes: 35 additions & 7 deletions src/render/SDL_render.c
Expand Up @@ -896,6 +896,26 @@ void VerifyDrawQueueFunctions(const SDL_Renderer *renderer)
SDL_assert(renderer->RunCommandQueue != NULL);
}

static SDL_RenderLineMethod SDL_GetRenderLineMethod()
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_LINE_METHOD);

int method = 0;
if (hint) {
method = SDL_atoi(hint);
}
switch (method) {
case 1:
return SDL_RENDERLINEMETHOD_POINTS;
case 2:
return SDL_RENDERLINEMETHOD_LINES;
case 3:
return SDL_RENDERLINEMETHOD_GEOMETRY;
default:
return SDL_RENDERLINEMETHOD_POINTS;
}
}

SDL_Renderer *
SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
{
Expand Down Expand Up @@ -1011,6 +1031,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)

renderer->relative_scaling = SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_SCALING, SDL_TRUE);

renderer->line_method = SDL_GetRenderLineMethod();

if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) {
renderer->hidden = SDL_TRUE;
} else {
Expand Down Expand Up @@ -1062,6 +1084,9 @@ SDL_CreateSoftwareRenderer(SDL_Surface * surface)
/* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */
renderer->render_command_generation = 1;

/* Software renderer always uses line method, for speed */
renderer->line_method = SDL_RENDERLINEMETHOD_LINES;

SDL_RenderSetViewport(renderer, NULL);
}
return renderer;
Expand Down Expand Up @@ -2794,6 +2819,10 @@ static int plotLineLow(SDL_Renderer *renderer, float x0, float y0, float x1, flo
SDL_FPoint *points = SDL_small_alloc(SDL_FPoint, count, &isstack);
SDL_FPoint *tmp = points;

if (!points) {
return SDL_OutOfMemory();
}

if (dy < 0) {
yi = -1;
dy = -dy;
Expand Down Expand Up @@ -2837,6 +2866,10 @@ static int plotLineHigh(SDL_Renderer *renderer, float x0, float y0, float x1, fl
SDL_FPoint *points = SDL_small_alloc(SDL_FPoint, count, &isstack);
SDL_FPoint *tmp = points;

if (!points) {
return SDL_OutOfMemory();
}

if (dx < 0) {
xi = -1;
dx = -dx;
Expand Down Expand Up @@ -2999,8 +3032,6 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
const SDL_FPoint * points, int count)
{
int retval = 0;
int use_renderpoints;
int use_rendergeometry;

CHECK_RENDERER_MAGIC(renderer, -1);

Expand All @@ -3018,12 +3049,9 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
}
#endif

use_renderpoints = 1;
use_rendergeometry = 1;

if (use_renderpoints) {
if (renderer->line_method == SDL_RENDERLINEMETHOD_POINTS) {
retval = RenderDrawLinesWithRectsF(renderer, points, count);
} else if (use_rendergeometry) {
} else if (renderer->line_method == SDL_RENDERLINEMETHOD_GEOMETRY) {
SDL_bool isstack1;
SDL_bool isstack2;
const float scale_x = renderer->scale.x;
Expand Down
11 changes: 11 additions & 0 deletions src/render/SDL_sysrender.h
Expand Up @@ -114,6 +114,14 @@ typedef struct SDL_VertexSolid
} SDL_VertexSolid;


typedef enum
{
SDL_RENDERLINEMETHOD_POINTS,
SDL_RENDERLINEMETHOD_LINES,
SDL_RENDERLINEMETHOD_GEOMETRY,
} SDL_RenderLineMethod;


/* Define the SDL renderer structure */
struct SDL_Renderer
{
Expand Down Expand Up @@ -214,6 +222,9 @@ struct SDL_Renderer
/* Whether or not to scale relative mouse motion */
SDL_bool relative_scaling;

/* The method of drawing lines */
SDL_RenderLineMethod line_method;

/* Remainder from scaled relative motion */
float xrel;
float yrel;
Expand Down

0 comments on commit 09ece86

Please sign in to comment.