1

I have this vertex array of a cube

float vertex_coordinates [] = {

-12.43796, -12.43796, 12.43796, -12.43796, 12.43796, 12.43796, 12.43796, 12.43796, 12.43796,
12.43796, 12.43796, 12.43796, 12.43796, -12.43796, 12.43796, -12.43796, -12.43796, 12.43796,
12.43796, -12.43796, -12.43796, 12.43796, 12.43796, -12.43796, -12.43796, 12.43796, -12.43796,
-12.43796, 12.43796, -12.43796, -12.43796, -12.43796, -12.43796, 12.43796, -12.43796, -12.43796,
-12.43796, -12.43796, -12.43796, -12.43796, 12.43796, -12.43796, -12.43796, 12.43796, 12.43796,
-12.43796, 12.43796, 12.43796, -12.43796, -12.43796, 12.43796, -12.43796, -12.43796, -12.43796,
12.43796, -12.43796, 12.43796, 12.43796, 12.43796, 12.43796, 12.43796, 12.43796, -12.43796,
12.43796, 12.43796, -12.43796, 12.43796, -12.43796, -12.43796, 12.43796, -12.43796, 12.43796,
-12.43796, 12.43796, 12.43796, -12.43796, 12.43796, -12.43796, 12.43796, 12.43796, -12.43796,
12.43796, 12.43796, -12.43796, 12.43796, 12.43796, 12.43796, -12.43796, 12.43796, 12.43796,
-12.43796, -12.43796, -12.43796, -12.43796, -12.43796, 12.43796, 12.43796, -12.43796, 12.43796,
12.43796, -12.43796, 12.43796, 12.43796, -12.43796, -12.43796, -12.43796, -12.43796, -12.43796,

};

At the moment I render it using

glVertexPointer(3, GL_FLOAT, 0, vertex__coordinates);

// texture pointer ...

// colour pointer

glDrawArrays(GL_TRIANGLES, 0, size);

How would I go about converting the vertex array into values that would render precisely the same cube but instead using GL_SHORT as the second parameter to glVertexPointer in order to speed up my code?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Dimitris
  • 682
  • 3
  • 14
  • 19

2 Answers2

3

In a preprocessing step we calculate the min and max of the object and use this to maximize the utilization of the precision in a short:

float modelMin[3] = {FLT_MAX, FLT_MAX, FLT_MAX}; //or std::numeric_limits<float>
float modelMax[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
for (int i = 0; i < size; ++i) {
    for (int j = 0; j < 3; ++j) {
        const float v = vertex_coordinates[i * 3 + j];
        modelMin[j] = std::min(modelMin[j], v);
        modelMax[j] = std::max(modelMax[j], v);
    }
}

short* short_coordinates = new short[size * 3];
for (int i = 0; i < size; ++i) {
    for (int j = 0; j < 3; ++j) {
        const float src = vertex_coordinates[i * 3 + j];
        short& dst = short_coordinats[i * 3 + j];
        dst = (short)floorf(((src - modelMin[j]) / (modelMax[j] - modelMin[j])) * 65536.0f - 32768.0f + 0.5f);
    }
}

And when drawing we do the following:

const float scale[3], bias[3];
for (int i = 0; i < 3; ++i) {
    scale[i] = (modelMax[j] - modelMin[j]) / 65536.0f;
    bias[i] = (32768.0f / 65536.0f) * (modelMax[j] - modelMin[j]) + modelMin[j];
}

glTranslatef(bias[0], bias[1], bias[2]);
glScalef(scale[0], scale[1], scale[2]);
glVertexPointer(3, GL_SHORT, 0, short_coordinates);
glDrawArrays(GL_TRIANGLES, 0, size);

/A.B.

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
0

instead of (+-)12.43796 use (+-)1

then apply a glScalef operation on your modelview matrix of 12.43796

I doubt this would speed up your code, however. All it will do is reduce your vertex array to half of its original size.

heeen
  • 4,736
  • 2
  • 21
  • 24
  • thanks! however, how would I apply this logic if I had multiple cubes of different sizes (+-6 for instance)? – Dimitris Nov 19 '09 at 12:44
  • 2
    On the iPhone, reductions in the size of the vertex array lead to significant performance boosts. Switching to shorts from floats boosted my rendering performance by 30% by itself. Dimitris, to apply this to various cases, you would just need to normalize your floating point values to +-32767. Find the largest absolute value of any vertex coordinate, and multiply all of your vertex values by 32767 divided by that value. You then can adjust your model view or projection matrix to match the new scaled size. – Brad Larson Nov 19 '09 at 17:05
  • Brad's suggestion works, but only if your model is centered roughly around (0,0,0). You'll need a regular scale and bias if it's not. – Alan Nov 19 '09 at 19:45