rswinkle / PortableGL

An implementation of OpenGL 3.x-ish in clean C
MIT License
1.05k stars 49 forks source link

Compatibility question: Will this work on an unusual platform? #24

Open XanCraft21 opened 3 weeks ago

XanCraft21 commented 3 weeks ago

Hello, i was wondering if this library would work with an unusual platform. This platform does not support shaders, has no GPU, or any graphics acceleration. Everything must be done in software, and my graphics are 16-bit. The size of an int is 16-bit (but i can change it to be long in the library), and memory is very limited. I also need the ability to make any sized texture and have it saved in that resolution (for example, a 64x64 texture will be loaded and saved as 64x64 instead of 256x256). There is no operating system and the coding language is c++11 (i know it’s outdated but it’s all i have at this time. I know it’s better to do this on a full pc but i am very adventurous when it comes to tiny computers and microcontrollers).

My platform of choice is Arduino, and my device of choice is a Teensy 4.0 by PJRC. I am aware that this has a very low chance of working, but i have gotten a port called TinyGL working perfectly fine. I supplied my own display driver and it was pretty simple to get working.

From what I understand this library emulates shaders in software, so theoretically they should work on the said platform. I may be wrong about this though.

I am asking this question because i am having trouble looking for a good 3D renderer that is like OpenGL, and i hope that i can do simple modifications to this library to allow it to work on my platform. Thank you for your help.

rswinkle commented 3 weeks ago

Theoretically as long as it has a C99 or C++ compiler it should work. It uses a full 32 bit color buffer but it uses fixed size integer types where necessary so there should be no problem. I was under the impression that the Cortex M7 is a 32 bit architecture with 32 bit ints anyway but maybe you were referring to your graphical style like "8-bit" style graphics? In that case you would just do exactly what you would do using real OpenGL.

The biggest issue with the Teensy is the limited memory and of course performance. I would definitely strip out all extraneous things. As of yet I have no built in way to not allocate the zbuffer and stencil buffer so if you don't need either of those just remove that code. I'm sure there are many other somewhat low hanging fruit.

I am positive that if you got TinyGL working you can get PortableGL working though it might be slightly slower out of the box.

XanCraft21 commented 3 weeks ago

Thank you for your fast reply.

I think i will need to comment out some printing functions and reconfigure a few things before it will work, but i think it should be ok with enough time and effort. As long as your library takes less than 150kb of ram (minus the frame buffer) it should work.

I also want to see if i can get away with a 16-bit image buffer for an RGB565 color resolution to save on ram and still get decent graphics even on a smaller display.

If it isn’t too much to ask may i have some help getting the library to work on my platform and device? If necessary we could get in contact so we can have faster replies, maybe discord if you have it?

I look forward to getting this library to work over time, and with your help it will be working hopefully in no time.

EDIT: I got the library to compile and upload with really only one change. Everything is fine except there is a strange bug that is probably only on my end, where the DEG_TO_RAD and RAD_TO_DEG functions with the double variable type, the double is not being recognized. I just commented it out and it was fine.

So i got the code to compile and upload just fine, but i have another problem, it is having trouble creating the context with init_glContext(). It may be an out of memory error, but i’m not sure.

my display resolution i am using right now is 128x128, and i even decreased it to 16x16, and it still didn’t work. Do you know how much ram your library takes at the minimum usage level? The most i can do safely at this time is 512 kB.

rswinkle commented 3 weeks ago

Thank you for your fast reply.

No problem, I like hearing about people using PortableGL

I think i will need to comment out some printing functions and reconfigure a few things before it will work, but i think it should be ok with enough time and effort. As long as your library takes less than 150kb of ram (minus the frame buffer) it should work.

It used to be that the only big allocations were the framebuffer (color, z, stencil) which can be calculated as width height (4+4+1). Then of course you have any data you pass to PGL just like OpenGL. You should use mapped data to save unecessary allocation and copying especially if you have any real amount of data.

Unfortunately what's killing it before it even starts is that I now pre-allocate the max amount of scratch space where I used to reserve only as much as the user needed on the fly. You can easily change the constants. Right now the scratch space is 62.5 MB (500000 vertices 8 max attributes 4 components *sizeof(float). You can see the macros here and the scratch allocation here. I would recommend 1000 for max vertices and 4 for max attributes attributes or 2000 and 2 or something in those ranges.

