We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3597 - Inconsistent implementation of logical versus physical window dimensions / coordinates
Summary: Inconsistent implementation of logical versus physical window dimensions / co...
Status: ASSIGNED
Alias: None
Product: SDL
Classification: Unclassified
Component: render (show other bugs)
Version: 2.0.5
Hardware: x86_64 Windows 10
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-01 22:07 UTC by MichaelIbison
Modified: 2017-08-11 19:12 UTC (History)
1 user (show)

See Also:


Attachments
jpg of pentagram drawn using SDL_RenderDrawLine superimposed on noise (5.78 MB, image/jpeg)
2017-03-01 22:07 UTC, MichaelIbison
Details

Note You need to log in before you can comment on or make changes to this bug.
Description MichaelIbison 2017-03-01 22:07:28 UTC
Created attachment 2700 [details]
jpg of pentagram drawn using SDL_RenderDrawLine superimposed on noise

When physical & logical dimensions differ SDL_RenderDrawLine() behaves strangely. 

Generally, but not always

SDL_RenderDrawLine(r,x1,y1,x2,y2) 

draws a line from logical coordinate (x1,y1) to logical coordinate (x2,y2) but at the *physical* resolution, not the logical resolution. Though the start and end points are correctly interpreted, the line is comprised of (filled-in / written-to) pixels at the physical, rather than logical resolution.

An exception is if x1==x2 or y1==y2, i.e. if the line is vertical or horizontal. In *that* case the line is drawn at the logical resolution.

To illustrate, when the physical dimensions of the display are exactly 40 times the logical dimensions, the routine PLT_DrawWheel() (below) called as 

PLT_DrawWheel(r, 0, 255, 255, 5, 0.9, 0.0, 0.0);

gives a pentagram which in the attached image is superimposed on gray-level noise rendered at the logical resolution. Notice how the lines that are not vertical or horizontal terminate at the 'corners' of the logical resolution pixels. 

Ideally, one would want to be able to choose between these two types of behavior. In any case, having them applied inconsistently is a bug.


---------------------------------------------------------------------

#include <math.h>
#include <SDL.h>

#define PI 3.14159265359
#define CVT_TO_INT(x) ((int)round(x))

void PLT_DrawWheel(SDL_Renderer* r, Uint8 red, Uint8 green, Uint8 blue, int numSpokes,  double rimSize, double hubSize /* in [0,1] - relative to window */, double angularOffset /* in [0,1] */)
{
int w,h,i;
SDL_RenderGetLogicalSize(r,&w,&h);
SDL_SetRenderDrawColor(r,red,green,blue,ALPHA_MASK);

double originX=(((double)w)/2.0);
double originY=(((double)h)/2.0);
double hubRadius=hubSize * ((double)h)/2.0;
double rimRadius=rimSize * ((double)h)/2.0;


for(i=0;i<numSpokes;i++)
	{
	double angle1 = 2.0*PI*(angularOffset + ((double)i)/((double)numSpokes));
	double angle2 = 2.0*PI*(angularOffset + ((double)(i+1))/((double)numSpokes));

	int p1=CVT_TO_INT(originX+hubRadius*cos(angle1));
	int q1=CVT_TO_INT(originY+hubRadius*sin(angle1));
        int p2=CVT_TO_INT(originX+hubRadius*cos(angle2));
	int q2=CVT_TO_INT(originY+hubRadius*sin(angle2));

        int x1=CVT_TO_INT(originX+rimRadius*cos(angle1));
	int y1=CVT_TO_INT(originY+rimRadius*sin(angle1));
        int x2=CVT_TO_INT(originX+rimRadius*cos(angle2));
	int y2=CVT_TO_INT(originY+rimRadius*sin(angle2));

/* The statements commented out below trap and adjust the horizontal and vertical cases as a work-around to the rendering inconsistency. */

   // (p1==x1) x1++;
   // if (q1==y1) y1++;
        SDL_RenderDrawLine(r,p1,q1,x1,y1);
   //if (x1==x2) x2++;
   //if (y1==y2) y2++;
        SDL_RenderDrawLine(r,x1,y1,x2,y2);
	//if (p1==p2) p2++;
   //if (q1==q2) q2++; 
        SDL_RenderDrawLine(r,p1,q1,p2,q2);
	}
SDL_RenderPresent(r);
}
Comment 1 Sam Lantinga 2017-08-11 19:12:15 UTC
Yes, this is because texture and fill can be changed to sub-pixel precision, but we don't currently have sub-pixel line widths in the rendering drivers.