Page 1 of 1

Graphics API Implementation

Posted: Tue Aug 30, 2022 5:15 pm
by devc1
Hello, I almost don't have any experience with graphics API's (DirectX, OpenGL, Vulkan...), so I need to implement a 3d and 2d graphics api for Windowing and such things, I only have a function for drawing rectangles, cubic beziers (with unlimited points) and I draw a line using the bezier algorithm. However if it is a big curved line it appears as a bunch of points.
Straight Forward :
How does Graphics API's work?
how they communicate with user and gpu?
some basic drawing algorithms?
fix for the bezier curve problem of the uncomplete path of points.
Rasterizer algorithm to rasterize vertexes (it will also solve my TTF Drawing problem)
I also don't know alot about the basics of graphics.

Thanks !
Devc1,

Re: Graphics API Implementation

Posted: Tue Aug 30, 2022 8:16 pm
by AndrewAPrice
For connecting points, look up line drawing algorithms. Then draw a line between your disconnected dots.

For how programs and GPUs interact, look up low level apis such as Vulcan and Metal. Basically, context switching for each "draw polygon" is slow, so a common method is to fill up a buffer with commands, and send it to the driver/GPU a huge batch of operations at once.

Re: Graphics API Implementation

Posted: Wed Aug 31, 2022 2:11 am
by devc1
I thinked of this but it seems too slow, I will need to think of a better way, is this what make 3d graphics need a huge gpu ? And resolution makes things slower ?

I think of an algorithm to calculate the increment value of the curved path for the variable "t" then I'll just do :

Code: Select all

double Inc = (APINAME)2DInternalsCalculateLineIncrementValue(NumCoordinates, Coordinates)
COORD Cordinates = {0};
for(double t = 0;t < 1;t+=Inc)
{
       (APINAME)2DInternalsGetLinePixel(NumCoordinates, Coordinates, t)
       SetPixel () // Set the pixel in the screen object or plane or whatever ....
}
An optimization from me is to pack the results at four functions, then use SIMD (SSE, AVX, AVX512) to do computations in parallel. Assuming that coordinates must be 32 bits, then we can for example multiply 4 32 bit values at once and so on.
Then minimise procedure calls, by implementing Internals as Inline.

Re: Graphics API Implementation

Posted: Wed Aug 31, 2022 2:31 pm
by AndrewAPrice
There are many line drawing algorithms out there. Bresenham's is popular and fast.

Yes, drawing at higher resolutions is be slower than low resolutions, because there are more pixels to fill.

An optimization is to cache the results to a buffer or texture. For example, if you request 'a' in 'Arial' at 14pt, then create a small buffer, draw 'a' to it once, then everywhere you want to draw 'a' in "Arial' at 14pt, you just copy the pre-rendered texture.

Re: Graphics API Implementation

Posted: Wed Aug 31, 2022 3:00 pm
by devc1
This is useful but I still can't figure out the number of pixels in a curved bezier to use the "double t" function in a big line without seing disconnected pixels.

Re: Graphics API Implementation

Posted: Fri Sep 02, 2022 6:21 am
by devc1
Any answers ??

I tried using the distance between points at t = 0.1 and t = 0.2 and divide the increment value by distance + 1

the result is this :

Image

however there is no anti-aliasing.

edit : whatever increment of "t" I set there was always a small gap between pixels. this is because I computed coordinates in my function as INT16, and not "double". Fixed !

This seems to work no matter how big is the curved line, I can post my method if you want !

Any algorithm to do an Anti-Aliasing on this line ??

Re: Graphics API Implementation

Posted: Fri Sep 02, 2022 8:20 am
by devc1
However the start and end of the path are not that much clean, why ?

What's wrong with my (old, unoptimized) code :

Code: Select all

int16_t GetBezierPoint(double* cordinates, UINT16 cordinate_length, double percent){
	double values[25] = { 0 }; // Currently only 25 coordinates can be used
	memset(values,0,sizeof(double)*cordinate_length);
	for(UINT64 a = 0;a<cordinate_length-1;a++){
		values[a] = (cordinates[a] + ((cordinates[a+1]-cordinates[a])*percent));
	}
	double cvalues[4] = { 0 };
	for(UINT64 i = 2;i<cordinate_length;i++){
		memset(cvalues,0,sizeof(double)*(4-i));
	for(UINT64 a = 0;a<cordinate_length-i;a++){
		cvalues[a] = (values[a] + ((values[a+1]-values[a]) * percent));
	}
	memset(values,0,sizeof(values));
	for(UINT64 a = 0;a<cordinate_length-i;a++){
		values[a] = cvalues[a];
	}
	}
return (INT16)values[0];
}

Re: Graphics API Implementation

Posted: Fri Sep 02, 2022 9:58 pm
by AndrewAPrice
From a quick Google search, all drawing algorithms recommend breaking the curve down in intervals and connecting the points via lines.

If you go to draw your line and find that your length is too long, you can always step backwards by a smaller interval.

For aliasing, you have a few options.

One is to use an antialiased drawing algorithm:
https://en.wikipedia.org/wiki/Xiaolin_W ... _algorithm

Xiaolin Wu's like algorithm allows you to start/stop lines at points not exactly aligned with pixels, and should give you a super smooth line.

The other is the draw into a buffer many times the final resolution, and then average the colors together to produce the final pixel.

Re: Graphics API Implementation

Posted: Sat Sep 03, 2022 5:48 am
by devc1
Since I will forcibly need to implement 3D, I think of the subpixel-rendering, and the MSAA Algorithms but I can't find any useful references that are easy to understand. I've changed my bezier drawing multilineal function using a very much faster one and now I am recreating it using SIMD Parallel-Computing and Data-Processing Extensions. I will create AVX and AVX512 Variants later. The problem is that to benifit from these SIMD registers (instead of RAM) you will need a bunch of ASM Macros, for storing and using them.

The function is currently like this :

Code: Select all

extern inline UINT64 GetBezierPoint(double* cordinates, double* beta, UINT8 NumCordinates, double percent){
	if(!NumCordinates || NumCordinates > 0x80) return 0;
	_SSE_BezierCopyCords(beta, cordinates, NumCordinates);
	return _SSE_ComputeBezier(beta, NumCordinates, percent);
}
Does extern inline help ??

Re: Graphics API Implementation

Posted: Sat Sep 03, 2022 2:57 pm
by devc1
Guys, how to rasterize impaired intersections ? Do I just double the middle intersection into 2 intersections and rasterize it ?

Re: Graphics API Implementation

Posted: Sun Sep 04, 2022 6:35 am
by AndrewAPrice
Can you explain what you mean by impaired intersections?

Re: Graphics API Implementation

Posted: Sun Sep 04, 2022 4:20 pm
by Gigasoft
Are you talking about points like this?

Code: Select all

/------------\
|       *    /
| *    / \  /
|/ \  /   \/
    \/
Yes, in that case you need to keep track of multiple contour pairs at once. If you mean something else then I have no idea.

Re: Graphics API Implementation

Posted: Sun Sep 18, 2022 5:11 am
by devc1
How I track these contours, do you mean to just double the middle intersection to get valid pairs of intersections ?