I also want to see if i can get away with a 16-bit image buffer for an RGB565 color resolution to save on ram and still get decent graphics even on a smaller display.

That wouldn't be too hard. All the internal calculations would still be done in float but you'd need to convert to and from RGB565 when interacting with the color buffer. Not much code.

If it isn’t too much to ask may i have some help getting the library to work on my platform and device? If necessary we could get in contact so we can have faster replies, maybe discord if you have it?

I can definitely help a bit if you need it but I think you probably won't need it and I don't have (or at least don't use) discord but I get email notifications for this.

I look forward to getting this library to work over time, and with your help it will be working hopefully in no time.

EDIT: I got the library to compile and upload with really only one change. Everything is fine except there is a strange bug that is probably only on my end, where the DEG_TO_RAD and RAD_TO_DEG functions with the double variable type, the double is not being recognized. I just commented it out and it was fine.

That sounds familiar, like something I might have fixed a while ago... I'd like to see the error if you don't mind.

So i got the code to compile and upload just fine, but i have another problem, it is having trouble creating the context with init_glContext(). It may be an out of memory error, but i’m not sure.

my display resolution i am using right now is 128x128, and i even decreased it to 16x16, and it still didn’t work. Do you know how much ram your library takes at the minimum usage level? The most i can do safely at this time is 512 kB.

See above about the scratch space. Lower the 2 relevant macro constants and you should be good.

XanCraft21 commented 3 weeks ago

Thank you. Unfortunately after changing the memory parameters as mentioned above it still doesn’t want to work. I even put them down pretty low too. If I remember correctly the hardware i am using doesn’t like working with 32-bit display buffers and must be a 16-bit buffer. What modifications do i have to make to your library to cut the u32 buffer in half?

I am wondering if i can just change the variable type and then modify the part of the code that writes to the buffer to work with 16-bit colors. Is it really that easy to do?

About the error message i was having before i think it said “expected unqualified-id before double”. I’m not sure what’s causing it to do that.

rswinkle commented 3 weeks ago

Sorry for the delay, been a bit busy with Halloween and work.

Thank you. Unfortunately after changing the memory parameters as mentioned above it still doesn’t want to work. I even put them down pretty low too. If I remember correctly the hardware i am using doesn’t like working with 32-bit display buffers and must be a 16-bit buffer. What modifications do i have to make to your library to cut the u32 buffer in half?

But it shouldn't be failing due to being out of memory anymore right? You should be getting a different error.

I am wondering if i can just change the variable type and then modify the part of the code that writes to the buffer to work with 16-bit colors. Is it really that easy to do?

About the error message i was having before i think it said “expected unqualified-id before double”. I’m not sure what’s causing it to do that.

Is your code public anywhere? Can I look at exactly what you're trying to use it with? Or if it's not public can you email it to me at robert at portablegl dot com? We could even schedule a meeting to go over it, you could show me the errors you're getting etc. Like I said before it would just require changes in a handful of places, when reading or writing from/to the color buffer and of course the initial allocation.

XanCraft21 commented 3 weeks ago

It’s perfectly fine, there’s no rush at all.

I am unsure of what the error is, all i know is that the init_glContext() function is returning false and i just have it print to the output a very basic message. I looked at the function code and the only spot i see returning false looks like out of memory. I might need to wait until i can get a memory expansion for my device.

I can probably create a github gist and send you the link so you can see my code, i basically just copied from one of the examples and removed the SDL stuff and put my own drivers, with some rearranging of the code too.

I am not sure how to set up a meeting since I usually don’t do meetings in this way. I hope i’m not giving you a hard time, but thank you for staying with me for this issue.

If possible could you point me to the places i would need to change to convert the display buffer to 16-bit?

rswinkle commented 3 weeks ago

It’s perfectly fine, there’s no rush at all.

I am unsure of what the error is, all i know is that the init_glContext() function is returning false and i just have it print to the output a very basic message. I looked at the function code and the only spot i see returning false looks like out of memory. I might need to wait until i can get a memory expansion for my device.

I can probably create a github gist and send you the link so you can see my code, i basically just copied from one of the examples and removed the SDL stuff and put my own drivers, with some rearranging of the code too.

That would definitely be useful, especially if we can't meet up to discuss it in real time.

I am not sure how to set up a meeting since I usually don’t do meetings in this way. I hope i’m not giving you a hard time, but thank you for staying with me for this issue.

There are lots of options these days. I've never used Jitsi but apparently it's free and open source and you don't even need an account? And of course there's always google meet, and zoom and all the other proprietary options out there.

If possible could you point me to the places i would need to change to convert the display buffer to 16-bit?

Again it would definitely be easier if I could just show you in the code live, or write it myself (or both at the same time) but for instance besides the allocation of the buffer, you'd have to make changes to draw_pixel and glClear. Possible a couple other places I'm forgetting off the top of my head.

XanCraft21 commented 2 weeks ago

I can definitely do a meeting on zoom. I only used it a few times once and i only did it on an ipad. I’m not the best at scheduling dates and times so i’m not sure how well it would work out, but we can definitely try it soon.

in the end it might not work anyway without some kind of memory expansion and an upgraded device that can support the expansion, since i don’t think half a megabyte is enough. I know it works mostly fine for TinyGL, but i think your library takes more ram not including the scratch space or the display buffer.

rswinkle commented 2 weeks ago

I'm not much for Zoom either but I've been meaning to try Jitsi and it seems as user friendly as google meet.

You're not the first to talk about using PGL on a Teensy and I said the same things then. Maybe I should just buy one and a screen myself and show that it can be done, but as cheap as it is it's hard justify both the cost and the dev time since I haven't made any money from PGL since my short term contract last year. I'm a terrible marketer.

With the right configuration/changes memory should not be an issue.

Assuming you're using this screen and we change the color buffer to 16 bits, eliminate the stencil buffer, and set PGL_MAX_VERTICES and GL_MAX_VERTEX_ATTRIBUTES at 1000 and 2 we get:

framebuffer 320x240*(2+4) = 460.8K

scratch space 100024*4 = 32K

The Teensy 4.0 has 1024K of RAM 512K tightly coupled

The above numbers add to 492.8K leaving about 19K for all other data if we want to squeeze into the "tightly coupled" RAM. Probably possible, but likely we would want to either eliminate the depth buffer or cut it in half as well which would require a few more changes but still not as much as you might think. Assuming we do one of those too, we drop down to a total of 185.6K or 339.2K respectively which gives far more leeway.

Looking at TinyGL now, I actually had forgotten that the pixel format was configureable at compile time ... and he's using a u16 for the zbuffer. Hmmm... more on the TODO list I guess.

XanCraft21 commented 2 weeks ago

Sorry about the late reply.

I have never heard of Jitsi before and i never used Google Meet before. I’m not ready to try something new yet so if it’s ok with you i will take either zoom or google meet. What days are you open to make a scheduled date? It will be hard for me to make it sometimes because i’m a very lazy person.

About the display i was using a 1.5 inch oled with 16-bit color (can go up to 18-bit but 16-bit is more commonly used) and a resolution of 128x128, and my display library is Arduino_GFX (aka GFX_Library_For_Arduino). I have plans to use a 240x320 display with PGL but i need to make some free ram space.

I assume that PGL uses Malloc() a lot so with the way the Teensy 4.0 ram is configured that only gives is 511k to work with. I could always get a Teensy 4.1 and add external ram for that and just modify the memory functions to work with that. I can also possibly use an ESP32 board with external ram, i might test that here soon.

I may not use the stencil buffer but i will definitely use the zbuffer. Maybe if we combine a 16-bit display buffer and a smaller zbuffer it should work on a teensy without the extra ram.

I forgot to clarify which version of TinyGL i was using, i was using the version modified by C-Chads, which allows me to make the texture size smaller and do some other configuration options, otherwise the texture size would be automatically locked at 256x256.

EDIT: I thought i would try an ESP32 with external ram, but i can’t get any ESP32 boards to work. I think it’s most likely on my end since my computer gets hacked by hackers every time i use it. Maybe i can find another way on a different day.