Can someone tell me why OpenGL is so widely spread if it is not a good API? Being an open standard is certainly important, but is it enough for such popularity?
Because it’s all there is. If you want to do cross-platform development, it’s your only choice.
Oh, someone could come along with a new API. And maybe they could get, say, Apple to implement it. But will they get it implemented on Linux? Windows? No.
The simple fact is that, in many cases, the first thing that works is what people use. Not the best thing, not even a good thing, just the first thing that comes along that happens to work.
People will put up with crap if it allows them to do what they need to do and there are no other alternatives. People actually wrote code in Direct3D version 3.0. Look the API up; it’ll make your eyes bleed.
But if you want a very simple example of the “not good” parts of OpenGL’s API, here’s a quick example:
glUniform1i(program, samplerLocation, texUnit);
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, textureObject);
glBindSampler(texUnit, samplerObject);
Just look at what is necessary to bind a texture to a texture unit and compare it to a sampler object. You have to set the active texture. But not to the texture unit itself; no, you have to set it to “GL_TEXTURE0” plus the texture unit. Why? Hey, don’t look at me, it’s OpenGL’s cruft.
After setting the active texture unit, only then can you actually bind the texture. But glBindTexture also specifies the type of texture. Why? It is illegal to bind that texture as anything other than its original texture type. So what’s the point of having to remember and explicitly say “GL_TEXTURE_2D” if OpenGL already knows that?
Sampler objects, a much more recent API, work exactly like what you expect. The bind call includes the texture unit. Not an enum, but the texture unit itself.
Next, there’s the use of GLSL samplers as “uniforms,” even though they have virtually none of the traits of uniforms. They can’t be in uniform blocks or structs. Even if they’re in arrays, you have very restricted access to those arrays. And so forth.
Compare this to uniform blocks. Uniform blocks aren’t uniforms; they’re a completely different kind of thing. Just like samplers should have been.
And this doesn’t even get into other boneheaded API decisions, like linking shaders into a single monolithic program (pre-separate_program_objects, which has some spec issues itself).