What to keep in mind when moving ahead?

I’m constantly afraid of writing something one way, and having it come back to bite me in the butt because it doesn’t fit with what I’ll be doing later; it’s happened plenty for me already through learning OpenGL. Do you all have any tips/pointers for how to lay out an OpenGL-based program? Is it best to encapsulate stuff in classes as much as I can, or is that not too necessary? I’m just a bit reluctant to do so because, since I’m a beginner, I might write classes looking at an OpenGL object from the wrong perspective, and they might end up being useless in the end.

It is very hard to give any kind of advice, since you have to find a compromise between efficiency and easiness of development.
The efficiency assumes a minimization of state changing, while OO paradigm assumes encapsulation states with objects.
DSA (Direct State Access) could be the solution, but it is not a part of the core.

My general advice: make classes/objects for renderer, shaders, data containers (vertex and texture) etc.

I didn’t even know about DSA. I just read about it, and that looks like it could really help with some of my class wrappers. For example:

    void SetData(const T &Data_in)
        if((Data_in != Data) || Dirty)
            Data = Data_in;
            GLuint Initial;
            glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)(&Initial));
            GLuint Previous = Initial;
            for(auto &i : Uniforms)
                if(i.first != Previous)
                    Previous = i.first;
            if(Initial != Previous) glUseProgram(Initial);
        Dirty = false;

DSA would be great for that. Is DSA commonly supported?

AMD and NVidia both do. Click “EXT_direct_state_access” here:

Check vendor, GPU, and driver combinations you care about.