OpenGL: glGenBuffer vs glGenBuffersARB - c++

What is the difference between the functions glGenBuffers()/glBufferData()/etc, and the functions with ARB appended to the function name glGenBuffersARB()/glBufferDataARB()/etc. I tried searching around but no one ever points out the difference, merely they just use one or the other.
Also, is it common for either function to be unavailable on some computers? What's the most common way of getting around that kind of situation without falling back to immediate mode?

glGenBuffers() is a core OpenGL function in OpenGL 1.5 and later; glGenBuffersARB() was an extension implementing the same functionality in earlier versions.
Unless you're developing for an ancient system, there's no longer any reason to use the ARB extension.

Related

Can glbinding load extensions in GL version <3.0?

I'm comparing GL function loading libraries, and glbinding looks promising. However, I've had problems with other loader libraries (specifically glLoadGen) not being able to load extension functions in OpenGL versions lower than 3.0 due to vagaries of GL versioning. Does glbinding have this problem?
Actually, glbinding doesn't care whether a function pointer comes from an extension or not.
There are two modes how to resolve OpenGL function pointers with glbinding.
The first (and default) is to resolve all function pointers at once, which will include every function pointer back to OpenGL 1.0 including all extensions that are available in the current active context.
The second is to resolve function pointers with their first use and comes with the same characteristics.
Maybe you speak of querying the list of available extensions, which glbinding currently supports with an OpenGL 3.0 context or newer.
The query of extensions for the older versions still needs to be done (thanks for pointing this out, issue is created: https://github.com/hpicgs/glbinding/issues/46).

OpenGL - Samplers in opengl 3.1?

I'm using samplers quite frequently in my application and everything has been working fine.
The problem is, I can only use opengl 3.1 on my laptop. According to the documentation, samplers are only available at opengl 3.3 or higher, but here's where I'm getting a bit confused.
I can use 'glGenSamplers' just fine, no errors are generated and the sampler ID seems fine as well. When using 'glBindSampler' on a valid texture, I get a 'GL_INVALID_VALUE​' error.
Can anyone clear this up for me? If samplers aren't available in opengl 3.1, why can I use glGenSamplers without a problem?
What can I do to provide backwards compatibility? I'm guessing my only option will be to set the texture parameters every time the texture is being used for rendering, if samplers aren't available?
There are two possibilities:
Your graphics card/driver supports ARB_sampler_objects, in this case it is unsurprising that the function is supported. Feel free to use it.
The function is present anyway. In this case, strange as it sounds, you are not allowed to use it.
Check whether glGetStringi(GL_EXTENSION, ...) returns the sampler objects extension at some index. Only functionality from extensions that the implementation advertizes as "supported" is allowed to be used.
If you find some functions despite no support, they might work anyway, but they might as well not. It's undefined.
Note that although you would normally expect the function being named glGenSamplersARB when it comes from an ARB extension, that is not the case here, since this is a "backwards extension" that provides selected functionality which is present identically in a later version on hardware which isn't able to provide the full functionality of that later version.
(About the error code, note comment by Brett Hale)

Defining GL_GLEXT_PROTOTYPES vs getting function pointers

I am writing a program which depends on OpenGL 2.0 or above. Looking at the specs of GL 2.0 I see that the extension defined in ARB_shader_objects has been promoted which I suppose mean that the ARB prefix is no more required for GL version 2.0 and above and any implementation supporting > GL2.0 will have this as part of the core implementation.
Having said that when I compile my program gcc on Linux gives warning: implicit declaration of function. One way to get these functions is to declare them in the program itself and then get the function pointers via *GetProcAddress function.
The other way is to define GL_GLEXT_PROTOTYPES before including glext.h which circumvents the problem of getting the function pointers for each of the functions which are by default now present in GL2.0 or above. Could someone please suggest if that is a recommended and right way? The base line is that my program requires OpenGL 2.0 or above and I don't want to support anything less than GL2.0.
Just in case someone suggests to use glee or glew, I don't want to use/ have option to use glee or glew libraries for achieving the same.
There are two issues here.
GL_ARB_shader_objects indeed was promoted to core in GL2.0, but the API has been slightly changed for the core version, so it is not just the same function names without the ARB prefix, e.g. there is glCreateShader() instead of glCreateShaderObjectARB(), and the two functions glGetShaderInfoLog() and glGetProgramInfoLog() replacing glGetInfoLogARB() and some other minor differences of this sort.
The second issue is assuming that the GL library exports all
the core functions. On Linux that is usually the case (not only for core functions, but basically for everything), but there is no standard guaranteeing that. The OpenGL ABI for Linux just requires:
3.4. The libraries must export all OpenGL 1.2, GLU 1.3, GLX 1.3, and ARB_multitexture entry points statically.
There are proposals for an update but I haven't heard anything about that recently.
Windows only exports OpenGL 1.1 core, as the opengl32.dll is part of the OS and the ICD is in a separate dll. You have to query the function pointers for virtually everything there.
So the most portable way is definitively to query the stuff, no matter if you do it manually or use some library like glew.

How to define OpenGL extensions correctly?

I get OpenGL extensions using wglGetProcAddress. But on different machines it use different parameters: e.g. for using glDrawArrays I should call wglGetProcAddress with "glDrawArrays" or "glDrawArraysEXT". How todefine what to use?
There's two pretty good OpenGL extension loading libraries out there - GLee and GLEW. GLEW is currently more up to date that GLee. Even if you don't want to use either of them, they're both open source, so you could do worse than taking a peek on how they do things.
You may also want to check http://www.opengl.org/sdk/ which is a decent collection of OpenGL documentation online.
"glDrawArrays" or "glDrawArraysEXT"
Both! Even if they're named similar, and more often than not procedure signature and token values are identical, they are different extensions, where details may be very well different.
It's ultimately up to the programmer to decide, which functions are used. And if a program uses an …EXT variant of a function, then this very function must be loaded even if there may be a …ARB or core function of same name; they may differ in signature and/or used tokens and state, so you can't mindlessly replace one for another.

Multiple context with different version

I'm experimenting on list sharing among multiple OpenGL contextes. It is a great feature, since it allow me to execute parallel rendering threads.
But since I'm using CreateContextAttribs, I offer the possibility to request a specific OpenGL implementation. So, it can happen the some context is implementing version 3.2+ while the other is implementing version 2.1.
Actually works quite fine, but I suspect that this modus operandi hides some side effect. What would be a list of problems which can occour while using contextes having different versions?
Beyond this, I query the implemented extentions for each context version, since I suppose that different versions can support different extension, is this right? And what about function pointers? I have to requery them for each context with different version (indeed, pointers changes depending on versions)?
It is a great feature, since it allow me to execute parallel rendering threads.
Accessing the GPU from multiple threads in parallel is a serious performance killer. Don't do it. The GPU will parallelize any rendering internally. Anything else you do, is throwing logs into its wheels.
If you want to speed up asset uploads, look into buffer objects and asynchronous access. But stay away from doing multiple OpenGL contexts in separate threads at the same time.
But since I'm using CreateContextAttribs, I offer the possibility to request a specific OpenGL implementation. So, it can happen the some context is implementing version 3.2+ while the other is implementing version 2.1.
Actually works quite fine, but I suspect that this modus operandi hides some side effect. What would be a list of problems which can occour while using contextes having different versions?
This is actually a very good question. And the specification answers it clearly:
1) Can different GL context versions share data?
PROPOSED: Yes, with restrictions as defined by the supported feature
sets. For example, program and shader objects cannot be shared with
OpenGL 1.x contexts, which do not support them.
NOTE: When the new object model is introduced, sharing must be
established at creation time, since the object handle namespace is
also shared. wglShareLists would therefore fail if either context
parameter to it were to be a context supporting the new object
model.
Beyond this, I query the implemented extentions for each context version, since I suppose that different versions can support different extension, is this right?
Indeed querying the set of supported extensions for each context is the right thing to do.
And what about function pointers? I have to requery them for each context with different version (indeed, pointers changes depending on versions)?
On Windows extension function pointers are tied to the context. The sane way to do this is having some
typedef struct OpenGLExtFunctions_S {
GLvoid (*glFoobarEXT)(GLenum, ...);
/* OpenGL function pointers */
} OpenGLExtFunctions;
/* currentContextFunction must be thread loacal since
contexts are active in one thread only */
__declspec(thread) OpenGLExtFunctions *currentContextFunctions;
#define glFoobarEXT (currentContextFunctions->glFoobarEXT);
#define ...
And wrap wglMakeCurrent and wglMakeContextCurrent with some helper function that sets the currentContextFunctions pointer to the one of the context being made current. Extension wrapper libraries like GLEW do all this grunt work for you, so you don't have to bother doing it yourself.
On X11/GLX things are much simpler: The function pointers returned by glXGetProcAddress must be the same for all contexts, so no need to switch them.