Skinning/Blending with T&L


My topic is about OpenGL LISTs (glGenList, glCallList… etc). I’d like to represent a skin with bones via T&L, which means, I would create so many Lists as I have bones. For example, let us take the Left Upper Arm. I would record all FACES for Left Upper Arm and store them into a glList. Then i would just set the MAtrix and call my list for upper arm and render it. My problem is, how to manage souch faces, that have vertices from current and parent bone? For example: 2 vertices from upper arm and one from lower arm? I don’t want to drop that vertices.

Any suggestions?

Setting one modelview per bone would be horribly inefficient.

And to support vertices with weights to more than one bone, you need EXT_vertex_weighting. Which NVIDIA dropped support for in version 45 drivers or so. It never performed well anyway.

What’s worse, with EXT_vertex_weighting, you can only have two bones affecting an entire TRIANGLE, not just single vertices.

The right way to do it is to split your mesh into chunks, each of which reference no more than 24 bones. Most current game meshes can be split in 2 or 3 chunks this way. Then use a vertex program, using indirect addressing (ARL) to transform vertices with more than one transform matrix and blend.

If your card is DX7 or earlier (GeForce 4 MX or lower, Radeon 7000 and lower, etc) which don’t support vertex programs in hardware then you’re probably better off to write a software skinning function which calculates the vertex blending for the entire mesh, and then submits the mesh to GL in one DrawArrays() call.

The way it is done in general is by splitting the object based on how many bones will effect that part.

Then you can write a vp (if you are using VP?) for each case (the number of bones).

Each vertex can have a weight for each bone. You can store that in vertex.weight or wherever you wish.

For rendering, you bind to your VPs based on how many bones the part needs and also send your bones through the program’s constant registers.
The later can be done at initialization for efficiency.

How do you store 24 bones jwatte?

3 registers per bone; times 24 bones == 72 registers used for bone matrices. Leaves enough for other things.

Note: this assumes no non-uniform scale, which means you can transform the normals using the upper 3x3 of the bone transform matrices; no inverse transpose necessary.