- spend a few hours working out why your display window just shows black
I hardly ever had this kind of problem… and I'm doing OpenGL programming for almost two decades now. Yes, when implementing a new shader (idea) I often am greeted with a blank window, too. This is where the "stringiness" of OpenGL is actually a huge benefit.
See, you don't have to recompile your program just to change things in the shader. In fact in development builds of my OpenGL programs I regularly place a filesystem monitor on each shader source file, so that the shader gets automatically reload and recompiled whenever the file changes. Combine that with a GLSL compiler error log parser (the GLSL compiler will emit helpful diagnostics) for your favourite editor and you can quickly iterate your development cycles.
Just to give you an idea of how well this works and how quickly you can develop with OpenGL if you know how to do it properly: Past February our company showed our new realtime videorate 4D-OCT system at Photonics West/BiOS expo. The first day of the expo, about 10 minutes before opening my CEO asked me, how difficult it would be to hack a variance visualization into it. Since we had a developer build of the software on the demo system I could make the changes in-situ in the running program. It took me less than 5 minutes to implement that new display mode shader… from scratch. Considering that even the smallest changes in the program C++ files would still require a at least 10s long linking stage and that after each launch of the program it takes about 2 minutes for the program to go through all the required calibration I couldn't have done it that quickly.
----
For those wondering how to effectively debug shaders: First get the vertex shader working, only then start with the fragment shader. Until the vertex shader doesn't work use the following as fragment shader:
out vec4 o_fragcolor; void main() { o_fragcolor = vec4(1.,0.,0.,1.); }
i.e. a solid red. For debugging the vertex shader you may introduce some varyings that you pass into the fragment color. Once you've got the vertex shader doing what you want it to do you can tackle the fragment shader.
And always remember: Don't link the shader text hard into your program binary. Load them from external files instead and have a way to signal a reload.
Your not hitting the black-screen since you've been doing it self-admitted for 20 years. Kudos, good for you.
The problem is getting fresh-blood in who have a hunger to learn but don't have a deep understanding of shaders, pipelines, vertices, etc. It's really easy to make a trivial mistake in that boiler plate(I've seen someone fight something for hours until they thought to turn of culling, they just had their winding wrong).
Case in point from one of the foremost figures in the domain:
https://twitter.com/id_aa_carmack/status/370205518532329472
PIX was about the most sane step in the direction of fixing this, sadly tools seem to have slid backwards of late.
The NVidia GLSL compiler (which is based on the Cg compiler), to this date, first compiles from GLSL into assembly as specified by the GL_ARB__program extensions plus extra instructions specified in the GL_NV__program extensions. Nothing wrong with that. But what's wrong is applying the LC_NUMERIC locale onto floating point literals emitted into the assembly code, because if your system happens to be set to a locale where the decimal separator is a comma (,) and not a period (.) the following assembly stage will interpret the commas as list separators. NVidia's beta drivers of November 2006 for their then newly released G80 GPUs had this very bug (it also happens that I did report it first, or so I think); NVidia got the report just in time to apply an in-situ workaround before the next non-beta driver release (at least so I was told back then).