For the vertex coordinates, you have a floating point number X and you need to convert it to one of the 16 bit alternatives in OpenGL: GL_SHORT or GL_UNSIGNED_SHORT or GL_HALF_FLOAT. First, you need to decide whether you want to use integers or floating point.
If you're going with integers, I recommend unsigned integers, so that zero maps to the minimal value and 65536 maps to the maximal value. With integers, you need to decide on the range of valid values for X.
Suppose you know that X is between Xmin and Xmax. Then, you can calculate a GL_UNSIGNED_SHORT-compatible representation by:
unsigned short convert_to_GL_UNSIGNED_SHORT(float x, float xmin, float xmax) {
if (x<=xmin)
return 0;
else if (x>=xmax)
return 65535;
else
return (unsigned short)((X-Xxmin)/(X-Xmax)*65535 + 0.5)
}
If you go with half floats, I suggest you look at 16-bit floats and GL_HALF_FLOAT
For the face indices, you have unsigned 32 bit integers, right? If they are all below 65536, you can easily convert them to 16 bit unsigned shorts by
unsigned short i16 = (unsigned short)i32;