4 ms·
The craziest thing I found in OpenGL API was that there was no way to bind data to a primitive. You have to repeat it for every vertex of the primitive, which s
by hrjet 12y ago
The craziest thing I found in OpenGL API was that there was no way to bind data to a primitive. You have to repeat it for every vertex of the primitive, which sometimes also means that you can't share vertices between primitives. This results in a 9x overhead in data for triangles!
Examples illustrating what I am saying:
http://stackoverflow.com/q/6530700 http://stackoverflow.com/q/6530700
http://stackoverflow.com/q/6056679 http://stackoverflow.com/q/6056679
http://stackoverflow.com/q/23879737 http://stackoverflow.com/q/23879737
- exDM69 12y agoYou can definitely "bind data to primitives" and share vertices between triangles in OpenGL and that has always been possible ever since the first version of OpenGL. Are you talking about legacy OpenGL style glBegin/glVertex/glEnd? That hasn't been the preferred way of drawing ever, and since OpenGL 1.5 (circa 1999), vertex buffers are the way to go. If you want to share vertices between triangles, you should build and index buffer and use glDrawElements* functions.
- hrjet 12y agoI meant to say "bind data to elements". It's been a while since I programmed in OpenGL so the terminology is shaky. I saw your other answer below too. I am not able to visualise how the duplicate data could affect caching postively. But anyway, I don't have deep knowledge about the hardware. And I didn't know other 3D APIs had the same problem. Thanks for mentioning that.
- flohofwoe 12y agoYou can share vertices between primitives if all vertex components are the same and indexing is used. That's the same on all 3D APIs though. I think the only exception was the Wii where you could have positions, texcoords, normals, etc... in different arrays of different sizes and index them with multiple indices per vertex. I can't image that this was efficient though...
- hrjet 12y agoThere are some cases where you can't share vertices. For example, flat shading with face normals. So now you need to put that normal data into every vertex and you have to duplicate vertices as well, which is 9x data for a very common use-case.
- flohofwoe 12y agoTrue, but I don't know any 3D API which allows this except for the OpenGL 1.x style glBegin/glEnd which doesn't map to an efficient hardware implementation. This specific problem can be solved by not fetching per-vertex normals at all, and compute the face normals on the fly in the geometry shader, not sure whether this is worth it though, geometry shaders have a reputation for being nearly useless.
- exDM69 12y ago> For example, flat shading with face normals I see your point, having interlaced vs. non-interlaced data arrays. Many 3d model interchange formats use the latter because it saves some bytes. All 3D APIs use the former. But this example works exactly the same way on every 3d API out there. Having a single index per vertex (rather than separate indices into position, normal, texcoord arrays) simplifies the vertex pipeline a little bit. Using a single index will also make more efficient caching of vertex data and post-transform caching (ie. output of vertex shaders are cached if possible). Separate indices would need more complicated cache addressing. Of course, with modern OpenGL, you can do more complicated addressing of data in the vertex shader. This isn't likely going to increase performance, though. However, this is largely a non-issue. Modern 3d graphics simply isn't limited by the number of vertices or triangles. Having to duplicate some data isn't going to make a significant difference in practice. Also, you can toggle the interpolation mode for varying variables (ie. fragment shader inputs) so you can use per-vertex normals and make them flat shaded if your whole model is going to be flat shaded.