
How OpenGL works: software renderer in 500 lines of code - gregorymichael
https://github.com/ssloy/tinyrenderer/wiki
======
sclangdon
This is great and so concise, but I'm surprised that the author didn't
implement OpenGL's interface (obviously not all of it), if the goal is to show
how OpenGL works.

Another good example of this is Trenki's software renderer for the GPX2[1],
which implements a shader architecture if memory serves. I haven't looked at
it for many years, but I remember it being a useful resource when learning
this stuff.

Other useful resources are, of course, Michael Abrash's Graphics Programming
Black Book[2] (despite it's age, is still a great read filled with useful
information), and for a really deep dive into the graphic's pipeline, ryg's
(of Farbrausch fame) A Trip Through the Graphics Pipeline[3].

[1]
[http://www.trenki.net/content/view/18/38/](http://www.trenki.net/content/view/18/38/)

[2] [https://github.com/jagregory/abrash-black-
book](https://github.com/jagregory/abrash-black-book)

[3] [https://fgiesen.wordpress.com/2011/07/09/a-trip-through-
the-...](https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-
pipeline-2011-index/)

~~~
sclangdon
It turns out that Trenki implemented the OpenGL ES-CL 1.0 interface on top of
his software renderer (link [1] above), which should serve as an even better
example of how OpenGL (may) work.

[http://www.trenki.net/content/view/39/48/](http://www.trenki.net/content/view/39/48/)

------
8bitpimp
I wrote a software implementation of OpenGL with the only goal of being able
to play Quake3 using it. I can vouch that it is an amazing learning
experience. The tutorial here doesnt seem to aproach the issues of performance
however, which really are another learning experience entirely.

~~~
gnarbarian
Holy crap. If you could reimplement OpenGL you should be able to buy a video
card. I think I had a tnt2 Ultra back then.

~~~
cmrx64
"being able to play quak 2" as a goal for validation of effort and to have
something concrete to strive for is completely different than "none of my
software or hardware on my system can play quake 2", and I suspect grandparent
meant the former and not the latter.

------
exDM69
The title is a bit misleading, this is boilerplate code for a graphics
programming course and it hasn't got much to do with OpenGL.

The articles describing the operation are much more interesting than the code
itself.

It's just an inefficient triangle rasterizer. All it does is loop over the
pixels in a rectangle covering a triangle, and for each pixel inside it calls
a "shader" function. All the beef is in these 40 lines [0].

I don't know how they've done the texturing in all those pretty pictures (it's
in the "shaders", not included here), but they don't calculate the partial
derivatives required for correct, mipmapped texturing. Simple non-mipmapped
perspective correct texture mapping can be computed in the shaders, with the
usual caveats.

OpenGL is much more than a rasterizer, there's texturing, depth-stencil
operations, blending, compute shaders and efficient memory management.

[0]
[https://github.com/ssloy/tinyrenderer/blob/master/our_gl.cpp...](https://github.com/ssloy/tinyrenderer/blob/master/our_gl.cpp#L42)

edit: Someone in reddit pointed out that this is a translation of a Russian
language course. The original Russian version looks to be a bit longer than
the English translation (but I don't read Russian, so I can't tell if it is
better):
[https://habrahabr.ru/post/249467/](https://habrahabr.ru/post/249467/)

~~~
fsloth
You need to look through the short course notes in the wiki of the page to
understand the full quality of this repository.

~~~
exDM69
Yes, I did and that's much more interesting than the code itself. But the
title is still misleading and emphasizes the code, which isn't terribly
spectacular.

~~~
fsloth
If it's looked purely from educational point of view it's quite hard to find
graphics code that is this clear and concise.

The author modifies this short code to implement various shading techniques
with code that is as pithy and understandable as any.

You have to recall that 40 years ago even texture mapping was a scientific
publication quality material.

This code makes several non-obvious things obvious - and simple! I don't think
that's a light achievement.

------
fsloth
Wov, this is so elegant, short and sweet. It's the most beautiful code I've
seen in a while - because it's pithy, to the point, but yet retains enough
critical detail to be educationally valid. Thanks for sharing.

------
leni536
I remember once I needed to macro up a software that needed an X server with
OpenGL to run. (Like really dirtily hack it up, with xmacro and stuff like
that). I wish I could set up a headless X server with a dummy OpenGL renderer
(witch doesn't actually render anything), so it doesn't bottleneck on
rendering that isn't used anyway. I guess it's even easier to write such and
OpenGL implementation.

edit: Now I see it doesn't implement the OpenGL API though, the goals are
obviously different.

~~~
jre
Mesa has an offscreen rendering implementation that allows you to do OpenGL
without an X server :

[http://www.mesa3d.org/osmesa.html](http://www.mesa3d.org/osmesa.html)

------
speps
Related but more efficient (includes a rasterizer) :

[https://fgiesen.wordpress.com/2013/02/17/optimizing-sw-
occlu...](https://fgiesen.wordpress.com/2013/02/17/optimizing-sw-occlusion-
culling-index/)

------
stop1234
I just went through the lessons and all the code compiled and worked as
expected. Nice and simple. As things should be.

Thank you for posting this online.

------
theoh
Stanford's past notes on polygon rasterization are interesting for historical
background and algorithmic elegance:
[http://www.graphics.stanford.edu/courses/cs248-98-fall/Lectu...](http://www.graphics.stanford.edu/courses/cs248-98-fall/Lectures/lecture9/slides/)

Edit: Also this
[https://graphics.stanford.edu/courses/cs248-08/scan/scan1.ht...](https://graphics.stanford.edu/courses/cs248-08/scan/scan1.html)

------
jahnu
[https://github.com/ssloy/tinyrenderer/blob/master/geometry.c...](https://github.com/ssloy/tinyrenderer/blob/master/geometry.cpp#L3)

What's going on there with the template<> template<> ?

~~~
sclangdon
The struct vec takes a template parameter T, and it's constructor takes a
different template parameter U. Therefore, you must specify both template
directives when defining the constructor; one for the class type, and one for
the constructor's argument.

~~~
jahnu
Edit: re-wording this reply.

I guess what surprised me is I would almost expect it to look something like
this...

template <> vec<3,int> ::vec(template <> const vec<3,float> &v) :
x(int(v.x+.5f)),y(int(v.y+.5f)),z(int(v.z+.5f)) {}

I can tell that is silly but still.

------
erichocean
If anyone has a link that shows the Vulkan equivalent (e.g. how pipeline
states might be implemented, etc.) I would really appreciate it.

In particular, I'm very curious how tile-based deferred rendering wound
interact (positively!) with a Vulkan software rendering implementation by
keeping all tile buffers for a render pass in the on-chip cache of a modern
Intel CPU. It seems like Vulkan provides a better API for a software rendering
than OpenGL for that reason, and I'd like to see that confirmed one way or the
other.

------
riazrizvi
OpenGL is partly these widely available graphics algorithms. Thank you for
explaining them so well here. OpenGL also has a particular architecture that
provides concurrency and extensibility among other things. If we are talking
about OpenGL specifically vs other Rendering Engines, then it would be good to
explain the architecture to help folks understand the reasons why OpenGL is so
widely used.

------
lbenes
Will this teach you how shader-based OpenGL works or the older fixed function
pipeline rendering method?

~~~
joeld42
"OpenGL" is a bit of a misnomer here, there's nothing directly related to
OpenGL. This will not teach you how opengl works, but is an example of a
software rasterizer. Knowing how that works will help you understand what is
going on under the hood of your graphics API.

This renderer does do lighting per-fragment, so it's more akin to the newer
shader-based OpenGL.

------
valine
I would love a section on anti-aliasing. It seems to be the big thing missing.

~~~
yoklov
That's probably because OpenGL doesn't do antialiasing by default. When it
does it, it does it by rendering everything at a larger scale and downscaling
it (well, actually MSAA allows the GL to avoid having to do this to
_everything_ , and only do it for some buffers)

FXAA and similar antialiasing algorithms fake it as a post process effect.

~~~
psykotic
> (well, actually MSAA allows the GL to avoid having to do this to everything,
> and only do it for some buffers)

MSAA is faster than supersampling because the GPU generates subsample coverage
but doesn't individually shade each subsample. And, this is absolutely
critical, there is a compression scheme for depth and color transmission
between the DRAM and texture cache which is a massive bandwidth optimization
in the common case where a sample tile (usually 8x8, which for 4x MSAA
corresponds to only 4x4 pixels) is covered by only one or two triangles.

------
latenightcoding
This looks amazing, I wish it was in C, but I will check it out.

------
sklogic
Somewhat related:
[https://github.com/a2flo/oclraster](https://github.com/a2flo/oclraster)

------
billconan
repost of
[https://news.ycombinator.com/item?id=11260507](https://news.ycombinator.com/item?id=11260507)

~~~
dang
Reposts are ok if a story hasn't had significant attention yet.

[https://news.ycombinator.com/newsfaq.html](https://news.ycombinator.com/newsfaq.html)

