Starting with OpenGL
category: code [glöplog]
When I was still doing demos (around the time North-America was discovered) I used DX7 and 8 and that was Fun and Good. I'm interested in doing some more coding but this time I'd like it to be cross-platform. So that means I need to start using OpenGL. Now, there's all sorts of options there (GL 3.3? 4? GLES 2? 3?) that it's starting to boggle my mind somewhat.
So I'd like to know what you guys would recommend. Which version of GL? What is the best mix between new features and robust drivers? How do I make sure that the shaders I write on NVidia work on ATI? Etc?
So I'd like to know what you guys would recommend. Which version of GL? What is the best mix between new features and robust drivers? How do I make sure that the shaders I write on NVidia work on ATI? Etc?
go vulkan!
I would go for OpenGL 4.x in the 'core' profile (warning: you can't use stuff like GLUT for this, because they won't let you specify which version and profile you want for your GL context).
The 'core' profile is stripped from nasty legacy code, which makes OpenGL 4.x core very similar to OpenGL ES 2+, which improves portability and compatibility.
Making sure the shaders work on all vendors? You don't, basically.
The problem with OpenGL is that the shader compiler is left up to the vendor to implement. So unlike DX there is no single compiler that is shared by all.
This means you will always run into small issues/incompatibilities, very similar to trying to compile code written for GCC on MSVC and vice versa.
To make things extra complicated, OpenGL ES uses a slightly different dialect of GLSL than regular OpenGL, which makes it even more difficult to write shaders once and compile them everywhere.
There is work in progress for a bytecode intermediate language, similar to the way DirectX has been doing it since the dawn of time. But afaik these extensions are not available in production drivers yet. So you're still left with the old situation of multiple compilers.
The 'core' profile is stripped from nasty legacy code, which makes OpenGL 4.x core very similar to OpenGL ES 2+, which improves portability and compatibility.
Making sure the shaders work on all vendors? You don't, basically.
The problem with OpenGL is that the shader compiler is left up to the vendor to implement. So unlike DX there is no single compiler that is shared by all.
This means you will always run into small issues/incompatibilities, very similar to trying to compile code written for GCC on MSVC and vice versa.
To make things extra complicated, OpenGL ES uses a slightly different dialect of GLSL than regular OpenGL, which makes it even more difficult to write shaders once and compile them everywhere.
There is work in progress for a bytecode intermediate language, similar to the way DirectX has been doing it since the dawn of time. But afaik these extensions are not available in production drivers yet. So you're still left with the old situation of multiple compilers.
@Maali: I don't want to wait another six months :)
@Scali: This new bytecode is related to SPIR-V I suppose? Will this be part of GL as well, or is this going to be Vulkan-specific? Are there any shader validators out there that you'd recommend?
But okay, GL4 core is a valid option then. I should probably use something like glLoadGen to create my loader specifically for my needs, I guess?
@Scali: This new bytecode is related to SPIR-V I suppose? Will this be part of GL as well, or is this going to be Vulkan-specific? Are there any shader validators out there that you'd recommend?
But okay, GL4 core is a valid option then. I should probably use something like glLoadGen to create my loader specifically for my needs, I guess?
Quote:
@Scali: This new bytecode is related to SPIR-V I suppose?
That is correct.
Quote:
Will this be part of GL as well, or is this going to be Vulkan-specific?
I'm not sure. The one thing we DO know for sure is that current GL drivers do not support it, so unless the current hardware gets driver updates, they will not ever support it.
That is a huge difference with DX: you need driver updates to get access to new APIs and features, where the DX runtime can be updated on top of existing drivers.
Quote:
Are there any shader validators out there that you'd recommend?
I have not used such.
I just wrote some code to grab the error log from the shader compiler, which tends to give quite a bit of info. Then I try to compile my shaders on Intel, AMD and nVidia drivers, and see what they say.
Quote:
I should probably use something like glLoadGen to create my loader specifically for my needs, I guess?
Perhaps, I don't have experience with glLoadGen myself. I use GLEW on Windows/linux/FreeBSD/OS X.
NeHe tutorials is good.
I'm honestly not sure if I would use the core mode. It makes getting up-and-running super-annoying for no good reason; you need a VAO and VBO and shaders just to get a single triangle on the screen. If you're going to do high-performance OpenGL, sure, you'll want that anyway, but why bother if you're just learning?
I can think of one compelling reason why, though: You don't say how cross-platform you want your cross-platform code to be, but if you want to run on Mesa (e.g. Intel drivers on Linux), it doesn't support compatibility mode, so you're stuck on 3.1 unless you go to core (although you do get extensions).
As for GLUT replacements, SDL2 supports core mode if you really want to.
For extensions, I've found epoxy to be a very good GLEW replacement (https://github.com/anholt/libepoxy). Just include some header files and a library, and tada, pretend you're writing OpenGL 4.x everywhere instead of having to worry about whether function XYZ comes from the core, an NV extension, ARB, etc. It also supports core mode if you want to, or GLES.
I can think of one compelling reason why, though: You don't say how cross-platform you want your cross-platform code to be, but if you want to run on Mesa (e.g. Intel drivers on Linux), it doesn't support compatibility mode, so you're stuck on 3.1 unless you go to core (although you do get extensions).
As for GLUT replacements, SDL2 supports core mode if you really want to.
For extensions, I've found epoxy to be a very good GLEW replacement (https://github.com/anholt/libepoxy). Just include some header files and a library, and tada, pretend you're writing OpenGL 4.x everywhere instead of having to worry about whether function XYZ comes from the core, an NV extension, ARB, etc. It also supports core mode if you want to, or GLES.
Quote:
I'm honestly not sure if I would use the core mode. It makes getting up-and-running super-annoying for no good reason; you need a VAO and VBO and shaders just to get a single triangle on the screen. If you're going to do high-performance OpenGL, sure, you'll want that anyway, but why bother if you're just learning?
Because as I said, in OpenGL ES you need to do that anyway. Might as well do it on the desktop as well, so you can share more code between platforms.
For cross-platform Window/context handling, GLFW is very nice and up-to-date. A bit too large for intros, though.
A semi-warning on vulkan: it's not just new, it's also very low level. That means managing everything down to GPU command queue level yourself. If you don't mind that it's interesting and potentially rewarding, but forget quickly throwing a shader onto the screen ;)
Same applies to Metal (iOS/OS x) and dx12 (in fact I hear the dx12 docs warn that it's for the experienced devs in search of adventure or something similar:)
Same applies to Metal (iOS/OS x) and dx12 (in fact I hear the dx12 docs warn that it's for the experienced devs in search of adventure or something similar:)
Quote:
A semi-warning on vulkan: it's not just new, it's also very low level.
It's so new that it's going to take a while until it's actually supported by OSes/drivers/etc :)
For openGL shader code validator use the khronos reference compiler. Of course it is simple to grab an error report when you try and compile your shaders and in fact the error reporting is quite verbose and useful. But this is only relevant to your own hardware and drivers while you are developing the shaders.
Anyway once you get close to a final release you can run it through the reference compiler or if you are feeling ambitious there is also the source code available and you can implement a run-time validation inside your own software/framework/dev-tool/whatever.
https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
If you are making full size demos or other non-restricted software then use SDL or GLFW as other people have said and those libraries will do a lot of the heavy lifting for you. If it is size restricted intros of course you need to roll your own setup code but honestly just making a basic opengl framework isn't that hard.
Anyway once you get close to a final release you can run it through the reference compiler or if you are feeling ambitious there is also the source code available and you can implement a run-time validation inside your own software/framework/dev-tool/whatever.
https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
If you are making full size demos or other non-restricted software then use SDL or GLFW as other people have said and those libraries will do a lot of the heavy lifting for you. If it is size restricted intros of course you need to roll your own setup code but honestly just making a basic opengl framework isn't that hard.
I can't really say SDL or GLFW does “a lot of heavy lifting”. They set up a screen and a context. That's tedious, but not particularly challenging. :-P
Of course and I literally said in the following sentence that it isn't hard to do. But it is time consuming as you said and openGL is a minefield of legacy crap with different versions and extensions when you are starting out. Not only that but SDL will do all the error handling as well as a lot of other useful stuff like audio, multithreading, timers, keyboard/mouse and other inputs as well as reading and writing files, all platform independant which is what the OP seems interested in.
Note that if you're doing size-limited intros on FreeBSD/Linux, SDL is considered acceptable as it's pretty much a default feature of any desktop system running games. Do not use SDL-1.2 if you start now, it's obsolete and has ceased to function properly on some newer desktop systems. Size-wise you need one extra call to set up your window & context and slight increase of mr. Kolmogorov otherwise too, when using version 2 as compared to 1.2, but such is life.
I've never seen a size-limited intro use GLFW (but you may prove me wrong). In the past there were several that used GLUT though.
I've never seen a size-limited intro use GLFW (but you may prove me wrong). In the past there were several that used GLUT though.
GLFW and SDL aren't meant for intros. Write your own stuff for that. Use them for demos.
Totally random collection of thoughts:
1. Don't read any NeHe tutorials, ever. Don't listen to people who tell you to look at them. They are overly complicated, terribly outdated, and aimed at a differend kind of beginner.
2. You don't really need a third-party libs. Look at various intro frameworks or intros with source on how to open a window etc. It's only few lines of code and you only have to write or copypaste it once. It might be a good idea to get started with one and get rid of it only when you actually have your content on the screen (to reduce the amount of possible pitfalls which are active at the same time).
3. Yes, use >= GL 4.3 core. If you restrict yourself to core profile, all kinds of fancy new debugging tools like nsight and renderdoc start working. Inspect GL state at runtime, look at buffer contents, trace pixel history, show wireframe, step through draw calls visually, get performance measurements. If you start fresh now, you might as well use this chance. There's no reason to not use 4.4 at the moment, but 4.5 has only partial support by ATi (nobody stops you from using those parts that are implemented). See http://www.g-truc.net/project-0033.html For g-truc's more or less regular gl driver status reports.
4. To get your first triangle on the screen, you don't need to create or bind any VAOs/VBOs. Just call glDrawArrays and choose the vertex position in the vertex shader by gl_VertexID.
5. http://docs.gl/ is a great function reference (only GL, not GLSL). Search for parts of a function name and filter by GL version.
6. glm is an option for the CPU part of the math and feels much like vector math in glsl, but it is questionable for use in an intro.
7. The NV compiler has become a bit more strict in the last months and the ATi compiler now supports most of the important things instead of just dying without error messages, so this difference is not as big as it used to be. If it works on ATi, it will probably run on nvidia as well. As the others said, use the khronos validator if you're on nvidia. But you'll only be sure both ways after someone has actually run it. Almost all the compo machines use nvidia cards at the moment.
8. It's normal to stare at a black screen for half a day, it's not only you and it will pass :)
1. Don't read any NeHe tutorials, ever. Don't listen to people who tell you to look at them. They are overly complicated, terribly outdated, and aimed at a differend kind of beginner.
2. You don't really need a third-party libs. Look at various intro frameworks or intros with source on how to open a window etc. It's only few lines of code and you only have to write or copypaste it once. It might be a good idea to get started with one and get rid of it only when you actually have your content on the screen (to reduce the amount of possible pitfalls which are active at the same time).
3. Yes, use >= GL 4.3 core. If you restrict yourself to core profile, all kinds of fancy new debugging tools like nsight and renderdoc start working. Inspect GL state at runtime, look at buffer contents, trace pixel history, show wireframe, step through draw calls visually, get performance measurements. If you start fresh now, you might as well use this chance. There's no reason to not use 4.4 at the moment, but 4.5 has only partial support by ATi (nobody stops you from using those parts that are implemented). See http://www.g-truc.net/project-0033.html For g-truc's more or less regular gl driver status reports.
4. To get your first triangle on the screen, you don't need to create or bind any VAOs/VBOs. Just call glDrawArrays and choose the vertex position in the vertex shader by gl_VertexID.
5. http://docs.gl/ is a great function reference (only GL, not GLSL). Search for parts of a function name and filter by GL version.
6. glm is an option for the CPU part of the math and feels much like vector math in glsl, but it is questionable for use in an intro.
7. The NV compiler has become a bit more strict in the last months and the ATi compiler now supports most of the important things instead of just dying without error messages, so this difference is not as big as it used to be. If it works on ATi, it will probably run on nvidia as well. As the others said, use the khronos validator if you're on nvidia. But you'll only be sure both ways after someone has actually run it. Almost all the compo machines use nvidia cards at the moment.
8. It's normal to stare at a black screen for half a day, it's not only you and it will pass :)
speaking from my own experience, I have to agree with everything cupe has said, with small addition to...
...which is, I've had nothing but lovely experiences with glm in the >=32kb categories, up to and including demos. I haven't done any disassembly to see exactly how small it gets, but that's because I haven't ever had to dig that deep, as stuff just ends up as small as it needs to be anyways :) As for the categories below that in size, I've never tried, but my guess is you're not using C++ at that point anyways, so it's probably not relevant.
Quote:
6. glm is an option for the CPU part of the math and feels much like vector math in glsl, but it is questionable for use in an intro.
...which is, I've had nothing but lovely experiences with glm in the >=32kb categories, up to and including demos. I haven't done any disassembly to see exactly how small it gets, but that's because I haven't ever had to dig that deep, as stuff just ends up as small as it needs to be anyways :) As for the categories below that in size, I've never tried, but my guess is you're not using C++ at that point anyways, so it's probably not relevant.
If you target Windows/MSVC, you could also use DirectXMath, which gives you intrinsics-based math routines for SSE2/NEON instructionsets. Should result in compact and efficient code.
Okay, good feedback, all! I should have clarified: I want to do this for demos, not necessarily intros, so any kind of framework that can do some of the basic setup for me is more than welcome. I was leaning towards GLFW but I'll just see what's the most sane to use.
I'll target the core profile then, version 4.4 or so.
I'll target the core profile then, version 4.4 or so.
I've found this book to be useful (even though it's not really a cookbook by any means..)
https://www.packtpub.com/game-development/opengl-40-shading-language-cookbook
https://www.packtpub.com/game-development/opengl-40-shading-language-cookbook
If you want, you could start here: http://sourceforge.net/p/bhmfileformat/code/ci/default/tree/BHM3DSample/
It's not core profile 4 (although I have a working version of that), but it does offer a complete shader-based GL2+ experience, so it's not too hard to convert to core profile 4.
At the time I just chose not to for better compatibility, but that was 5 years ago :)
It's not core profile 4 (although I have a working version of that), but it does offer a complete shader-based GL2+ experience, so it's not too hard to convert to core profile 4.
At the time I just chose not to for better compatibility, but that was 5 years ago :)
Also 'What Cupe said' plus..
- If you're going for cross-platform and mean desktop GL on windows and iOS/raspberry pi then a lot of stuff is common between GL ES 2 (iOS) and Opengl 2.1+ as long as you're careful with functions you use (no immediate mode). shaders may need some tweaking. (My winter project this year is a cross-platform app, I'm developing the bulk of my code on desktop gl and porting to iOS down the line). Last time I looked there were desktop GL ES dll's available for amd and nvidia.
- Fully agree that the time spent rolling your own window set up code is worthwhile as its not that huge a deal. (actually the only thing from the NeHe days that may be slightly relevant!).. the next point is also important.
- The window set up code varies significantly between ES and Desktop GL as they have created EGL to "help" with window set up on ES.
- The only library I use is GLEW for desktop GL, but thats not needed for ES as ES implementations use an import library.
- I haven't used GLM, and have rolled my own.. depends what your goals and ideals are.
- there is this c++ wrapper http://oglplus.org. i've not used it, but i have referred to the code when stuck a couple times. its still updated, and there are a good set of examples.
- as far as debugging once things are on screen there are a few simple tricks like switching up colours to see whats happening. the most useful is getting the vendors own tool, like AMDs gDEBugger and having good quality debug output/logging from your app. as cupe's point #8 says, it is easy to get stuck looking at a black screen. for me, this has mostly been down to some kind of GL state issue. (first time i tried to do render to texture i got stuck for ages.. it was discouraging, but satisfying once i sorted it, and yes.. it was a state thing - notice cupe had that first in his list too!)
- As far as resources go I can only recommend two books.
The 'blue book', the Fourth Edition of the OpenGL superbible covers the "modern" GL style, and as its been superceded is available very cheaply from amazon markeplace if you're into physical books like me.
There is also the 'gold book' the Open GL ES 2.0 programming guide. still holds a good price but i'm waiting for a drop :)
They (and newer editions) are also both out there and easy to find in pdf form.
The OpenGL 2.1 Api Manual is available here (as are all other versions if you dig) https://www.opengl.org/sdk/docs/man2/ but it looks like a prettier, less accessible version of http://docs.gl/
- If you're going for cross-platform and mean desktop GL on windows and iOS/raspberry pi then a lot of stuff is common between GL ES 2 (iOS) and Opengl 2.1+ as long as you're careful with functions you use (no immediate mode). shaders may need some tweaking. (My winter project this year is a cross-platform app, I'm developing the bulk of my code on desktop gl and porting to iOS down the line). Last time I looked there were desktop GL ES dll's available for amd and nvidia.
- Fully agree that the time spent rolling your own window set up code is worthwhile as its not that huge a deal. (actually the only thing from the NeHe days that may be slightly relevant!).. the next point is also important.
- The window set up code varies significantly between ES and Desktop GL as they have created EGL to "help" with window set up on ES.
- The only library I use is GLEW for desktop GL, but thats not needed for ES as ES implementations use an import library.
- I haven't used GLM, and have rolled my own.. depends what your goals and ideals are.
- there is this c++ wrapper http://oglplus.org. i've not used it, but i have referred to the code when stuck a couple times. its still updated, and there are a good set of examples.
- as far as debugging once things are on screen there are a few simple tricks like switching up colours to see whats happening. the most useful is getting the vendors own tool, like AMDs gDEBugger and having good quality debug output/logging from your app. as cupe's point #8 says, it is easy to get stuck looking at a black screen. for me, this has mostly been down to some kind of GL state issue. (first time i tried to do render to texture i got stuck for ages.. it was discouraging, but satisfying once i sorted it, and yes.. it was a state thing - notice cupe had that first in his list too!)
- As far as resources go I can only recommend two books.
The 'blue book', the Fourth Edition of the OpenGL superbible covers the "modern" GL style, and as its been superceded is available very cheaply from amazon markeplace if you're into physical books like me.
There is also the 'gold book' the Open GL ES 2.0 programming guide. still holds a good price but i'm waiting for a drop :)
They (and newer editions) are also both out there and easy to find in pdf form.
The OpenGL 2.1 Api Manual is available here (as are all other versions if you dig) https://www.opengl.org/sdk/docs/man2/ but it looks like a prettier, less accessible version of http://docs.gl/