#ifdef HAVE_CONFIG_H # include "config.h" #endif #include "QF/sys.h" #include "QF/GL/defines.h" #include "QF/GL/funcs.h" typedef void (*qfgl_func_t) (const GLvoid *); static const GLvoid *color_pointer; static GLsizei color_stride; static qfgl_func_t color_func; static int color_enabled = 0; static const GLvoid *edgeflag_pointer; static GLsizei edgeflag_stride; static int edgeflag_enabled = 0; static const GLvoid *index_pointer; static GLsizei index_stride; static qfgl_func_t index_func; static int index_enabled = 0; static const GLvoid *normal_pointer; static GLsizei normal_stride; static qfgl_func_t normal_func; static int normal_enabled = 0; static const GLvoid *texcoord_pointer; static GLsizei texcoord_stride; static qfgl_func_t texcoord_func; static int texcoord_enabled = 0; static const GLvoid *vertex_pointer; static GLsizei vertex_stride; static qfgl_func_t vertex_func; static int vertex_enabled = 0; static qfgl_func_t *color_functions[][8] = { { (qfgl_func_t *) (char *) &qfglColor3bv, (qfgl_func_t *) (char *) &qfglColor3ubv, (qfgl_func_t *) (char *) &qfglColor3sv, (qfgl_func_t *) (char *) &qfglColor3usv, (qfgl_func_t *) (char *) &qfglColor3iv, (qfgl_func_t *) (char *) &qfglColor3uiv, (qfgl_func_t *) (char *) &qfglColor3fv, (qfgl_func_t *) (char *) &qfglColor3dv, }, { (qfgl_func_t *) (char *) &qfglColor4bv, (qfgl_func_t *) (char *) &qfglColor4ubv, (qfgl_func_t *) (char *) &qfglColor4sv, (qfgl_func_t *) (char *) &qfglColor4usv, (qfgl_func_t *) (char *) &qfglColor4iv, (qfgl_func_t *) (char *) &qfglColor4uiv, (qfgl_func_t *) (char *) &qfglColor4fv, (qfgl_func_t *) (char *) &qfglColor4dv, }, }; static qfgl_func_t *index_functions[] = { (qfgl_func_t *) (char *) &qfglIndexubv, (qfgl_func_t *) (char *) &qfglIndexsv, (qfgl_func_t *) (char *) &qfglIndexiv, (qfgl_func_t *) (char *) &qfglIndexfv, (qfgl_func_t *) (char *) &qfglIndexdv, }; static qfgl_func_t *normal_functions[] = { (qfgl_func_t *) (char *) &qfglNormal3bv, (qfgl_func_t *) (char *) &qfglNormal3sv, (qfgl_func_t *) (char *) &qfglNormal3iv, (qfgl_func_t *) (char *) &qfglNormal3fv, (qfgl_func_t *) (char *) &qfglNormal3dv, }; static qfgl_func_t *texcoord_functions[][4] = { { (qfgl_func_t *) (char *) &qfglTexCoord1sv, (qfgl_func_t *) (char *) &qfglTexCoord1iv, (qfgl_func_t *) (char *) &qfglTexCoord1fv, (qfgl_func_t *) (char *) &qfglTexCoord1dv, }, { (qfgl_func_t *) (char *) &qfglTexCoord2sv, (qfgl_func_t *) (char *) &qfglTexCoord2iv, (qfgl_func_t *) (char *) &qfglTexCoord2fv, (qfgl_func_t *) (char *) &qfglTexCoord2dv, }, { (qfgl_func_t *) (char *) &qfglTexCoord3sv, (qfgl_func_t *) (char *) &qfglTexCoord3iv, (qfgl_func_t *) (char *) &qfglTexCoord3fv, (qfgl_func_t *) (char *) &qfglTexCoord3dv, }, { (qfgl_func_t *) (char *) &qfglTexCoord4sv, (qfgl_func_t *) (char *) &qfglTexCoord4iv, (qfgl_func_t *) (char *) &qfglTexCoord4fv, (qfgl_func_t *) (char *) &qfglTexCoord4dv, }, }; static qfgl_func_t *vertex_functions[][4] = { { (qfgl_func_t *) (char *) &qfglVertex2sv, (qfgl_func_t *) (char *) &qfglVertex2iv, (qfgl_func_t *) (char *) &qfglVertex2fv, (qfgl_func_t *) (char *) &qfglVertex2dv, }, { (qfgl_func_t *) (char *) &qfglVertex3sv, (qfgl_func_t *) (char *) &qfglVertex3iv, (qfgl_func_t *) (char *) &qfglVertex3fv, (qfgl_func_t *) (char *) &qfglVertex3dv, }, { (qfgl_func_t *) (char *) &qfglVertex4sv, (qfgl_func_t *) (char *) &qfglVertex4iv, (qfgl_func_t *) (char *) &qfglVertex4fv, (qfgl_func_t *) (char *) &qfglVertex4dv, }, }; static void qfgl_ColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { int index; int bytes = 0; switch (type) { case GL_BYTE: index = 0; bytes = sizeof (GLbyte); break; case GL_UNSIGNED_BYTE: index = 1; bytes = sizeof (GLubyte); break; case GL_SHORT: index = 2; bytes = sizeof (GLshort); break; case GL_UNSIGNED_SHORT: index = 3; bytes = sizeof (GLushort); break; case GL_INT: index = 4; bytes = sizeof (GLint); break; case GL_UNSIGNED_INT: index = 5; bytes = sizeof (GLuint); break; case GL_FLOAT: index = 6; bytes = sizeof (GLfloat); break; case GL_DOUBLE: index = 7; bytes = sizeof (GLdouble); break; default: return; } color_pointer = ptr; // color_stride = stride + size * bytes; color_stride = stride ? stride : size * bytes; color_func = *color_functions[size - 3][index]; } static void qfgl_EdgeFlagPointer (GLsizei stride, const GLvoid *ptr) { edgeflag_pointer = ptr; edgeflag_stride = stride + sizeof (GLboolean); } static void qfgl_IndexPointer (GLenum type, GLsizei stride, const GLvoid *ptr) { int index; int bytes = 0; switch (type) { case GL_UNSIGNED_BYTE: index = 0; bytes = sizeof (GLubyte); break; case GL_SHORT: index = 1; bytes = sizeof (GLshort); break; case GL_INT: index = 2; bytes = sizeof (GLint); break; case GL_FLOAT: index = 3; bytes = sizeof (GLfloat); break; case GL_DOUBLE: index = 4; bytes = sizeof (GLdouble); break; default: return; } index_pointer = ptr; index_stride = stride + bytes; index_func = *index_functions[index]; } static void qfgl_NormalPointer (GLenum type, GLsizei stride, const GLvoid *ptr) { int index; int bytes = 0; switch (type) { case GL_BYTE: index = 0; bytes = sizeof (GLbyte); break; case GL_SHORT: index = 1; bytes = sizeof (GLshort); break; case GL_INT: index = 2; bytes = sizeof (GLint); break; case GL_FLOAT: index = 3; bytes = sizeof (GLfloat); break; case GL_DOUBLE: index = 4; bytes = sizeof (GLdouble); break; default: return; } normal_pointer = ptr; normal_stride = stride + bytes; normal_func = *normal_functions[index]; } static void qfgl_TexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { int index; int bytes = 0; switch (type) { case GL_SHORT: index = 0; bytes = sizeof (GLshort); break; case GL_INT: index = 1; bytes = sizeof (GLint); break; case GL_FLOAT: index = 2; bytes = sizeof (GLfloat); break; case GL_DOUBLE: index = 3; bytes = sizeof (GLdouble); break; default: return; } texcoord_pointer = ptr; texcoord_stride = stride + size * bytes; texcoord_func = *texcoord_functions[size - 1][index]; } static void qfgl_VertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { int index; int bytes = 0; switch (type) { case GL_SHORT: index = 0; bytes = sizeof (GLshort); break; case GL_INT: index = 1; bytes = sizeof (GLint); break; case GL_FLOAT: index = 2; bytes = sizeof (GLfloat); break; case GL_DOUBLE: index = 3; bytes = sizeof (GLdouble); break; default: return; } vertex_pointer = ptr; vertex_stride = stride + size * bytes; vertex_func = *vertex_functions[size - 2][index]; } static void qfgl_InterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer) { const GLbyte *ptr = pointer; switch (format) { case GL_V2F: stride += 2 * sizeof (GLfloat); break; case GL_V3F: stride += 3 * sizeof (GLfloat); break; case GL_C4UB_V2F: stride += 4 * sizeof (GLubyte); stride += 2 * sizeof (GLfloat); break; case GL_C4UB_V3F: stride += 4 * sizeof (GLubyte); stride += 3 * sizeof (GLfloat); break; case GL_C3F_V3F: stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_N3F_V3F: stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_C4F_N3F_V3F: stride += 4 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_T2F_V3F: stride += 2 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_T4F_V4F: stride += 4 * sizeof (GLfloat); stride += 4 * sizeof (GLfloat); break; case GL_T2F_C4UB_V3F: stride += 2 * sizeof (GLfloat); stride += 4 * sizeof (GLubyte); stride += 3 * sizeof (GLfloat); break; case GL_T2F_C3F_V3F: stride += 2 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_T2F_N3F_V3F: stride += 2 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_T2F_C4F_N3F_V3F: stride += 2 * sizeof (GLfloat); stride += 4 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); break; case GL_T4F_C4F_N3F_V4F: stride += 4 * sizeof (GLfloat); stride += 4 * sizeof (GLfloat); stride += 3 * sizeof (GLfloat); stride += 4 * sizeof (GLfloat); break; default: break; } switch (format) { case GL_T2F_V3F: case GL_T2F_C4UB_V3F: case GL_T2F_C3F_V3F: case GL_T2F_N3F_V3F: case GL_T2F_C4F_N3F_V3F: qfgl_TexCoordPointer (2, GL_FLOAT, stride - 2 * sizeof (GLfloat), ptr); ptr += 2 * sizeof (GLfloat); break; case GL_T4F_V4F: case GL_T4F_C4F_N3F_V4F: qfgl_TexCoordPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat), ptr); ptr += 4 * sizeof (GLfloat); break; default: break; } switch (format) { case GL_C4UB_V2F: case GL_C4UB_V3F: case GL_T2F_C4UB_V3F: qfgl_ColorPointer (4, GL_UNSIGNED_BYTE, stride - 4 * sizeof (GLubyte), ptr); ptr += 4 * sizeof (GLubyte); break; case GL_C3F_V3F: case GL_T2F_C3F_V3F: qfgl_ColorPointer (3, GL_FLOAT, stride - 3 * sizeof (GLfloat), ptr); ptr += 3 * sizeof (GLfloat); break; case GL_C4F_N3F_V3F: case GL_T2F_C4F_N3F_V3F: case GL_T4F_C4F_N3F_V4F: qfgl_ColorPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat), ptr); ptr += 4 * sizeof (GLfloat); break; default: break; } switch (format) { case GL_N3F_V3F: case GL_C4F_N3F_V3F: case GL_T2F_N3F_V3F: case GL_T2F_C4F_N3F_V3F: case GL_T4F_C4F_N3F_V4F: qfgl_NormalPointer (GL_FLOAT, stride - 3 * sizeof (GLfloat), ptr); ptr += 3 * sizeof (GLfloat); break; default: break; } switch (format) { case GL_V2F: case GL_C4UB_V2F: qfgl_VertexPointer (2, GL_FLOAT, stride - 2 * sizeof (GLfloat), ptr); ptr += 2 * sizeof (GLfloat); break; case GL_V3F: case GL_C4UB_V3F: case GL_C3F_V3F: case GL_N3F_V3F: case GL_C4F_N3F_V3F: case GL_T2F_V3F: case GL_T2F_C4UB_V3F: case GL_T2F_C3F_V3F: case GL_T2F_N3F_V3F: case GL_T2F_C4F_N3F_V3F: qfgl_VertexPointer (3, GL_FLOAT, stride - 3 * sizeof (GLfloat), ptr); ptr += 3 * sizeof (GLfloat); break; case GL_T4F_V4F: case GL_T4F_C4F_N3F_V4F: qfgl_VertexPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat), ptr); ptr += 4 * sizeof (GLfloat); break; default: break; } } static void qfgl_ArrayElement (GLint i) { if (texcoord_enabled) texcoord_func ((char*)texcoord_pointer + i * texcoord_stride); if (edgeflag_enabled) qfglEdgeFlagv ((byte*)edgeflag_pointer + i * edgeflag_stride); if (color_enabled) color_func ((char*)color_pointer + i * color_stride); if (normal_enabled) normal_func ((char*)normal_pointer + i * normal_stride); if (index_enabled) index_func ((char*)index_pointer + i * index_stride); if (vertex_enabled) vertex_func ((char*)vertex_pointer + i * vertex_stride); } static void qfgl_DrawArrays (GLenum mode, GLint first, GLsizei count) { GLint i; qfglBegin (mode); for (i = first; i < first + count; i++) qfgl_ArrayElement (i); qfglEnd (); } static void qfgl_DrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { GLsizei i; const GLubyte *ub_indices; const GLushort *us_indices; const GLuint *ui_indices; switch (type) { case GL_UNSIGNED_BYTE: ub_indices = indices; for (i = 0; i < count; i++) qfgl_ArrayElement (ub_indices[i]); break; case GL_UNSIGNED_SHORT: us_indices = indices; for (i = 0; i < count; i++) qfgl_ArrayElement (us_indices[i]); break; case GL_UNSIGNED_INT: ui_indices = indices; for (i = 0; i < count; i++) qfgl_ArrayElement (ui_indices[i]); break; default: break; } } static void qfgl_DrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices) { GLsizei i; const GLubyte *ub_indices; const GLushort *us_indices; const GLuint *ui_indices; switch (type) { case GL_UNSIGNED_BYTE: ub_indices = indices; for (i = 0; i < count; i++) if (ub_indices[i] >= start && ub_indices[i] <= end) qfgl_ArrayElement (ub_indices[i]); break; case GL_UNSIGNED_SHORT: us_indices = indices; for (i = 0; i < count; i++) if (us_indices[i] >= start && us_indices[i] <= end) qfgl_ArrayElement (us_indices[i]); break; case GL_UNSIGNED_INT: ui_indices = indices; for (i = 0; i < count; i++) if (ui_indices[i] >= start && ui_indices[i] <= end) qfgl_ArrayElement (ui_indices[i]); break; default: break; } } static void client_state (GLenum cap, GLboolean state) { switch (cap) { case GL_VERTEX_ARRAY: vertex_enabled = state; break; case GL_NORMAL_ARRAY: normal_enabled = state; break; case GL_COLOR_ARRAY: color_enabled = state; break; case GL_INDEX_ARRAY: index_enabled = state; break; case GL_TEXTURE_COORD_ARRAY: texcoord_enabled = state; break; case GL_EDGE_FLAG_ARRAY: edgeflag_enabled = state; break; } } static void qfgl_EnableClientState (GLenum cap) { client_state (cap, GL_TRUE); } static void qfgl_DisableClientState (GLenum cap) { client_state (cap, GL_FALSE); } static void qfgl_GetPointerv (GLenum pname, void **params) { Sys_Error ("GetPointerv not implemented"); } static void qfgl_PopClientAttrib (void) { Sys_Error ("PopClientAttrib not implemented"); } static void qfgl_PushClientAttrib (GLbitfield mask) { Sys_Error ("PushClientAttrib not implemented"); } struct { const char *name; void *func; } qfgl_functions [] = { {"glColorPointer", qfgl_ColorPointer}, {"glEdgeFlagPointer", qfgl_EdgeFlagPointer}, {"glIndexPointer", qfgl_IndexPointer}, {"glNormalPointer", qfgl_NormalPointer}, {"glTexCoordPointer", qfgl_TexCoordPointer}, {"glVertexPointer", qfgl_VertexPointer}, {"glInterleavedArrays", qfgl_InterleavedArrays}, {"glArrayElement", qfgl_ArrayElement}, {"glDrawArrays", qfgl_DrawArrays}, {"glDrawElements", qfgl_DrawElements}, {"glDrawRangeElements", qfgl_DrawRangeElements}, {"glEnableClientState", qfgl_EnableClientState}, {"glDisableClientState", qfgl_DisableClientState}, {"glGetPointerv", qfgl_GetPointerv}, {"glPopClientAttrib", qfgl_PopClientAttrib}, {"glPushClientAttrib", qfgl_PushClientAttrib}, };