This document is an in-formal way to get up to speed with how to use opengl. Note I will be talking about opengl3+ but not vulkan.
high level overview
When I started learning about opengl I wasn't too familiar with c++ I highly recommend having the book "c++ primer" on hand at all times when working through things.
I recommend reading from the website learnopengl, it starts with including glfw into a c program, which in order to do you have to understand how to compile and link libraries into your own c programs, for this I learned about cmake using their official tutorial, once I finished the tutorial I was able to use glfw and create a basic window.
After creating a basic window I followed along with learnopengl until I could create the basic triangle, glfw also has a good reference for how to do it, from there I got through the camera tutorials and was able to move around while looking at a cube. From there you are pretty free to do your own thing.
a good way to remember the opengl pipeline
opengl is like the laziest person in the world who is staring at a TV and won't turn their head, if you want opengl to see something you're going to have to bring it into their field of vision, they're so lazy in fact that if you want to make it seem like an object is moving, they expect you to manipulate the entire world to make it seem like it is. That's why you to transform your objects over time and then apply a understanding perspective transformation.
That's pretty much a long winded way of saying the camera doesn't move.
more specifically
opengl defines clip space which is what gets rendered to the screen. If something is to be visible, we make sure it's inside of the clip space. If a point is not within clip space it will not be seen.
To make movement occur you need to encode your 3d translation into a matrix and then apply that to the vertices of objects in your world.
opengl does not make any assumptions, by default everything is drawn orthographically, if you want perspective you have to come up with a transformation which does that and then apply it in your shaders.
operating opengl
When operating opengl there are a few things that should help you remember how to use it.
There is one physical object that operates quite like it, the CD player:
This cd player doesn't necessarily look normal as it can hold 100 different cd's but this will make sense in a few seconds.
I want you to imagine it's 2008 and you want to expand your music library for easy listening. The first step is to go out to the store and buy blank cd's. Next up you have different genres you like listening to and you go on limewire/frostwire and download songs in the different genres. Let's say you make a few cd's like c_jazz
, c_rock
, c_classical
, etc...
You launch your cd burning software and make 15 cd's each one having songs from a different genre. You go back to your cd player and load all 15 cd's in. You also have some hi-fi speakers hooked up to the cd player that would benefit from some equalization, meaning that you can tweak the bass, mids and treble before any sound comes out, each genre of music has a general equalization setup that makes the music sound it's best. Suppose you have a few equalization set ups like e_jazz
, e_rock
, e_classical
, etc..
You're feeling like listening to some jazz, so you turn on your music system, and set your equalization to e_jazz
, and you select the cd c_jazz
and you press play, and everything sounds great. After going through a few songs, you decide to listen to some rock so you switch to the c_rock
cd and play a song, it sounds a little weird because you forgot to change the eq to be e_rock
, so you pause the song, make sure that e_rock
is enabled and then it all sounds good.
This process is exactly mirrored when using opengl. When you go out to buy your cd's you are calling glGenVertexArrays
. Suppose you download your songs along with some album art as well, when you burn this data onto your cd's you are using glGenBuffers
, glBindBuffer
and glBufferData
. When you put a cd that has album art into your cd player it still works fine because it knows where to get actual song data, so it knows how to interpret the info on the disk, this interpretation is equivalent to the methods glGetAttribLocation
, glEnableVertexAttribArray
, glVertexAttribPointer
.
recap
before
- go buy cd's /
glGenVertexArrays
- ex) create your shotgun VAO
- burn data to your cd's /
glGenBuffers, glBindBuffer, glBufferData
- ex) load in vertices for your shotgun model along with extra data like texture coordinates, normals, etc...
- tell the computer how to find the songs /
glGetAttribLocation, glEnableVertexAttribArray, glVertexAttribPointer
- ex) you tell opengl how to iterate through your data (a pointer for the 3d vertices in space and then a pointer for moving over the texture coordinates)
now play your music
- select the correct cd /
glBindVertexArray
- ex) you select the shotgun VAO and load it up
- enable the correct equalization /
glUseProgram
- ex) you select the correct shader for this model
- press play /
glDrawArrays, glDrawElements
- ex) draw the shotgun
- when done listening stop the cd from playing /
glBindVertexArray(0)
- ex) unload the shotgun data, maybe you need to draw hud elements now
facts
you don't need an active shader program to setup a vao in certain scenarios for example you can set up a vao by setting the pointers if your shaders use the location keyword, otherwise the program will have to be used to work.
resources
- https://kylehalladay.com/blog/tutorial/2016/11/04/Texture-Atlassing-With-Mips.html
a list of stuff that might be happening if you're stuck
ERROR 1281 in glEnableVertexAttribArray
This usually occurs when there was a problem when trying to enable a vertex attribute, and most of the time that's what this is, but this bug plagued me on one or two evenings before I realized the second way you can get this error.
You can also get this error if a vertex attribute is never used anywhere in your shader program, for me I had commented out using texture data, and then my texture coordinate vertex attribute stopped working, be sure that the vertex attributes you're binding are actually being used in the code, or else you may get this error.