Of course this overarching point doesn't work out so hot if you *only* do Direct3D coding, but otherwise you're going to be happy that you understand things at a lower level. Because if you're pursuing making games, especially if you're on your own or in any indie capacity, it's going to come up.
The enemy of this process is the middleware abstractions that you're likely engaging. But realistically this is where you'll be starting out. In regards to getting a game made, which ostensibly is your goal, engines like Unity, UDK, etc. are fantastic tools (although I have heard some horror stories about the licensing model for Unreal and I assume that Crytek's setup is similar). I would recommend then grabbing a book or two and working through some example applications outside of an engine.
Some quick notes on OpenGL specs:
Some quick notes on OpenGL specs:
- The old, nearly ancient approach, is the fixed pipeline stuff
- Programmable pipeline is where everyone is working now
- Literature and specs in this space can be confusing because they address both approaches
What you need is a solid baseline to work from. Due to the points above that can be difficult in regards to googling and, quite unfortunately, even when purchasing books.
Luckily the OpenGL-ES 2.0 specification is programmable only (i.e. free of the burden of backwards support for fixed pipeline functions), contemporary, clean, and has been largely accepted as the standard specification in the non-ES world. Of course there's more to the politics, legacy support decisions, and everything else that has taken place, but I'm neither qualified to comment on nor interested in the minutia... I just care about having a sane baseline of understanding.
Something to keep in mind if you're coming from systems with heavy layers of abstraction is that things are really more simple and rudimentary than you probably realized. You create a buffer of data on the card and fill it with your vertex data. It's just a buffer, nothing special to it. You create vertex layouts as templates for how those buffers of data are interpreted. When drawing, a vertex layout, one or more buffers of data, a shader program, and [usually] textures are bound and then a draw command issued. The vertex layout also specifies the names of things that are pushed into the vertex and fragment shaders.
So working through all of this and arriving at an understanding of the lower level, you can see how middleware often impose their own restrictions to make their system work, but that these restrictions are not inherently necessary.
As with everything in computers (and this may apply elsewhere but that's another topic altogether) is built from simple bits of logic. The difficulty and complexity come into play after layers and layers of simple pieces of logic are put down on top of one another. So while interacting with OpenGL/Direct3D directly isn't particularly difficult in simple cases, the complexity comes from trying to keep everything in the air while you draw hundreds of objects while running a simulation/game.
A fantastic reference for OpenGL-ES 2.0 is http://www.amazon.com/gp/product/0321502795
Also, while I'm at it, Real-Time Rendering, 3rd Edition, is a super comprehensive exploration of modern 3d graphics concepts and architectures and personally has been critical in filling in some gaps in my understanding of 3d pipelines (like texture filtering options, etc.).
And lastly, Game Engine Architecture covers modern engine creation very well and has many real-world and in general a real-world focus. It leaves out some things that are readily found on the internet, but that's one of the reasons I like it to be honest. Past a certain point the amount of hand-holding one needs is pretty minimal (and if not then the chances that you'll be successfully building your own game engine could be safely considered slim =)