5 ms·
Do you write old-and-busted OpenGL or new-hotness OpenGL? Seems fairly clean to me when you leave out all that legacy crack the CAD vendors can't seem to give u
by dtf 14y ago
Do you write old-and-busted OpenGL or new-hotness OpenGL? Seems fairly clean to me when you leave out all that legacy crack the CAD vendors can't seem to give up.
- exDM69 14y ago> Do you write old-and-busted OpenGL or new-hotness OpenGL? Seems fairly clean to me when you leave out all that legacy crack the CAD vendors can't seem to give up. I usually use the latest GL only. Today that would be GL 4.2 core profile. Or GLES2. Sure the old fixed function pipeline and immediate mode are gone. But the API still sucks. Bind-to-modify semantics, using integers for handles, global state everywhere, etc. They are the big problems, for both, users and implementors.
- optymizer 14y agoWhat's wrong with bind-to-modify and using integers for handles? What alternatives are there? With my limited knowledge of OpenGL, I know you get a number, describing a resource in video card memory. I bet for an OpenGL implementation, binding a resource id means finding a pointer to the resource. Sounds reasonable to me. Would you rather get an invalid pointer that you should refrain from dereferencing (because you'll be reading from RAM, not GPU RAM)? That would've been a disaster. And I don't really know what 'global state everywhere' means. Do you mean that you keep OpenGL-related info in your program's global state? In that case, you should be using some AppState object to keep the state (and pass a pointer around). Otherwise, what global state is there "everywhere"?
- exDM69 14y ago> What's wrong with bind-to-modify and using integers for handles? What alternatives are there? glBindTexture(GL_TEXTURE_2D, my_texture_handle); glTexImage2D(GL_TEXTURE_2D, ....); Why not: glTexImage(my_texture_handle, ....); In addition to being used for accessing and modifying, the bindings are global values that affect rendering. In the example above, it affects which texture is used on the texture unit that has been selected by glActiveTexture. What a mess. > With my limited knowledge of OpenGL, I know you get a number, describing a resource in video card memory. I bet for an OpenGL implementation, binding a resource id means finding a pointer to the resource. Sounds reasonable to me. Wrong. There's a lot of software in between, before we start talking about GPU resources, so it refers to a structure on the CPU side. The integer-to-pointer lookup in between is another cache miss that we don't need (it has measurable L1 cache effects). This has, to some degree, been worked around by adding state objects like "Vertex Array Objects" (similar to D3D input layout). > Would you rather get an invalid pointer that you should refrain from dereferencing (because you'll be reading from RAM, not GPU RAM)? That would've been a disaster. Opaque pointers are used quite a lot in that way (e.g. D3D, via object pointers), it's a common idiom in C that adds a little type safety and documentation. In this case the pointers would be internal structures in the GL driver's user space. But you should not dereference them anyway. Unix uses integers as handles because the stuff it refers to is inside kernel memory, and you could poison the kernel by giving invalid pointers. > Do you mean that you keep OpenGL-related info in your program's global state? In that case, you should be using some AppState object to keep the state (and pass a pointer around). I don't. OpenGL does. In OpenGL, you have a global variable (actually: thread local) called the "context" which contains all the state of the rendering pipeline. In essence, it's a global variable that has side-effects when you access it.
- brooksbp 14y ago> Why not: > glTexImage(my_texture_handle, ....); Macro?
- nvoorhies 14y agoYou'll still have the driver doing the mapping from id to handle under the hood. It can get to be north of 25% of cpu cycles spent looking this up in some cases.
- cscheid 14y agoMacros here would make the problem worse. The problem is not notation, it's the call to glBindTexture. It has 1) inescapable measurable performance overhead and 2) affects state that changes the rendering output. So if you macro it, you're forcing yourself to calling glBindTexture even in the cases where that wasn't necessary. (say, if you had just called glBindTexture and knew that the right texture was bound anyway). And, in addition, you have to remember to store the previous state of the bound texture in case someone down the execution path wants to use that value. Macroing things which change global state is, in general, a terrible idea. If you don't macro it, your code has to remember whether the right texture has been bound, and design around that. It can be done for sufficiently simple cases, but the general solution also has performance overhead (checking a local variable before calling glBindTexture will get you into branch misprediction problems) You can imagine complicated solutions like state batching: writing a better, retained-mode domain-specific language atop OpenGL which will analyze the sequences of your calls before making it, and then remove all the unnecessary glBindTexture, etc. calls. But it's a major pain in the ass that simply shouldn't exist.
- jra101 14y agoYou can use the EXT_direct_state_access instead of bind-to-modify. glBindTexture(GL_TEXTURE_2D, texId); glTexImage2D(GL_TEXTURE_2D, ...); vs glTextureImage2DEXT(texId, GL_TEXTURE_2D, ...);
- exDM69 14y agoEXT_direct_state_access is not very well maintained. And bind-to-modify is just one problem, there are others. Everything is mutable in OpenGL (a stark contrast to D3D), and that makes things complicated.