Well! Apart from having a nice little travel into London to see the family and a haircut, what have I been up to today you ask? The answer to that resides in my Colour graphics library! Its not very often that I improve on my libraries unless I need to, or I’m bored as I’m not a particularly large fan of programming in the first place, its just the easiest and fastest way for me to get a useful end product!
ANYWAY, with regards to the library what additions have I made?
- Colour creation through percentage and the ColP(r,g,b) function. This allows 16bit colour words to be created from colour percentages. You can still send the raw 16bit words to my functions, but who on earth enjoys compiling a 16bit RGB565 colour from scratch, not me! I’ve also got a ColIP(c, p) function which produces the colour bits with respect to percentages shifted to the correct 16bit region. The ColP function is actually 3 ColIP calls, all OR’d together!
- A triangle function! Triangles in 3 dimensions are a pretty important part of computer graphics as they allow complex surfaces to be made from simple blocks. I’m going to be adding a second Triangle function soon for non-equilateral triangles but until then, this one shall suffice! The function is Triangle(x, y, l, a, c) where x, y is the position of the centre of the triangle, l is the side length, a is the angle where 0deg is the triangle pointing up and 180deg is the triangle pointing down and finally, c is the colour. In the video, you can see that the triangle isn’t layering upon previously drawn triangles and I do this by drawing a black triangle over the previous triangle at the exact same co-ordinates, essentially erasing the old triangle without refreshing the whole screen
- A much more efficient PChar, PStr and PNum set of functions which utilize mathematical methods of devising the size scaling. The PChar function has the choice between using essentially infinite sizes or a set of faster predefined sizes (0 to 4). The reason for this is because the Sizes parameter divides certain variables if the “infinite” method is used. The predefined sizes eradicates the divisions.
- More efficient Rect and FillRec functions. Previously, a rectangle was drawn with a for loop setting pixels along the edge. For easier code decoding, I just used my cartesian line function to draw these pixels. Not much more efficient as drawing a single pixel requires 7 SPI writes (THAT is slow considering at top speed on the STM32F0, one pixel write takes 0.333uS meaning that writing one pixel takes 2.33uS! If you wanted to fill the screen using pixel writes one by one, it would take 38ms, of course ignoring any overhead). This is fixed partially in the FillRec function. Previously, the FillRec had the same method of filling in the rectangle drawn. It used two for loops, drawing pixels in the region defined by the edges. This was really inefficient and large filled rectangles took ages to draw! I took advantage of one of the ILI9163 hardware functions which allows a certain area of memory to be mapped linearly, allowing me to set the area of memory to the area inside of the edges and then just writing the pixel data, meaning that each pixel write is two SPI writes (just for clarification – one SPI write is 8bits).
- A couple of additional integrated functions. My main aim is to eradicate the need for any of the standard C libraries as these generally eat a lot of space. I’ve managed to get rid of math.h and string.h by creating my own abs, sin, pow and strlen functions. These are written to be relatively fast, especially sin. The sine function, qSin(x) returns the sine value where x is in degrees within the range of a 32bit integer. The returned value is 11 bits and will be between 1024 and -1024. To imitate multiplying by a floating point value, one can merely do (a*qSin(x))>>10 which first multiplies by the returned value then shifts down by 10 bits to imitate a decimal. The sine approximation is somewhat poor as it uses two quadratics to approximate a sine wave (an -x^2 quadratic looks like a sinewave from 0-180deg and an x^2 quadratic looks like the rest! All you need to do is move the Y of each section accordingly). The other functions are pretty simple. The IAbs(x) function returns X if X>0 and -X if X<0. The FPow function uses a loop to multiply a number by the original number X amount of times. This only works for positive integer powers! The StrLen(x) function returns the length of a string by counting through the string until the ” terminator character is found.
- One thing to note, since the qSin is an approximation, anything that uses it is affected meaning LineP (Line with polar co-ordinates), Circle, Ellipse, Semicircle and triangle. The approximation is most visible with the Circle as it causes the circle to look pretty boxy instead of circular! A better sine approximation would solve this, or more so, a better circle approximation in general, such as the Bresenham version.
The fabled boxy circle! As the resolution isn’t infinite too, the circle sometimes has glitches in, this will be improved… at some point!
Thats pretty much all of the improvements as of yet. Its only part of a nights worth of work so I’m not expecting big things just yet! I’ve written a new simple demo program too:
I don’t see why my test code would be particularly useful to anyone, but in case it is, you can find it on my github. Note however: None of this code is well commented so sorry if its hard to follow in parts!