Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Fecotourist
Nov 1, 2008
Say I have a mesh of vertices that I want to draw as triangle strips or
triangle fans. The vertices are packed into (an) array(s), and vertices
are shared by multiple primitives, of course.
1. Does glVertexPointer(),glNormalPointer(), etc. followed by glDrawElements()
have close to optimal performance nowadays, or is there a different interface
that's a much better choice? At present, each primitive set is 8 vertices, a
hexagon drawn as a trifan.
2. Does it matter whether
a: the vertices, normals, and texture coordinates are packed into an array of structs
b: there are separate vertex array, normal array, TC array
3. How much does spatial locality matter to performance on modern hardware?
glDrawElements() takes an array of indices, is it faster if the used vertices are
close together in memory than if the indices (uint) jump all over the place?

I'm basically looking for current common knowledge. I don't want to put a lot
of work into using an interface that's about to be obsoleted and/or stupidly
inefficient.

Adbot
ADBOT LOVES YOU

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

Both ways are pretty common, and it probably doesn't matter especially unless you already know it matters.
Thanks, exactly what I was looking for.

Avenging Dentist posted:

Why are you worrying about locality when you're operating on sets of 8 verts?

Let me rephrase the question. Given a big vertex array and two possible index arrays, A and B:
code:
A = { 0, 1, 2, 3, 4, 5, 6, 1}
B = { 995, 50, 50210, 3323, 472, 100205, 3, 50}
Is A faster because the vertices it references are close in memory? Is it worth shuffling the vertex array to make index arrays like A more common? I want to draw lots and lots of these 8-vert primitive sets every frame, as many as can be rendered at a given frame rate.

Avenging Dentist posted:

Also: why do you always hit "enter" after a few words? It's really annoying.

Is it more annoying than a single-line post that is stretched to 50 line equivalents by a big dumb avatar?

Avenging Dentist posted:

Also also: why do people (in general, not just you) always ask for help before they've even started on a project? You'll learn much better if you work on things yourself and maybe consult a book. :confused:

I don't think that's the case here. My application already runs ok using OpenSceneGraph, [which seems to be using the glDrawElements() path the way I've been doing it]. For various reasons, I'm switching from OSG to SDL plus explicit OpenGL. If I'm doing that work, I just want to follow a good path.

Fecotourist
Nov 1, 2008

Avenging Dentist posted:


Have you run performance tests to determine where your bottlenecks are? Those would give you way more information than some random internet people who don't know the specifics of your code.

My meshes are LOD'ed, and the global detail level is adjusted continuously to maintain a target frame rate, so I can assert pretty confidently that rendering will often be a bottleneck. More detail than that, I don't know. With per-vertex normals and a single texture (cheap per pixel, right?), I have the impression that it's worth a little effort up front to make the geometry expression efficient.

But my take home seems to be that glDrawElements() is not a totally stupid way to go, that packed/separate doesn't matter a priori, and that it's probably not a huge deal that my index arrays jump around in memory, so thanks for that confirmation.

Fecotourist
Nov 1, 2008

Mata posted:

Yeah I worked out an algorithm in my head but it's still funny how something like "create a list of unique vertices" which would be EZ in say, python, is difficult for me in C++.

If you'd use a dictionary in Python (maybe even if you wouldn't), use a std::map in C++. Something like a map from tuple<vertex_pointer,normal_pointer...> to index in the vertex array. Map is happy to tell you if it's already seen something, with log complexity.
Or I'm completely missing the point.

vvvvvvvvvv When I did this, it was at load time. Given raw vertices, normals, etc. and the code to draw the geometry, replaced glVertex();glNormal()... with a map lookup. If the combination was novel, add a new interleaved vertex to the array and do a map insertion. Otherwise just took the index the map gave me. Either way the index array got a new index.

Fecotourist fucked around with this message at 17:54 on Nov 13, 2009

Fecotourist
Nov 1, 2008
I had the luxury of just relying on pointer comparison. I was really just going from an independent multiple-index format to single-index.

Fecotourist
Nov 1, 2008
The page on Bindless Graphics says it's supported on G80 (8800?) and higher. Would you expect it to be supported on Ion, which is based on the 9400?

Fecotourist
Nov 1, 2008

roomforthetuna posted:

This isn't really a code problem so much as a math problem - what's the correct skinning transformation for each of these 3 bones? For the first bone it's obviously just R1, but it can't be R2*R1 for the second because that would do both transformations around the origin.

Is this relevant?
http://isg.cs.tcd.ie/projects/DualQuaternions/

The dual quaternion may be what you're looking for in terms of putting rotation and translation into one entity that can be interpolated, etc.

Fecotourist
Nov 1, 2008
It's probably worth understanding how to do the job with vector components rather than angles. There is no end to the gross stuff you'll run into. All too often a nasty-looking expression involving cascaded forward and inverse trig functions simplifies to a couple of multiplies and adds. And you'll never again have to wrap an angle back into [0,360).

Allow yourself an inverse trig function if you need to print a value for a human to look at, otherwise use unit vectors to encode directions. For doing rotations, the rotation matrix is trivial to construct from the components of a direction vector.

Fecotourist fucked around with this message at 06:29 on Oct 6, 2010

Adbot
ADBOT LOVES YOU

Fecotourist
Nov 1, 2008
Given that each sample is evaluated 8 times (as each of 8 corners of the cube), is it possible that a vertex passes the threshold on some evaluations and not others? Maybe the threshold value is being computed for each comparison and the optimizer is generating code with slightly varying numerical behavior.

The surface can be closed only if every sample is found to be greater than threshold all 8 times or less all 8 times.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply