Greetings, everyone.
Recently I've been interested in Warcraft3's model system.
I download the War3ModelEditor source code (from: http://home.magosx.com/index.php?topic=6.0), read it, and rewrite a program witch can render Warcraft3's model using OpenGL ES.
When I run this code on an Android phone, it looks good but, when there're more than 5 models in the screen, the FPS becomes very low.
Currently I do all the bone animation(matrix calculation and vertex position calculation) in CPU side.
I think it might be faster if we can do all these works in GPU side.
But I just don't know how to do it
The Warcraft3's vertex position calculation is complex for me.
Let me explain a little more.
In a Warcraft3's model, each vertex is linked to one or moe bone.
Here is how the War3ModelEditor calculate the vertex's position:
step1. for each bone[i], calculate matrix_list[i]
step2. for each vertex
position = (matrix_list[vertex_bone[0]] * v
+ matrix_list[vertex_bone[1]] * v
+ ...
+ matrix_list[vertex_bone[n]] * v) / n
note: n is the length of 'vertex_bone', each vertex may have a different 'vertex_bone'.
Actually, several vertex can share a same 'vertex_bone' array,
while several other vertex share another 'vertex_bone' array.
For example, a model with 500 vertices may have only 35 different 'vertex_bone' arrays.
But I don't know how can I make use of this, to optimize the performance.
?
The step1 may be easy. Since a typical Warcraft3 model will have less than 30 bones, we can do this step in CPU side without much performance hit.
But step2 is quite complex.
If I write a vertex shader (GLSL) it will be something like this:
uniform mat4 u_matrix_list[50]; /* there might be more ?? */
attribute float a_n;
attribute float a_vertex_bone[4]; /* there might be more ?? */
attribute vec4 a_position;
void main() {
float i;
vec4 p = vec4(0.0, 0.0, 0.0, 1.0);
for (i = 0; i < a_n; ++i) {
p += u_matrix_list[int(a_vertex_bone[int(i)])] * a_position;
}
gl_Position = p / float(a_n);
}
There're some problems.
1. When I compile the vertex shader above (on my laptop, either than an Android phone), it reports 'success' with a warning message 'OpenGL does not allow attributes of type float[4]'.
And some times (when I change the order of the 3 attributes) it cause my program goes down, with a message 'The NVIDIA OpenGL driver lost connection with the display driver due to exceeding the Windows Time-Out limit and is unable to continue.'
2. The book <OpenGL ES 2.0 Programming Guide> page 83, says that 'many OpenGL ES only mandates that array indexing be supported by constant integral expressions (there is an exception to this, which is the indexing of uniform variables in vertex shaders that is discussed in Chapter 8).', so the statement 'a_vertex_bone[int(i)]' might not work on some OpenGL ES hardware.
Actually I've never write such a complex(?) shader before.
Any one could you give me some advice?
Thank you.