+void GL_ConvertColorsFloatToByte(int numverts)
+{
+ int i, k, total;
+ // LordHavoc: to avoid problems with aliasing (treating memory as two
+ // different types - exactly what this is doing), these must be volatile
+ // (or a union)
+ volatile int *icolor;
+ volatile float *fcolor;
+ qbyte *bcolor;
+
+ total = numverts * 4;
+
+ // shift float to have 8bit fraction at base of number
+ fcolor = varray_color;
+ for (i = 0;i < total;)
+ {
+ fcolor[i ] += 32768.0f;
+ fcolor[i + 1] += 32768.0f;
+ fcolor[i + 2] += 32768.0f;
+ fcolor[i + 3] += 32768.0f;
+ i += 4;
+ }
+
+ // then read as integer and kill float bits...
+ icolor = (int *)varray_color;
+ bcolor = varray_bcolor;
+ for (i = 0;i < total;)
+ {
+ k = icolor[i ] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i ] = (qbyte) k;
+ k = icolor[i + 1] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 1] = (qbyte) k;
+ k = icolor[i + 2] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 2] = (qbyte) k;
+ k = icolor[i + 3] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 3] = (qbyte) k;
+ i += 4;
+ }
+}
+
+void GL_TransformVertices(int numverts)
+{
+ int i;
+ float m[12], tempv[4], *v;
+ m[0] = backendmatrix.m[0][0];
+ m[1] = backendmatrix.m[0][1];
+ m[2] = backendmatrix.m[0][2];
+ m[3] = backendmatrix.m[0][3];
+ m[4] = backendmatrix.m[1][0];
+ m[5] = backendmatrix.m[1][1];
+ m[6] = backendmatrix.m[1][2];
+ m[7] = backendmatrix.m[1][3];
+ m[8] = backendmatrix.m[2][0];
+ m[9] = backendmatrix.m[2][1];
+ m[10] = backendmatrix.m[2][2];
+ m[11] = backendmatrix.m[2][3];
+ for (i = 0, v = varray_vertex;i < numverts;i++, v += 4)
+ {
+ VectorCopy(v, tempv);
+ v[0] = tempv[0] * m[0] + tempv[1] * m[1] + tempv[2] * m[2] + m[3];
+ v[1] = tempv[0] * m[4] + tempv[1] * m[5] + tempv[2] * m[6] + m[7];
+ v[2] = tempv[0] * m[8] + tempv[1] * m[9] + tempv[2] * m[10] + m[11];
+ }
+}
+
+void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, GLuint *index)
+{
+ unsigned int i, j, in;
+ qbyte *c;
+ float *v;
+ GL_LockArray(firstvert, endvert - firstvert);
+ if (gl_mesh_drawmode.integer >= 3/* && (endvert - firstvert) <= gl_maxdrawrangeelementsvertices && (indexcount) <= gl_maxdrawrangeelementsindices*/)
+ {
+ // GL 1.2 or GL 1.1 with extension
+ qglDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, index);
+ CHECKGLERROR
+ }
+ else if (gl_mesh_drawmode.integer >= 2)
+ {
+ // GL 1.1
+ qglDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index);
+ CHECKGLERROR
+ }
+ else if (gl_mesh_drawmode.integer >= 1)
+ {
+ // GL 1.1
+ // feed it manually using glArrayElement
+ qglBegin(GL_TRIANGLES);
+ for (i = 0;i < indexcount;i++)
+ qglArrayElement(index[i]);
+ qglEnd();
+ CHECKGLERROR
+ }
+ else
+ {
+ // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver
+ // feed it manually
+ qglBegin(GL_TRIANGLES);
+ if (gl_state.texture[1]) // if the mesh uses multiple textures
+ {
+ // the minigl doesn't have this (because it does not have ARB_multitexture)
+ for (i = 0;i < indexcount;i++)
+ {
+ in = index[i];
+ c = varray_bcolor + in * 4;
+ qglColor4ub(c[0], c[1], c[2], c[3]);
+ for (j = 0;j < backendunits;j++)
+ {
+ if (gl_state.texture[j])
+ {
+ v = varray_texcoord[j] + in * 2;
+ qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, v[0], v[1]);
+ }
+ }
+ v = varray_vertex + in * 4;
+ qglVertex3f(v[0], v[1], v[2]);
+ }
+ }
+ else