![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
TinyGL is a subset of OpenGL with a zlib license. It uses software rendering. For systems that cannot take full advantage of GPUs or high performance graphics drivers, TinyGL gives decent performance. It's been used on several small handheld devices and on less standard operating systems like Amiga clones and BeOS. It offers much of the functionality of OpenGL 1.1. PicoGL is a fork of TinyGL with several backends including SDL 1.2.x, nano-x, Vesa framebuffer and X11. More can easily be added. I've already added support for SDL 2.x. PicoGL also attempted to add fixed point support for systems that had issues with floating point representation.
I've been patching PicoGL since 2013 and have added several features. It's currently stable enough to use with an OpenGL application such as Emilia Pinball. I've looked at several TinyGL forks with similar licenses and attempted to add the best of these forks into my version of PicoGL. I've updated the math-ssl library to a later version that uses a MIT license instead of the original GPL 2 license.
Other modifications include switching to 32 bit internal representation. I added some missing functions. I coded support for blending textures. I fixed a lighting issue that's visible in the gears demo. The gears are now displaying as red/green/blue as expected instead of white/yellow/cyan. After a lot of research, I found a way to work with power of 2 sized textures that are represented with sizes other than 256 internally.
I still have several modifications I want to make. In order for simple font atlases to work, I needed support for glTexSubImage2D. I recently added that and it appears to be working as long as textures are sized by a power of two. I'm currently working on refactoring the texture related code and cleaning up how to handle conversions between different formats (such as RGB, RGBA, BGRA).
Was surprised that the various forks of TinyGL have not fixed many of the bugs in the code. After I fixed the lighting issue for the gears demo, I ran across a few forks that mentioned the lighting problem. I also found a texture mapping bug. It's very easy to notice when you're using a font atlas. I had a letter next to a box character. When drawing the letter section of the texture, it went over by one pixel in the x direction. The first pixel of the box was displaying along with the letter. None of the forks I've looked at have made mention of the issue. The bug is in the s and t transforms in the gl_transform_to_viewport code. Assuming the texture has a width of 8, then the code should transform the x texture coordinates ranging from 0 to 1 to the texture bitmap coordinates 0 to width - 1 which in the example is 7. The PicoGL code is attempting to convert from one coordinate system to the other and then shift left by 14. However, the formula is combining the coordinate transformation with the shifting into one formula. It takes the highest shifted coordinate as ZB_POINT_S_MAX and the lowest shifted coordinate as ZB_POINT_S_MIN. The TinyGL code looks like s * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN. In the texture routine, the bits of the s coordinate are ANDed with a mask to remove fractions and then shifted back to get the transformed coordinate. The problem appears to be in how the transform and shift were combined in the formula. I believe the transform should be using 0 as the minimum and then doing the shift. The formula for the example texture should be (s-0/(1-0))*(width-1 - 0)+0 and then the shift is applied. That means the added minimum value should be 0 and even after it's shifted should still be 0. The maximum (width - 1) can be shifted once before it's multiplied with v to save time calculating (which is similar to what the original formula does). Thus, the formula should look more like s * (width - 1 << 14). Actually, the formula in the program is a little more complicated. It does the equivalent of adding in .5 to the maximum texture coordinate (width - 1) during the multiplication process for better rounding and then lops off the fractions from the result using a mask (in this case, width - 1 << 14) during the texture rendering phase before shifting the results to the right. However, I try to go through the formula or calculate this, adding in ZB_POINT_S_MIN in the original formula moves everything off by one pixel. The coordinate system should be 0 to width - 1 not .5 to width - 1. Fixing the coordinate system, fixes the bug. With a coordinate change in place, I no longer see an extra line of pixels when I use texture mapping to display parts of a font atlas to the screen.
It's difficult to find good documentation on how to create a rendering engine similar to the one used by PicoGL to render triangles and perspective correct textures. There really aren't any useful details on how the rendering works in documentation within TinyGL. That can make it difficult to figure out what the intention of the programmer was and whether there are any issues with the implementation (such as the texture mapping being off by a pixel) or whether they are 'intended features'. Best information I could find on how texture rendering engines work is in the Perspective Texture Mapping articles at http://chrishecker.com/Miscellaneous_Technical_Articles
There is also a discussion of some techniques here:
http://www.phatcode.net/~fb/forum/viewtopic.php?t=24889 If anyone runs across other good documentation on the subject, please let me know.
If there are any other projects, groups or developers using or investigating using TinyGL, PicoGL or a similar fork, I would love to share development ideas and code and/or discuss design issues. Have you worked with or done something interesting with PicoGL or TinyGL? Please let me know. I'm also in search of useful, portable applications that will work with a TinyGL or PicoGL backend. Have any favorites? Please share some details about them. Feel free to contact me: http://www.distasis.com/connect.htm
I've been patching PicoGL since 2013 and have added several features. It's currently stable enough to use with an OpenGL application such as Emilia Pinball. I've looked at several TinyGL forks with similar licenses and attempted to add the best of these forks into my version of PicoGL. I've updated the math-ssl library to a later version that uses a MIT license instead of the original GPL 2 license.
Other modifications include switching to 32 bit internal representation. I added some missing functions. I coded support for blending textures. I fixed a lighting issue that's visible in the gears demo. The gears are now displaying as red/green/blue as expected instead of white/yellow/cyan. After a lot of research, I found a way to work with power of 2 sized textures that are represented with sizes other than 256 internally.
I still have several modifications I want to make. In order for simple font atlases to work, I needed support for glTexSubImage2D. I recently added that and it appears to be working as long as textures are sized by a power of two. I'm currently working on refactoring the texture related code and cleaning up how to handle conversions between different formats (such as RGB, RGBA, BGRA).
Was surprised that the various forks of TinyGL have not fixed many of the bugs in the code. After I fixed the lighting issue for the gears demo, I ran across a few forks that mentioned the lighting problem. I also found a texture mapping bug. It's very easy to notice when you're using a font atlas. I had a letter next to a box character. When drawing the letter section of the texture, it went over by one pixel in the x direction. The first pixel of the box was displaying along with the letter. None of the forks I've looked at have made mention of the issue. The bug is in the s and t transforms in the gl_transform_to_viewport code. Assuming the texture has a width of 8, then the code should transform the x texture coordinates ranging from 0 to 1 to the texture bitmap coordinates 0 to width - 1 which in the example is 7. The PicoGL code is attempting to convert from one coordinate system to the other and then shift left by 14. However, the formula is combining the coordinate transformation with the shifting into one formula. It takes the highest shifted coordinate as ZB_POINT_S_MAX and the lowest shifted coordinate as ZB_POINT_S_MIN. The TinyGL code looks like s * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN. In the texture routine, the bits of the s coordinate are ANDed with a mask to remove fractions and then shifted back to get the transformed coordinate. The problem appears to be in how the transform and shift were combined in the formula. I believe the transform should be using 0 as the minimum and then doing the shift. The formula for the example texture should be (s-0/(1-0))*(width-1 - 0)+0 and then the shift is applied. That means the added minimum value should be 0 and even after it's shifted should still be 0. The maximum (width - 1) can be shifted once before it's multiplied with v to save time calculating (which is similar to what the original formula does). Thus, the formula should look more like s * (width - 1 << 14). Actually, the formula in the program is a little more complicated. It does the equivalent of adding in .5 to the maximum texture coordinate (width - 1) during the multiplication process for better rounding and then lops off the fractions from the result using a mask (in this case, width - 1 << 14) during the texture rendering phase before shifting the results to the right. However, I try to go through the formula or calculate this, adding in ZB_POINT_S_MIN in the original formula moves everything off by one pixel. The coordinate system should be 0 to width - 1 not .5 to width - 1. Fixing the coordinate system, fixes the bug. With a coordinate change in place, I no longer see an extra line of pixels when I use texture mapping to display parts of a font atlas to the screen.
It's difficult to find good documentation on how to create a rendering engine similar to the one used by PicoGL to render triangles and perspective correct textures. There really aren't any useful details on how the rendering works in documentation within TinyGL. That can make it difficult to figure out what the intention of the programmer was and whether there are any issues with the implementation (such as the texture mapping being off by a pixel) or whether they are 'intended features'. Best information I could find on how texture rendering engines work is in the Perspective Texture Mapping articles at http://chrishecker.com/Miscellaneous_Technical_Articles
There is also a discussion of some techniques here:
http://www.phatcode.net/~fb/forum/viewtopic.php?t=24889 If anyone runs across other good documentation on the subject, please let me know.
If there are any other projects, groups or developers using or investigating using TinyGL, PicoGL or a similar fork, I would love to share development ideas and code and/or discuss design issues. Have you worked with or done something interesting with PicoGL or TinyGL? Please let me know. I'm also in search of useful, portable applications that will work with a TinyGL or PicoGL backend. Have any favorites? Please share some details about them. Feel free to contact me: http://www.distasis.com/connect.htm