I'd recommend the Pikuma course Graphics From Scratch[0]. The first thing you do is write a set_pixel function utilizing SDL and the rest of the course is all your code, every matrix operation, every vertex transformation, every triangle rasterization. You calculate what every individual pixel should be colored. [0]: https://pikuma.com/courses/learn-3d-computer-graphics-progra...
>No GPU, no OpenGL, no DirectX! This is the opposite of what you would hope to see for learning graphics programming.
> This is the opposite of what you would hope to see for learning graphics programming.
It is exactly what you would hope to see.
And I would dare say I'm a graphics programmer, mostly self taught.
When I started, as a teenager, in the late 80's, there were no GPUs. So I learned everything from first principles. I recall implementing Bresenham in x86 assembly for my CGA card. And then, as a follow up, rasterizing a triangle. You really had to understand stuff end-to-end then as the hardware was so slow. I.e. even C was too slow for that stuff.
And today, still, the best offline renderers, that produce the images you see on the big screen, are CPU-only. 100% custom code, no 3rd party API dependency.[1]
If you write stuff for CAD/CAM/CAE/VFX, there is a big chance you do not think about the constraints of a GPU and less so of one of the APIs used to program it. Except for previewing stuff.
I would suggest to anyone learning graphics programming (or anything else for that matter) to do so from first principles.
GPUs are specialized hardware for realtime applications. That is very specific. I don't say don't learn that. But I suggest to not start with it.
[1] One of my best friends is the lead developer of the 3Delight renderer.