summaryrefslogtreecommitdiff
path: root/libGL/client_gl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libGL/client_gl.c')
-rwxr-xr-xlibGL/client_gl.c6652
1 files changed, 6652 insertions, 0 deletions
diff --git a/libGL/client_gl.c b/libGL/client_gl.c
new file mode 100755
index 0000000..e73431b
--- /dev/null
+++ b/libGL/client_gl.c
@@ -0,0 +1,6652 @@
+/*
+ * Guest-side implementation of GL/GLX API. Replacement of standard libGL.so
+ *
+ * Copyright (c) 2006,2007 Even Rouault
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+
+#include "opengl_func.h"
+#include "common.h"
+#include "lock.h"
+#include "call.h"
+
+#include "client_stub.c"
+
+#include "glgetv_cst.h"
+
+#include "log.h"
+
+extern GLFunctionTable glFuncTable;
+GLAPI void APIENTRY glPushAttrib(GLbitfield mask)
+{
+ GET_CURRENT_STATE();
+ long args[] = { UNSIGNED_INT_TO_ARG(mask)};
+ if (state->server_sp < MAX_SERVER_STATE_STACK_SIZE)
+ {
+ state->server_stack[state->server_sp].mask = mask;
+ if (mask & GL_ENABLE_BIT)
+ {
+ state->server_stack[state->server_sp].linesmoothEnabled = state->current_server_state.linesmoothEnabled;
+ state->server_stack[state->server_sp].lightingEnabled = state->current_server_state.lightingEnabled;
+ state->server_stack[state->server_sp].texture2DEnabled = state->current_server_state.texture2DEnabled;
+ state->server_stack[state->server_sp].blendEnabled = state->current_server_state.blendEnabled;
+ }
+ if (mask & GL_TRANSFORM_BIT)
+ {
+ state->server_stack[state->server_sp].matrixMode = state->current_server_state.matrixMode;
+ }
+ if (mask & GL_DEPTH_BUFFER_BIT)
+ {
+ state->server_stack[state->server_sp].depthFunc = state->current_server_state.depthFunc;
+ }
+ if (mask & GL_TEXTURE_BIT)
+ {
+ state->server_stack[state->server_sp].bindTexture2D = state->current_server_state.bindTexture2D;
+ state->server_stack[state->server_sp].bindTextureRectangle = state->current_server_state.bindTextureRectangle;
+ }
+ if (mask & GL_FOG_BIT)
+ {
+ state->server_stack[state->server_sp].fog = state->current_server_state.fog;
+ }
+ state->server_sp++;
+ }
+ else
+ {
+ log_gl("server_sp > MAX_SERVER_STATE_STACK_SIZE\n");
+ }
+ do_opengl_call(glPushAttrib_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glPopAttrib()
+{
+ GET_CURRENT_STATE();
+ if (state->server_sp > 0)
+ {
+ state->server_sp--;
+ if (state->server_stack[state->server_sp].mask & GL_ENABLE_BIT)
+ {
+ state->current_server_state.linesmoothEnabled = state->server_stack[state->server_sp].linesmoothEnabled;
+ state->current_server_state.lightingEnabled = state->server_stack[state->server_sp].lightingEnabled;
+ state->current_server_state.texture2DEnabled = state->server_stack[state->server_sp].texture2DEnabled;
+ state->current_server_state.blendEnabled = state->server_stack[state->server_sp].blendEnabled;
+ }
+ if (state->server_stack[state->server_sp].mask & GL_TRANSFORM_BIT)
+ {
+ state->current_server_state.matrixMode = state->server_stack[state->server_sp].matrixMode;
+ }
+ if (state->server_stack[state->server_sp].mask & GL_DEPTH_BUFFER_BIT)
+ {
+ state->current_server_state.depthFunc = state->server_stack[state->server_sp].depthFunc;
+ }
+ if (state->server_stack[state->server_sp].mask & GL_TEXTURE_BIT)
+ {
+ state->current_server_state.bindTexture2D = state->server_stack[state->server_sp].bindTexture2D;
+ state->current_server_state.bindTextureRectangle = state->server_stack[state->server_sp].bindTextureRectangle;
+ }
+ if (state->server_stack[state->server_sp].mask & GL_FOG_BIT)
+ {
+ state->current_server_state.fog = state->server_stack[state->server_sp].fog;
+ }
+ }
+ else
+ {
+ log_gl("server_sp <= 0\n");
+ }
+ do_opengl_call(glPopAttrib_func, NULL, NULL, NULL);
+}
+
+GLAPI GLboolean APIENTRY glIsEnabled( GLenum cap )
+{
+ GLboolean ret = 0;
+ if (debug_gl) log_gl("glIsEnabled(0x%X)\n", cap);
+ GET_CURRENT_STATE();
+ if (!disable_optim)
+ {
+ if (cap == GL_LINE_SMOOTH)
+ {
+ return state->current_server_state.linesmoothEnabled;
+ }
+ else if (cap == GL_LIGHTING)
+ {
+ return state->current_server_state.lightingEnabled;
+ }
+ else if (cap == GL_TEXTURE_2D)
+ {
+ return state->current_server_state.texture2DEnabled;
+ }
+ else if (cap == GL_BLEND)
+ {
+ return state->current_server_state.blendEnabled;
+ }
+ else if (cap == GL_SCISSOR_TEST)
+ {
+ return state->current_server_state.scissorTestEnabled;
+ }
+ else if (cap == GL_VERTEX_PROGRAM_NV)
+ {
+ return state->current_server_state.vertexProgramEnabled;
+ }
+ else if (cap == GL_FOG)
+ {
+ return state->current_server_state.fogEnabled;
+ }
+ }
+ long args[] = { INT_TO_ARG(cap) };
+ do_opengl_call(glIsEnabled_func, &ret, args, NULL);
+ if (debug_gl) log_gl("glIsEnabled(0x%X) = %d\n", cap, ret);
+ return ret;
+}
+
+static ClientArray* _getArray(GLenum cap, int verbose)
+{
+ GET_CURRENT_STATE();
+ switch(cap)
+ {
+ case GL_VERTEX_ARRAY: return &state->client_state.arrays.vertexArray;
+ case GL_COLOR_ARRAY: return &state->client_state.arrays.colorArray;
+ case GL_SECONDARY_COLOR_ARRAY: return &state->client_state.arrays.secondaryColorArray;
+ case GL_NORMAL_ARRAY: return &state->client_state.arrays.normalArray;
+ case GL_INDEX_ARRAY: return &state->client_state.arrays.indexArray;
+ case GL_TEXTURE_COORD_ARRAY:
+ return &state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture];
+ case GL_EDGE_FLAG_ARRAY: return &state->client_state.arrays.edgeFlagArray;
+ case GL_WEIGHT_ARRAY_ARB: return &state->client_state.arrays.weightArray;
+ case GL_MATRIX_INDEX_ARRAY_POINTER_ARB: return &state->client_state.arrays.matrixIndexArray;
+ case GL_FOG_COORD_ARRAY: return &state->client_state.arrays.fogCoordArray;
+ case GL_ELEMENT_ARRAY_ATI: return &state->client_state.arrays.elementArrayATI;
+ default:
+ if (cap >= GL_VERTEX_ATTRIB_ARRAY0_NV && cap < GL_VERTEX_ATTRIB_ARRAY0_NV + MY_GL_MAX_VERTEX_ATTRIBS_NV)
+ return &state->client_state.arrays.vertexAttribArrayNV[cap - GL_VERTEX_ATTRIB_ARRAY0_NV];
+ if (verbose) log_gl("unhandled cap : %d\n", cap); return NULL;
+ }
+}
+
+GLAPI void APIENTRY glEnable(GLenum cap)
+{
+ GET_CURRENT_STATE();
+ /* Strange but some programs use glEnable(GL_VERTEX_ARRAY)
+ instead of glEnableClientState(GL_VERTEX_ARRAY) ...
+ I've discovered that while trying to make the spheres demo of chromium running
+ and mesa confirms it too */
+ if (_getArray(cap, 0))
+ {
+ glFuncTable.fpEnableClientState(cap);
+ return;
+ }
+
+ if (cap == GL_LINE_SMOOTH)
+ {
+ state->current_server_state.linesmoothEnabled = 1;
+ }
+ else if (cap == GL_LIGHTING)
+ {
+ state->current_server_state.lightingEnabled = 1;
+ }
+ else if (cap == GL_TEXTURE_2D)
+ {
+ state->current_server_state.texture2DEnabled = 1;
+ }
+ else if (cap == GL_BLEND)
+ {
+ state->current_server_state.blendEnabled = 1;
+ }
+ else if (cap == GL_SCISSOR_TEST)
+ {
+ state->current_server_state.scissorTestEnabled = 1;
+ }
+ else if (cap == GL_VERTEX_PROGRAM_NV)
+ {
+ state->current_server_state.vertexProgramEnabled = 1;
+ }
+ else if (cap == GL_FOG)
+ {
+ state->current_server_state.fogEnabled = 1;
+ }
+ long args[] = { INT_TO_ARG(cap)};
+ do_opengl_call(glEnable_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glDisable(GLenum cap)
+{
+ GET_CURRENT_STATE();
+ if (_getArray(cap, 0))
+ {
+ glFuncTable.fpDisableClientState(cap);
+ return;
+ }
+
+ if (cap == GL_LINE_SMOOTH)
+ {
+ state->current_server_state.linesmoothEnabled = 0;
+ }
+ else if (cap == GL_LIGHTING)
+ {
+ state->current_server_state.lightingEnabled = 0;
+ }
+ else if (cap == GL_TEXTURE_2D)
+ {
+ state->current_server_state.texture2DEnabled = 0;
+ }
+ else if (cap == GL_BLEND)
+ {
+ state->current_server_state.blendEnabled = 0;
+ }
+ else if (cap == GL_SCISSOR_TEST)
+ {
+ state->current_server_state.scissorTestEnabled = 0;
+ }
+ else if (cap == GL_VERTEX_PROGRAM_NV)
+ {
+ state->current_server_state.vertexProgramEnabled = 0;
+ }
+ else if (cap == GL_FOG)
+ {
+ state->current_server_state.fogEnabled = 0;
+ }
+ long args[] = { INT_TO_ARG(cap)};
+ do_opengl_call(glDisable_func, NULL, args, NULL);
+}
+
+#define GET_CAP_NAME(x) case x: return #x;
+static const char* _getArrayName(GLenum cap)
+{
+ switch (cap)
+ {
+ GET_CAP_NAME(GL_VERTEX_ARRAY);
+ GET_CAP_NAME(GL_COLOR_ARRAY);
+ GET_CAP_NAME(GL_SECONDARY_COLOR_ARRAY);
+ GET_CAP_NAME(GL_NORMAL_ARRAY);
+ GET_CAP_NAME(GL_INDEX_ARRAY);
+ GET_CAP_NAME(GL_TEXTURE_COORD_ARRAY);
+ GET_CAP_NAME(GL_EDGE_FLAG_ARRAY);
+ GET_CAP_NAME(GL_WEIGHT_ARRAY_ARB);
+ GET_CAP_NAME(GL_MATRIX_INDEX_ARRAY_ARB);
+ GET_CAP_NAME(GL_FOG_COORD_ARRAY);
+ GET_CAP_NAME(GL_ELEMENT_ARRAY_ATI);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY0_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY1_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY2_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY3_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY4_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY5_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY6_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY7_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY8_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY9_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY10_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY11_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY12_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY13_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY14_NV);
+ GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY15_NV);
+ }
+ return "unknown";
+}
+
+GLAPI void APIENTRY EXT_FUNC(glEnableVertexAttribArrayARB)(GLuint index)
+{
+ CHECK_PROC(glEnableVertexAttribArrayARB);
+ GET_CURRENT_STATE();
+ long args[] = { index };
+ do_opengl_call(glEnableVertexAttribArrayARB_func, NULL, args, NULL);
+
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ state->client_state.arrays.vertexAttribArray[index].enabled = 1;
+ }
+ else
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "glEnableVertexAttribArrayARB",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glEnableVertexAttribArray)(GLuint index)
+{
+ CHECK_PROC(glEnableVertexAttribArray);
+ GET_CURRENT_STATE();
+ long args[] = { index };
+ do_opengl_call(glEnableVertexAttribArray_func, NULL, args, NULL);
+
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ state->client_state.arrays.vertexAttribArray[index].enabled = 1;
+ }
+ else
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "glEnableVertexAttribArray",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glDisableVertexAttribArrayARB)(GLuint index)
+{
+ CHECK_PROC(glDisableVertexAttribArrayARB);
+ GET_CURRENT_STATE();
+ long args[] = { index };
+ do_opengl_call(glDisableVertexAttribArrayARB_func, NULL, args, NULL);
+
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ state->client_state.arrays.vertexAttribArray[index].enabled = 0;
+ }
+ else
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "1",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glDisableVertexAttribArray)(GLuint index)
+{
+ CHECK_PROC(glDisableVertexAttribArray);
+ GET_CURRENT_STATE();
+ long args[] = { index };
+ do_opengl_call(glDisableVertexAttribArray_func, NULL, args, NULL);
+
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ state->client_state.arrays.vertexAttribArray[index].enabled = 0;
+ }
+ else
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "2",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ }
+}
+
+GLAPI void APIENTRY glEnableClientState(GLenum cap)
+{
+ if (cap == GL_VERTEX_ARRAY_RANGE_NV ||
+ cap == GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) return; /* FIXME */
+ GET_CURRENT_STATE();
+ ClientArray* array = _getArray(cap, 1);
+ if (array == NULL) return;
+ if (debug_array_ptr)
+ {
+ if (cap == GL_TEXTURE_COORD_ARRAY)
+ log_gl("enable texture %d\n", state->client_state.clientActiveTexture);
+ else
+ log_gl("enable feature %s\n", _getArrayName(cap));
+ }
+ if ((!disable_optim) && array->enabled)
+ {
+ //log_gl("discard useless command\n");
+ return;
+ }
+ array->enabled = 1;
+ /*if ((!disable_optim) && cap == GL_TEXTURE_COORD_ARRAY)
+ {
+ long args[] = { UNSIGNED_INT_TO_ARG(state->client_state.clientActiveTexture + GL_TEXTURE0_ARB)};
+ do_opengl_call(glClientActiveTexture_func, NULL, args, NULL);
+ }*/
+ long args[] = { UNSIGNED_INT_TO_ARG(cap)};
+ do_opengl_call(glEnableClientState_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glDisableClientState(GLenum cap)
+{
+ if (cap == GL_VERTEX_ARRAY_RANGE_NV ||
+ cap == GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) return; /* FIXME */
+ GET_CURRENT_STATE();
+ ClientArray* array = _getArray(cap, 1);
+ if (array == NULL) return;
+ if (debug_array_ptr)
+ {
+ if (cap == GL_TEXTURE_COORD_ARRAY)
+ log_gl("disable texture %d\n", state->client_state.clientActiveTexture);
+ else
+ log_gl("disable feature %s\n", _getArrayName(cap));
+ }
+
+ if ((!disable_optim) && array->enabled == 0)
+ {
+ //log_gl("discard useless command\n");
+ return;
+ }
+ array->enabled = 0;
+ /*if ((!disable_optim) && cap == GL_TEXTURE_COORD_ARRAY)
+ {
+ long args[] = { UNSIGNED_INT_TO_ARG(state->client_state.clientActiveTexture + GL_TEXTURE0_ARB)};
+ do_opengl_call(glClientActiveTexture_func, NULL, args, NULL);
+ }*/
+ long args[] = { UNSIGNED_INT_TO_ARG(cap)};
+ do_opengl_call(glDisableClientState_func, NULL, args, NULL);
+}
+
+
+GLAPI void APIENTRY glClientActiveTexture(GLenum texture)
+{
+ GET_CURRENT_STATE();
+
+ if (disable_optim || state->client_state.clientActiveTexture != (int)texture - GL_TEXTURE0_ARB)
+ {
+ long args[] = { UNSIGNED_INT_TO_ARG(texture)};
+ do_opengl_call(glClientActiveTexture_func, NULL, args, NULL);
+ }
+
+ state->client_state.clientActiveTexture = (int)texture - GL_TEXTURE0_ARB;
+
+ assert(state->client_state.clientActiveTexture >= 0 &&
+ state->client_state.clientActiveTexture < NB_MAX_TEXTURES);
+}
+
+GLAPI void APIENTRY glClientActiveTextureARB(GLenum texture)
+{
+ glFuncTable.fpClientActiveTexture(texture);
+}
+
+GLAPI void APIENTRY glActiveTextureARB(GLenum texture)
+{
+ GET_CURRENT_STATE();
+ if (disable_optim || state->activeTexture != texture)
+ {
+ state->activeTexture = texture;
+
+ long args[] = { INT_TO_ARG(texture) };
+ do_opengl_call(glActiveTextureARB_func, NULL, args, NULL);
+ }
+}
+
+GLAPI void APIENTRY glPushClientAttrib(GLbitfield mask)
+{
+ GET_CURRENT_STATE();
+ long args[] = { UNSIGNED_INT_TO_ARG(mask)};
+ if (state->client_state_sp < MAX_CLIENT_STATE_STACK_SIZE)
+ {
+ state->client_state_stack[state->client_state_sp].mask = mask;
+ if (mask & GL_CLIENT_VERTEX_ARRAY_BIT)
+ {
+ state->client_state_stack[state->client_state_sp].arrays = state->client_state.arrays;
+ }
+ if (mask & GL_CLIENT_PIXEL_STORE_BIT)
+ {
+ state->client_state_stack[state->client_state_sp].pack = state->client_state.pack;
+ state->client_state_stack[state->client_state_sp].unpack = state->client_state.unpack;
+ }
+ state->client_state_sp++;
+ }
+ else
+ {
+ log_gl("state->client_state_sp > MAX_CLIENT_STATE_STACK_SIZE\n");
+ }
+ do_opengl_call(glPushClientAttrib_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glPopClientAttrib()
+{
+ GET_CURRENT_STATE();
+ if (state->client_state_sp > 0)
+ {
+ state->client_state_sp--;
+ if (state->client_state_stack[state->client_state_sp].mask & GL_CLIENT_VERTEX_ARRAY_BIT)
+ {
+ state->client_state.arrays = state->client_state_stack[state->client_state_sp].arrays;
+ }
+ if (state->client_state_stack[state->client_state_sp].mask & GL_CLIENT_PIXEL_STORE_BIT)
+ {
+ state->client_state.pack = state->client_state_stack[state->client_state_sp].pack;
+ state->client_state.unpack = state->client_state_stack[state->client_state_sp].unpack;
+ }
+ }
+ else
+ {
+ log_gl("state->client_state_sp <= 0\n");
+ }
+ do_opengl_call(glPopClientAttrib_func, NULL, NULL, NULL);
+}
+
+static void _glPixelStore(GLenum pname, GLint param)
+{
+ GET_CURRENT_STATE();
+ switch (pname)
+ {
+ case GL_PACK_SWAP_BYTES: state->client_state.pack.swapEndian = param != 0; break;
+ case GL_PACK_LSB_FIRST: state->client_state.pack.lsbFirst = param != 0; break;
+ case GL_PACK_ROW_LENGTH: if (param >= 0) state->client_state.pack.rowLength = param; break;
+ case GL_PACK_IMAGE_HEIGHT: if (param >= 0) state->client_state.pack.imageHeight = param; break;
+ case GL_PACK_SKIP_ROWS: if (param >= 0) state->client_state.pack.skipRows = param; break;
+ case GL_PACK_SKIP_PIXELS: if (param >= 0) state->client_state.pack.skipPixels = param; break;
+ case GL_PACK_SKIP_IMAGES: if (param >= 0) state->client_state.pack.skipImages = param; break;
+ case GL_PACK_ALIGNMENT: if (param == 1 || param == 2 || param == 4 || param == 8)
+ state->client_state.pack.alignment = param; break;
+ case GL_UNPACK_SWAP_BYTES: state->client_state.unpack.swapEndian = param != 0; break;
+ case GL_UNPACK_LSB_FIRST: state->client_state.unpack.lsbFirst = param != 0; break;
+ case GL_UNPACK_ROW_LENGTH: if (param >= 0) state->client_state.unpack.rowLength = param; break;
+ case GL_UNPACK_IMAGE_HEIGHT: if (param >= 0) state->client_state.unpack.imageHeight = param; break;
+ case GL_UNPACK_SKIP_ROWS: if (param >= 0) state->client_state.unpack.skipRows = param; break;
+ case GL_UNPACK_SKIP_PIXELS: if (param >= 0) state->client_state.unpack.skipPixels = param; break;
+ case GL_UNPACK_SKIP_IMAGES: if (param >= 0) state->client_state.unpack.skipImages = param; break;
+ case GL_UNPACK_ALIGNMENT: if (param == 1 || param == 2 || param == 4 || param == 8)
+ state->client_state.unpack.alignment = param; break;
+ default: log_gl("unhandled pname %d\n", pname); break;
+ }
+}
+
+GLAPI void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
+{
+ long args[] = { UNSIGNED_INT_TO_ARG(pname), FLOAT_TO_ARG(param)};
+ if (!(pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_IMAGES ||
+ pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_IMAGES))
+ {
+ _glPixelStore(pname, (GLint)(param + 0.5));
+ do_opengl_call(glPixelStoref_func, NULL, args, NULL);
+ }
+}
+
+void glPixelStorei_no_lock(GLenum pname, GLint param)
+{
+ _glPixelStore(pname, param);
+ if (!(pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_ROWS || pname == GL_PACK_SKIP_IMAGES ||
+ pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_ROWS || pname == GL_UNPACK_SKIP_IMAGES))
+ {
+ long args[] = { UNSIGNED_INT_TO_ARG(pname), INT_TO_ARG(param)};
+ do_opengl_call_no_lock(glPixelStorei_func, NULL, args, NULL);
+ }
+}
+
+GLAPI void APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+ LOCK(glPixelStorei_func);
+ glPixelStorei_no_lock(pname, param);
+ UNLOCK(glPixelStorei_func);
+}
+
+static int get_nb_composants_of_gl_get_constant_compare(const void* a, const void* b)
+{
+ GlGetConstant* constantA = (GlGetConstant*)a;
+ GlGetConstant* constantB = (GlGetConstant*)b;
+ return constantA->token - constantB->token;
+}
+
+static int get_size_get_boolean_integer_float_double_v(int func_number, int pname)
+{
+ GlGetConstant constant;
+ GlGetConstant* found;
+ constant.token = pname;
+ found = bsearch(&constant, gl_get_constants,
+ sizeof(gl_get_constants) / sizeof(GlGetConstant), sizeof(GlGetConstant),
+ get_nb_composants_of_gl_get_constant_compare);
+ if (found)
+ return found->count;
+ else
+ {
+ log_gl("unknown name for %s : %d\n", tab_opengl_calls_name[func_number], pname);
+ log_gl("hoping that size is 1...\n");
+ return 1;
+ }
+}
+
+#define AFFECT_N(x, y, N) do { int _i; for(_i=0;_i<N;_i++) x[_i]=y[_i]; } while(0)
+
+#define IS_VALID_MATRIX_MODE(mode) \
+ ((mode >= GL_MODELVIEW && mode <= GL_TEXTURE) || \
+ (mode == GL_MATRIX_PALETTE_ARB) || \
+ (mode == GL_MODELVIEW1_ARB) || \
+ (mode >= GL_MODELVIEW2_ARB && mode <= GL_MODELVIEW31_ARB))
+
+#define MATRIX_MODE_TO_MATRIX_INDEX(mode) \
+ ((mode == GL_MODELVIEW) ? 0 : \
+ (mode == GL_PROJECTION) ? 1 : \
+ (mode == GL_TEXTURE) ? 2 + state->activeTexture - GL_TEXTURE0_ARB: \
+ (mode == GL_MATRIX_PALETTE_ARB) ? 2 + NB_MAX_TEXTURES : \
+ (mode == GL_MODELVIEW1_ARB) ? 3 + NB_MAX_TEXTURES : \
+ (mode >= GL_MODELVIEW2_ARB && mode <= GL_MODELVIEW31_ARB) ? 4 + NB_MAX_TEXTURES + mode - GL_MODELVIEW2_ARB : -1)
+
+static int maxTextureSize = -1; /* optimization for ppracer */
+static int maxTextureUnits = -1;
+
+static int _glGetIntegerv(GLenum pname)
+{
+ int ret;
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(&ret) };
+ int args_size[] = { 0, sizeof(int) };
+ do_opengl_call_no_lock(glGetIntegerv_func, NULL, CHECK_ARGS(args, args_size));
+ return ret;
+}
+
+void glGetIntegerv_no_lock( GLenum pname, GLint *params );
+
+#define glGetf(funcName, funcNumber, cType, typeBase) \
+void CONCAT(funcName,_no_lock)( GLenum pname, cType *params ) \
+{ \
+ GET_CURRENT_STATE(); \
+ switch (pname) \
+ { \
+ case GL_VERTEX_ARRAY: *params = state->client_state.arrays.vertexArray.enabled; break; \
+ case GL_NORMAL_ARRAY: *params = state->client_state.arrays.normalArray.enabled; break; \
+ case GL_COLOR_ARRAY: *params = state->client_state.arrays.colorArray.enabled; break; \
+ case GL_INDEX_ARRAY: *params = state->client_state.arrays.indexArray.enabled; break; \
+ case GL_TEXTURE_COORD_ARRAY: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].enabled; break; \
+ case GL_EDGE_FLAG_ARRAY: *params = state->client_state.arrays.edgeFlagArray.enabled; break; \
+ case GL_SECONDARY_COLOR_ARRAY: *params = state->client_state.arrays.secondaryColorArray.enabled; break; \
+ case GL_FOG_COORDINATE_ARRAY: *params = state->client_state.arrays.fogCoordArray.enabled; break; \
+ case GL_WEIGHT_ARRAY_ARB: *params = state->client_state.arrays.weightArray.enabled; break; \
+ case GL_VERTEX_ARRAY_SIZE: *params = state->client_state.arrays.vertexArray.size; break; \
+ case GL_VERTEX_ARRAY_TYPE: *params = state->client_state.arrays.vertexArray.type; break; \
+ case GL_VERTEX_ARRAY_STRIDE: *params = state->client_state.arrays.vertexArray.stride; break; \
+ case GL_NORMAL_ARRAY_TYPE: *params = state->client_state.arrays.normalArray.type; break; \
+ case GL_NORMAL_ARRAY_STRIDE: *params = state->client_state.arrays.normalArray.stride; break; \
+ case GL_COLOR_ARRAY_SIZE: *params = state->client_state.arrays.colorArray.size; break; \
+ case GL_COLOR_ARRAY_TYPE: *params = state->client_state.arrays.colorArray.type; break; \
+ case GL_COLOR_ARRAY_STRIDE: *params = state->client_state.arrays.colorArray.stride; break; \
+ case GL_INDEX_ARRAY_TYPE: *params = state->client_state.arrays.indexArray.type; break; \
+ case GL_INDEX_ARRAY_STRIDE: *params = state->client_state.arrays.indexArray.stride; break; \
+ case GL_TEXTURE_COORD_ARRAY_SIZE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size; break; \
+ case GL_TEXTURE_COORD_ARRAY_TYPE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type; break; \
+ case GL_TEXTURE_COORD_ARRAY_STRIDE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride; break; \
+ case GL_EDGE_FLAG_ARRAY_STRIDE: *params = state->client_state.arrays.edgeFlagArray.stride; break; \
+ case GL_SECONDARY_COLOR_ARRAY_SIZE: *params = state->client_state.arrays.secondaryColorArray.size; break; \
+ case GL_SECONDARY_COLOR_ARRAY_TYPE: *params = state->client_state.arrays.secondaryColorArray.type; break; \
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE: *params = state->client_state.arrays.secondaryColorArray.stride; break; \
+ case GL_FOG_COORDINATE_ARRAY_TYPE: *params = state->client_state.arrays.fogCoordArray.type; break; \
+ case GL_FOG_COORDINATE_ARRAY_POINTER: *params = state->client_state.arrays.fogCoordArray.stride; break; \
+ case GL_WEIGHT_ARRAY_SIZE_ARB: *params = state->client_state.arrays.weightArray.size; break; \
+ case GL_WEIGHT_ARRAY_TYPE_ARB: *params = state->client_state.arrays.weightArray.type; break; \
+ case GL_WEIGHT_ARRAY_STRIDE_ARB: *params = state->client_state.arrays.weightArray.stride; break; \
+ case GL_MATRIX_INDEX_ARRAY_SIZE_ARB: *params = state->client_state.arrays.matrixIndexArray.size; break; \
+ case GL_MATRIX_INDEX_ARRAY_TYPE_ARB: *params = state->client_state.arrays.matrixIndexArray.type; break; \
+ case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB: *params = state->client_state.arrays.matrixIndexArray.stride; break; \
+ case GL_VERTEX_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.vertexArray.vbo_name; break; \
+ case GL_NORMAL_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.normalArray.vbo_name; break; \
+ case GL_COLOR_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.colorArray.vbo_name; break; \
+ case GL_INDEX_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.indexArray.vbo_name; break; \
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name; break; \
+ case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.edgeFlagArray.vbo_name; break; \
+ case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.secondaryColorArray.vbo_name; break; \
+ case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.fogCoordArray.vbo_name; break; \
+ case GL_WEIGHT_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.weightArray.vbo_name; break; \
+ case GL_PACK_SWAP_BYTES: *params = state->client_state.pack.swapEndian; break; \
+ case GL_PACK_LSB_FIRST: *params = state->client_state.pack.lsbFirst; break; \
+ case GL_PACK_ROW_LENGTH: *params = state->client_state.pack.rowLength; break; \
+ case GL_PACK_IMAGE_HEIGHT: *params = state->client_state.pack.imageHeight; break; \
+ case GL_PACK_SKIP_ROWS: *params = state->client_state.pack.skipRows; break; \
+ case GL_PACK_SKIP_PIXELS: *params = state->client_state.pack.skipPixels; break; \
+ case GL_PACK_SKIP_IMAGES: *params = state->client_state.pack.skipImages; break; \
+ case GL_PACK_ALIGNMENT: *params = state->client_state.pack.alignment; break; \
+ case GL_UNPACK_SWAP_BYTES: *params = state->client_state.unpack.swapEndian; break; \
+ case GL_UNPACK_LSB_FIRST: *params = state->client_state.unpack.lsbFirst; break; \
+ case GL_UNPACK_ROW_LENGTH: *params = state->client_state.unpack.rowLength; break; \
+ case GL_UNPACK_IMAGE_HEIGHT: *params = state->client_state.unpack.imageHeight; break; \
+ case GL_UNPACK_SKIP_ROWS: *params = state->client_state.unpack.skipRows; break; \
+ case GL_UNPACK_SKIP_PIXELS: *params = state->client_state.unpack.skipPixels; break; \
+ case GL_UNPACK_SKIP_IMAGES: *params = state->client_state.unpack.skipImages; break; \
+ case GL_UNPACK_ALIGNMENT: *params = state->client_state.unpack.alignment; break; \
+ case GL_TEXTURE_2D_BINDING_EXT: *params = state->current_server_state.bindTexture2D; break; \
+ case GL_TEXTURE_BINDING_RECTANGLE_ARB: *params = state->current_server_state.bindTextureRectangle; break; \
+ case GL_VIEWPORT: params[0] = state->viewport.x; params[1] = state->viewport.y; params[2] = state->viewport.width; params[3] = state->viewport.height; break; \
+ case GL_SCISSOR_BOX: params[0] = state->scissorbox.x; params[1] = state->scissorbox.y; params[2] = state->scissorbox.width; params[3] = state->scissorbox.height; break; \
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: *params = 16; break;\
+ case GL_MATRIX_MODE: *params = state->current_server_state.matrixMode; break; \
+ case GL_DEPTH_FUNC: *params = state->current_server_state.depthFunc; break; \
+ case GL_FOG_MODE: *params = state->current_server_state.fog.mode; break; \
+ case GL_FOG_DENSITY: *params = state->current_server_state.fog.density; break; \
+ case GL_FOG_START: *params = state->current_server_state.fog.start; break; \
+ case GL_FOG_END: *params = state->current_server_state.fog.end; break; \
+ case GL_FOG_INDEX: *params = state->current_server_state.fog.index; break; \
+ case GL_FOG_COLOR: AFFECT_N(params, state->current_server_state.fog.color, 4); break; \
+ case GL_COMPRESSED_TEXTURE_FORMATS_ARB: \
+ { \
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; \
+ int args_size[] = { 0, 0 }; \
+ int nb_compressed_texture_formats = 0; \
+ glGetIntegerv_no_lock(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &nb_compressed_texture_formats); \
+ args_size[1] = tab_args_type_length[typeBase] * nb_compressed_texture_formats; \
+ do_opengl_call_no_lock(funcNumber, NULL, CHECK_ARGS(args, args_size)); \
+ break; \
+ } \
+ case GL_ARRAY_BUFFER_BINDING: *params = state->arrayBuffer; break; \
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: *params = state->elementArrayBuffer; break; \
+ case GL_MAX_TEXTURE_SIZE: if (maxTextureSize == -1) maxTextureSize = _glGetIntegerv(pname); *params = maxTextureSize; break; \
+ case GL_MAX_TEXTURE_UNITS_ARB: if (maxTextureUnits == -1) maxTextureUnits = _glGetIntegerv(pname); *params = maxTextureUnits; break; \
+ case GL_MODELVIEW_MATRIX: \
+ case GL_PROJECTION_MATRIX: \
+ case GL_TEXTURE_MATRIX: AFFECT_N(params, state->matrix[pname - GL_MODELVIEW_MATRIX].current.val, 16); break; \
+ case GL_CURRENT_RASTER_POSITION: \
+ { \
+ if (!state->currentRasterPosKnown) \
+ { \
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(state->currentRasterPos) }; \
+ int args_size[] = { 0, 4 * sizeof(float) }; \
+ if(debug_gl) log_gl("getting value 0x%X\n", pname); \
+ do_opengl_call_no_lock(glGetFloatv_func, NULL, CHECK_ARGS(args, args_size)); \
+ state->currentRasterPosKnown = 1; \
+ } \
+ AFFECT_N(params, state->currentRasterPos, 4); \
+ break; \
+ } \
+ default: \
+ { \
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; \
+ int args_size[] = { 0, 0 }; \
+ args_size[1] = tab_args_type_length[typeBase] * get_size_get_boolean_integer_float_double_v(funcNumber, pname); \
+ if(debug_gl) log_gl("getting value 0x%X\n", pname); \
+ do_opengl_call_no_lock(funcNumber, NULL, CHECK_ARGS(args, args_size)); \
+ if (debug_gl && typeBase == TYPE_INT) log_gl("val=%d\n", (int)*params); \
+ else if (debug_gl && typeBase == TYPE_FLOAT) log_gl("val=%f\n", (float)*params); \
+ } \
+ } \
+} \
+GLAPI void APIENTRY funcName( GLenum pname, cType *params ) \
+{ \
+ LOCK(funcNumber); \
+ CONCAT(funcName,_no_lock)(pname, params); \
+ UNLOCK(funcNumber); \
+}
+
+glGetf(glGetBooleanv, glGetBooleanv_func, GLboolean, TYPE_CHAR);
+glGetf(glGetIntegerv, glGetIntegerv_func, GLint, TYPE_INT);
+glGetf(glGetFloatv, glGetFloatv_func, GLfloat, TYPE_FLOAT);
+glGetf(glGetDoublev, glGetDoublev_func, GLdouble, TYPE_DOUBLE);
+
+GLAPI void APIENTRY glDepthFunc(GLenum func)
+{
+ long args[] = { UNSIGNED_INT_TO_ARG(func)};
+ GET_CURRENT_STATE();
+ state->current_server_state.depthFunc = func;
+ do_opengl_call(glDepthFunc_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glClipPlane(GLenum plane, const GLdouble * equation)
+{
+ GET_CURRENT_STATE();
+ if (plane >= GL_CLIP_PLANE0 && plane < GL_CLIP_PLANE0 + N_CLIP_PLANES)
+ memcpy(state->current_server_state.clipPlanes[plane-GL_CLIP_PLANE0], equation, 4 * sizeof(double));
+ long args[] = { UNSIGNED_INT_TO_ARG(plane), POINTER_TO_ARG(equation)};
+ do_opengl_call(glClipPlane_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glGetClipPlane(GLenum plane, GLdouble * equation)
+{
+ GET_CURRENT_STATE();
+ if (plane >= GL_CLIP_PLANE0 && plane < GL_CLIP_PLANE0 + N_CLIP_PLANES)
+ {
+ memcpy(equation, state->current_server_state.clipPlanes[plane-GL_CLIP_PLANE0], 4 * sizeof(double));
+ return;
+ }
+ long args[] = { UNSIGNED_INT_TO_ARG(plane), POINTER_TO_ARG(equation)};
+ do_opengl_call(glGetClipPlane_func, NULL, args, NULL);
+}
+
+
+GLAPI void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_STATE();
+ long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height)};
+
+ /*
+ * Update the render buffer if the current window size is different from the one in state.
+ */
+ _check_and_resize_window (state, state->current_drawable);
+
+ glFuncTable.fpEnable(GL_DEPTH_TEST);
+ glClearDepth (1.0);
+ glFuncTable.fpClear(GL_DEPTH_BUFFER_BIT);
+
+ state->viewport.x = x;
+ state->viewport.y = y;
+ state->viewport.width = width;
+ state->viewport.height = height;
+ if (debug_gl) log_gl("viewport %d,%d,%d,%d\n", x, y, width, height);
+ do_opengl_call(glViewport_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_STATE();
+ long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height)};
+ state->scissorbox.x = x;
+ state->scissorbox.y = y;
+ state->scissorbox.width = width;
+ state->scissorbox.height = height;
+ do_opengl_call(glScissor_func, NULL, args, NULL);
+}
+
+
+/* Matrix optimization : openquartz */
+#if 1
+GLAPI void APIENTRY glMatrixMode(GLenum mode)
+{
+ GET_CURRENT_STATE();
+ long args[] = { UNSIGNED_INT_TO_ARG(mode)};
+ if (IS_VALID_MATRIX_MODE(mode))
+ state->current_server_state.matrixMode = mode;
+ do_opengl_call(glMatrixMode_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glPushMatrix()
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ if (state->matrix[index_mode].sp < MAX_MATRIX_STACK_SIZE)
+ {
+ memcpy(state->matrix[index_mode].stack[state->matrix[index_mode].sp].val,
+ state->matrix[index_mode].current.val,
+ 16 * sizeof(double));
+ state->matrix[index_mode].sp++;
+ }
+ else
+ {
+ log_gl("matrix[mode].sp >= MAX_MATRIX_STACK_SIZE\n");
+ }
+ }
+
+ do_opengl_call(glPushMatrix_func, NULL, NULL, NULL);
+}
+
+GLAPI void APIENTRY glPopMatrix()
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ if (state->matrix[index_mode].sp > 0)
+ {
+ state->matrix[index_mode].sp--;
+ memcpy(state->matrix[index_mode].current.val,
+ state->matrix[index_mode].stack[state->matrix[index_mode].sp].val,
+ 16 * sizeof(double));
+ }
+ else
+ {
+ log_gl("matrix[mode].sp <= 0\n");
+ }
+ }
+
+ do_opengl_call(glPopMatrix_func, NULL, NULL, NULL);
+}
+
+GLAPI void APIENTRY glLoadIdentity()
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ int j;
+ if (index_mode >= 0)
+ {
+ for(j=0;j<16;j++)
+ {
+ state->matrix[index_mode].current.val[j] = (j == 0 || j == 5 || j == 10 || j == 15);
+ }
+ }
+ do_opengl_call(glLoadIdentity_func, NULL, NULL, NULL);
+}
+
+static void _internal_glLoadMatrixd(const GLdouble matrix[16])
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ memcpy(state->matrix[index_mode].current.val, matrix, 16 * sizeof(double));
+}
+
+static void _internal_glLoadMatrixf(const GLfloat matrix[16])
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ int i;
+ for(i=0;i<16;i++)
+ state->matrix[index_mode].current.val[i] = matrix[i];
+ }
+}
+
+GLAPI void APIENTRY glLoadMatrixd(const GLdouble matrix[16])
+{
+ _internal_glLoadMatrixd(matrix);
+ long args[] = { POINTER_TO_ARG(matrix)};
+ do_opengl_call(glLoadMatrixd_func, NULL, args, NULL);
+}
+
+static void matrixfToMatrixd(const GLfloat matrixf[16], GLdouble matrix[16])
+{
+ int i;
+ for(i=0;i<16;i++)
+ {
+ matrix[i] = matrixf[i];
+ }
+}
+
+GLAPI void APIENTRY glLoadMatrixf(const GLfloat matrix[16])
+{
+ _internal_glLoadMatrixf(matrix);
+
+ long args[] = { POINTER_TO_ARG(matrix)};
+ do_opengl_call(glLoadMatrixf_func, NULL, args, NULL);
+}
+
+static void _internal_glMultMatrixd(const GLdouble matrix[16])
+{
+ GET_CURRENT_STATE();
+ GLdouble destMatrix[16];
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* oriMatrix = state->matrix[index_mode].current.val;
+
+ /* t(C)=t(A.B)=t(B).t(A) */
+
+ destMatrix[0*4+0] = matrix[0*4+0] * oriMatrix[0*4+0] +
+ matrix[0*4+1] * oriMatrix[1*4+0] +
+ matrix[0*4+2] * oriMatrix[2*4+0] +
+ matrix[0*4+3] * oriMatrix[3*4+0];
+ destMatrix[0*4+1] = matrix[0*4+0] * oriMatrix[0*4+1] +
+ matrix[0*4+1] * oriMatrix[1*4+1] +
+ matrix[0*4+2] * oriMatrix[2*4+1] +
+ matrix[0*4+3] * oriMatrix[3*4+1];
+ destMatrix[0*4+2] = matrix[0*4+0] * oriMatrix[0*4+2] +
+ matrix[0*4+1] * oriMatrix[1*4+2] +
+ matrix[0*4+2] * oriMatrix[2*4+2] +
+ matrix[0*4+3] * oriMatrix[3*4+2];
+ destMatrix[0*4+3] = matrix[0*4+0] * oriMatrix[0*4+3] +
+ matrix[0*4+1] * oriMatrix[1*4+3] +
+ matrix[0*4+2] * oriMatrix[2*4+3] +
+ matrix[0*4+3] * oriMatrix[3*4+3];
+
+ destMatrix[1*4+0] = matrix[1*4+0] * oriMatrix[0*4+0] +
+ matrix[1*4+1] * oriMatrix[1*4+0] +
+ matrix[1*4+2] * oriMatrix[2*4+0] +
+ matrix[1*4+3] * oriMatrix[3*4+0];
+ destMatrix[1*4+1] = matrix[1*4+0] * oriMatrix[0*4+1] +
+ matrix[1*4+1] * oriMatrix[1*4+1] +
+ matrix[1*4+2] * oriMatrix[2*4+1] +
+ matrix[1*4+3] * oriMatrix[3*4+1];
+ destMatrix[1*4+2] = matrix[1*4+0] * oriMatrix[0*4+2] +
+ matrix[1*4+1] * oriMatrix[1*4+2] +
+ matrix[1*4+2] * oriMatrix[2*4+2] +
+ matrix[1*4+3] * oriMatrix[3*4+2];
+ destMatrix[1*4+3] = matrix[1*4+0] * oriMatrix[0*4+3] +
+ matrix[1*4+1] * oriMatrix[1*4+3] +
+ matrix[1*4+2] * oriMatrix[2*4+3] +
+ matrix[1*4+3] * oriMatrix[3*4+3];
+
+ destMatrix[2*4+0] = matrix[2*4+0] * oriMatrix[0*4+0] +
+ matrix[2*4+1] * oriMatrix[1*4+0] +
+ matrix[2*4+2] * oriMatrix[2*4+0] +
+ matrix[2*4+3] * oriMatrix[3*4+0];
+ destMatrix[2*4+1] = matrix[2*4+0] * oriMatrix[0*4+1] +
+ matrix[2*4+1] * oriMatrix[1*4+1] +
+ matrix[2*4+2] * oriMatrix[2*4+1] +
+ matrix[2*4+3] * oriMatrix[3*4+1];
+ destMatrix[2*4+2] = matrix[2*4+0] * oriMatrix[0*4+2] +
+ matrix[2*4+1] * oriMatrix[1*4+2] +
+ matrix[2*4+2] * oriMatrix[2*4+2] +
+ matrix[2*4+3] * oriMatrix[3*4+2];
+ destMatrix[2*4+3] = matrix[2*4+0] * oriMatrix[0*4+3] +
+ matrix[2*4+1] * oriMatrix[1*4+3] +
+ matrix[2*4+2] * oriMatrix[2*4+3] +
+ matrix[2*4+3] * oriMatrix[3*4+3];
+
+ destMatrix[3*4+0] = matrix[3*4+0] * oriMatrix[0*4+0] +
+ matrix[3*4+1] * oriMatrix[1*4+0] +
+ matrix[3*4+2] * oriMatrix[2*4+0] +
+ matrix[3*4+3] * oriMatrix[3*4+0];
+ destMatrix[3*4+1] = matrix[3*4+0] * oriMatrix[0*4+1] +
+ matrix[3*4+1] * oriMatrix[1*4+1] +
+ matrix[3*4+2] * oriMatrix[2*4+1] +
+ matrix[3*4+3] * oriMatrix[3*4+1];
+ destMatrix[3*4+2] = matrix[3*4+0] * oriMatrix[0*4+2] +
+ matrix[3*4+1] * oriMatrix[1*4+2] +
+ matrix[3*4+2] * oriMatrix[2*4+2] +
+ matrix[3*4+3] * oriMatrix[3*4+2];
+ destMatrix[3*4+3] = matrix[3*4+0] * oriMatrix[0*4+3] +
+ matrix[3*4+1] * oriMatrix[1*4+3] +
+ matrix[3*4+2] * oriMatrix[2*4+3] +
+ matrix[3*4+3] * oriMatrix[3*4+3];
+
+ memcpy(oriMatrix, destMatrix, 16 * sizeof(double));
+ }
+}
+
+GLAPI void APIENTRY glMultMatrixd(const GLdouble matrix[16])
+{
+ _internal_glMultMatrixd(matrix);
+
+ long args[] = { POINTER_TO_ARG(matrix)};
+ do_opengl_call(glMultMatrixd_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glMultMatrixf(const GLfloat matrix[16])
+{
+ GLdouble matrixd[16];
+ matrixfToMatrixd(matrix, matrixd);
+ _internal_glMultMatrixd(matrixd);
+
+ long args[] = { POINTER_TO_ARG(matrix)};
+ do_opengl_call(glMultMatrixf_func, NULL, args, NULL);
+}
+
+/**
+ * Transpose a GLfloat matrix.
+ *
+ * \param to destination array.
+ * \param from source array.
+ */
+static void
+_math_transposef( GLfloat to[16], const GLfloat from[16] )
+{
+ to[0] = from[0];
+ to[1] = from[4];
+ to[2] = from[8];
+ to[3] = from[12];
+ to[4] = from[1];
+ to[5] = from[5];
+ to[6] = from[9];
+ to[7] = from[13];
+ to[8] = from[2];
+ to[9] = from[6];
+ to[10] = from[10];
+ to[11] = from[14];
+ to[12] = from[3];
+ to[13] = from[7];
+ to[14] = from[11];
+ to[15] = from[15];
+}
+
+
+/**
+ * Transpose a GLdouble matrix.
+ *
+ * \param to destination array.
+ * \param from source array.
+ */
+static void
+_math_transposed( GLdouble to[16], const GLdouble from[16] )
+{
+ to[0] = from[0];
+ to[1] = from[4];
+ to[2] = from[8];
+ to[3] = from[12];
+ to[4] = from[1];
+ to[5] = from[5];
+ to[6] = from[9];
+ to[7] = from[13];
+ to[8] = from[2];
+ to[9] = from[6];
+ to[10] = from[10];
+ to[11] = from[14];
+ to[12] = from[3];
+ to[13] = from[7];
+ to[14] = from[11];
+ to[15] = from[15];
+}
+
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat m[16])
+{
+ GLfloat dest[16];
+ _math_transposef(dest, m);
+ glFuncTable.fpLoadMatrixf(dest);
+}
+
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble m[16])
+{
+ GLdouble dest[16];
+ _math_transposed(dest, m);
+ glLoadMatrixd(dest);
+}
+
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat m[16])
+{
+ GLfloat dest[16];
+ _math_transposef(dest, m);
+ glFuncTable.fpMultMatrixf(dest);
+}
+
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble m[16])
+{
+ GLdouble dest[16];
+ _math_transposed(dest, m);
+ glMultMatrixd(dest);
+}
+
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat* m)
+{
+ GLfloat dest[16];
+ _math_transposef(dest, m);
+ glFuncTable.fpLoadMatrixf(dest);
+}
+
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble* m)
+{
+ GLdouble dest[16];
+ _math_transposed(dest, m);
+ glLoadMatrixd(dest);
+}
+
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat* m)
+{
+ GLfloat dest[16];
+ _math_transposef(dest, m);
+ glFuncTable.fpMultMatrixf(dest);
+}
+
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble* m)
+{
+ GLdouble dest[16];
+ _math_transposed(dest, m);
+ glMultMatrixd(dest);
+}
+
+GLAPI void APIENTRY glOrtho( GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble near_val,
+ GLdouble far_val)
+{
+ double tx, ty, tz;
+ tx = -(right + left) / (right - left);
+ ty = -(top + bottom) / (top - bottom);
+ tz = -(far_val + near_val) / (far_val - near_val);
+ double matrix[16] = { 2/(right - left), 0, 0, 0,
+ 0, 2/(top-bottom), 0, 0,
+ 0, 0, -2/(far_val - near_val), 0,
+ tx, ty, tz, 1 };
+ _internal_glMultMatrixd(matrix);
+
+ long args[] = { DOUBLE_TO_ARG(left), DOUBLE_TO_ARG(right), DOUBLE_TO_ARG(bottom), DOUBLE_TO_ARG(top), DOUBLE_TO_ARG(near_val), DOUBLE_TO_ARG(far_val)};
+ do_opengl_call(glOrtho_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glFrustum( GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble near_val,
+ GLdouble far_val)
+{
+ double V1, V2, A, B, C, D;
+ V1 = 2 * near_val / (right - left);
+ V2 = 2 * near_val / (top - bottom);
+ A = (right + left) / (right - left);
+ B = (top + bottom) / (top - bottom);
+ C = -(far_val + near_val) / (far_val - near_val);
+ D = -2 * far_val * near_val / (far_val - near_val);
+ double matrix[16] = { V1, 0, 0, 0,
+ 0, V2, 0, 0,
+ A, B, C, -1,
+ 0, 0, D, 0};
+ _internal_glMultMatrixd(matrix);
+
+ long args[] = { DOUBLE_TO_ARG(left), DOUBLE_TO_ARG(right), DOUBLE_TO_ARG(bottom), DOUBLE_TO_ARG(top), DOUBLE_TO_ARG(near_val), DOUBLE_TO_ARG(far_val)};
+ do_opengl_call(glFrustum_func, NULL, args, NULL);
+
+}
+
+static void _glRotate_internal(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ double c = cos(angle / 180. * M_PI);
+ double s = sin(angle / 180. * M_PI);
+ if (x == 1 && y == 0 && z == 0)
+ {
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* matrix = state->matrix[index_mode].current.val;
+ double t, u;
+
+ t = matrix[1*4+0];
+ u = matrix[2*4+0];
+ matrix[1*4+0] = c * t + s * u;
+ matrix[2*4+0] = c * u - s * t;
+
+ t = matrix[1*4+1];
+ u = matrix[2*4+1];
+ matrix[1*4+1] = c * t + s * u;
+ matrix[2*4+1] = c * u - s * t;
+
+ t = matrix[1*4+2];
+ u = matrix[2*4+2];
+ matrix[1*4+2] = c * t + s * u;
+ matrix[2*4+2] = c * u - s * t;
+
+ t = matrix[1*4+3];
+ u = matrix[2*4+3];
+ matrix[1*4+3] = c * t + s * u;
+ matrix[2*4+3] = c * u - s * t;
+ }
+ }
+ else if (x == 0 && y == 1 && z == 0)
+ {
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* matrix = state->matrix[index_mode].current.val;
+ double t, u;
+
+ t = matrix[0*4+0];
+ u = matrix[2*4+0];
+ matrix[0*4+0] = c * t - s * u;
+ matrix[2*4+0] = s * t + c * u;
+
+ t = matrix[0*4+1];
+ u = matrix[2*4+1];
+ matrix[0*4+1] = c * t - s * u;
+ matrix[2*4+1] = s * t + c * u;
+
+ t = matrix[0*4+2];
+ u = matrix[2*4+2];
+ matrix[0*4+2] = c * t - s * u;
+ matrix[2*4+2] = s * t + c * u;
+
+ t = matrix[0*4+3];
+ u = matrix[2*4+3];
+ matrix[0*4+3] = c * t - s * u;
+ matrix[2*4+3] = s * t + c * u;
+ }
+ }
+ else if (x == 0 && y == 0 && z == 1)
+ {
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* matrix = state->matrix[index_mode].current.val;
+ double t, u;
+
+ t = matrix[0*4+0];
+ u = matrix[1*4+0];
+ matrix[0*4+0] = c * t + s * u;
+ matrix[1*4+0] = c * u - s * t;
+
+ t = matrix[0*4+1];
+ u = matrix[1*4+1];
+ matrix[0*4+1] = c * t + s * u;
+ matrix[1*4+1] = c * u - s * t;
+
+ t = matrix[0*4+2];
+ u = matrix[1*4+2];
+ matrix[0*4+2] = c * t + s * u;
+ matrix[1*4+2] = c * u - s * t;
+
+ t = matrix[0*4+3];
+ u = matrix[1*4+3];
+ matrix[0*4+3] = c * t + s * u;
+ matrix[1*4+3] = c * u - s * t;
+ }
+ }
+ else
+ {
+ double sqrt_sum_sqr = sqrt(x*x+y*y+z*z);
+ if (sqrt_sum_sqr < 1e-4) return;
+ x /= sqrt_sum_sqr;
+ y /= sqrt_sum_sqr;
+ z /= sqrt_sum_sqr;
+ double matrix[16] = { x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
+ x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
+ x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
+ 0, 0, 0, 1};
+ _internal_glMultMatrixd(matrix);
+ }
+}
+
+GLAPI void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ _glRotate_internal(angle, x, y, z);
+
+ long args[] = { DOUBLE_TO_ARG(angle), DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)};
+ do_opengl_call(glRotated_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ _glRotate_internal(angle, x, y, z);
+
+ long args[] = { FLOAT_TO_ARG(angle), FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)};
+ do_opengl_call(glRotatef_func, NULL, args, NULL);
+}
+
+static void _glScale_internal(double a, double b, double c)
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* matrix = state->matrix[index_mode].current.val;
+ matrix[0*4+0] *= a;
+ matrix[0*4+1] *= a;
+ matrix[0*4+2] *= a;
+ matrix[0*4+3] *= a;
+ matrix[1*4+0] *= b;
+ matrix[1*4+1] *= b;
+ matrix[1*4+2] *= b;
+ matrix[1*4+3] *= b;
+ matrix[2*4+0] *= c;
+ matrix[2*4+1] *= c;
+ matrix[2*4+2] *= c;
+ matrix[2*4+3] *= c;
+ }
+}
+
+GLAPI void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ _glScale_internal(x, y, z);
+
+ long args[] = { DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)};
+ do_opengl_call(glScaled_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ _glScale_internal(x, y, z);
+
+ long args[] = { FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)};
+ do_opengl_call(glScalef_func, NULL, args, NULL);
+}
+
+static void _glTranslate_internal(double a, double b, double c)
+{
+ GET_CURRENT_STATE();
+ int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode);
+ if (index_mode >= 0)
+ {
+ GLdouble* matrix = state->matrix[index_mode].current.val;
+
+ matrix[3*4+0] += a * matrix[0*4+0] + b * matrix[1*4+0] + c * matrix[2*4+0];
+ matrix[3*4+1] += a * matrix[0*4+1] + b * matrix[1*4+1] + c * matrix[2*4+1];
+ matrix[3*4+2] += a * matrix[0*4+2] + b * matrix[1*4+2] + c * matrix[2*4+2];
+ matrix[3*4+3] += a * matrix[0*4+3] + b * matrix[1*4+3] + c * matrix[2*4+3];
+ }
+}
+
+GLAPI void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+ _glTranslate_internal(x, y, z);
+
+ long args[] = { DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)};
+ do_opengl_call(glTranslated_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ _glTranslate_internal(x, y, z);
+
+ long args[] = { FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)};
+ do_opengl_call(glTranslatef_func, NULL, args, NULL);
+}
+#endif
+/* End of matrix optimization */
+
+void glBindBufferARB_no_lock(GLenum target, GLuint buffer)
+{
+ CHECK_PROC(glBindBufferARB);
+ GET_CURRENT_STATE();
+ if (buffer >= 32768)
+ {
+ log_gl("buffer >= 32768\n");
+ return;
+ }
+ long args[] = {INT_TO_ARG(target), INT_TO_ARG(buffer)};
+ if (target == GL_ARRAY_BUFFER_ARB)
+ {
+ //log_gl("glBindBufferARB(GL_ARRAY_BUFFER,%d)\n", buffer);
+ state->arrayBuffer = buffer;
+ }
+ else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ {
+ //log_gl("glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,%d)\n", buffer);
+ state->elementArrayBuffer = buffer;
+ }
+ else if (target == GL_PIXEL_UNPACK_BUFFER_EXT)
+ {
+ //log_gl("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT,%d)\n", buffer);
+ state->pixelUnpackBuffer = buffer;
+ }
+ else if (target == GL_PIXEL_PACK_BUFFER_EXT)
+ {
+ //log_gl("glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT,%d)\n", buffer);
+ state->pixelPackBuffer = buffer;
+ }
+ do_opengl_call_no_lock(glBindBufferARB_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glBindBufferARB) (GLenum target, GLuint buffer)
+{
+ LOCK(glBindBufferARB_func);
+ glBindBufferARB_no_lock(target, buffer);
+ UNLOCK(glBindBufferARB_func);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glBindBuffer) (GLenum target, GLuint buffer)
+{
+ glBindBufferARB(target, buffer);
+}
+
+GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint * tab)
+{
+ CHECK_PROC(glGenBuffersARB);
+ GET_CURRENT_STATE();
+ if (n <= 0) { log_gl("n <= 0\n"); return; }
+ alloc_range(state->bufferAllocator, n, tab);
+ long args[] = { INT_TO_ARG(n) };
+ do_opengl_call(glGenBuffersARB_fake_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint * tab)
+{
+ glGenBuffersARB(n, tab);
+}
+
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint * tab)
+{
+ CHECK_PROC(glDeleteBuffersARB);
+ GET_CURRENT_STATE();
+ if (n <= 0) { log_gl("n <= 0\n"); return; }
+ delete_range(state->bufferAllocator, n, tab);
+ long args[] = { INT_TO_ARG(n), POINTER_TO_ARG(tab) };
+ do_opengl_call(glDeleteBuffersARB_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glDeleteBuffers(GLsizei n, const GLuint * tab)
+{
+ glDeleteBuffersARB(n, tab);
+}
+
+static Buffer* _get_buffer(GLenum target)
+{
+ GET_CURRENT_STATE();
+ if (target == GL_ARRAY_BUFFER_ARB)
+ {
+ if (state->arrayBuffer)
+ return &state->arrayBuffers[state->arrayBuffer];
+ else
+ return NULL;
+ }
+ else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ {
+ if (state->elementArrayBuffer)
+ return &state->elementArrayBuffers[state->elementArrayBuffer];
+ else
+ return NULL;
+ }
+ else if (target == GL_PIXEL_UNPACK_BUFFER_EXT)
+ {
+ if (state->pixelUnpackBuffer)
+ return &state->pixelUnpackBuffers[state->pixelUnpackBuffer];
+ else
+ return NULL;
+ }
+ else if (target == GL_PIXEL_PACK_BUFFER_EXT)
+ {
+ if (state->pixelPackBuffer)
+ return &state->pixelPackBuffers[state->pixelPackBuffer];
+ else
+ return NULL;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+GLAPI GLenum APIENTRY glGetError()
+{
+ int ret = 0;
+ if (disable_optim)
+ {
+ do_opengl_call(glGetError_func, &ret, NULL, NULL);
+ log_gl("glGetError() = %d\n", ret);
+ }
+ else
+ do_opengl_call(_glGetError_fake_func, NULL, NULL, NULL);
+ return ret;
+}
+
+GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
+{
+ CHECK_PROC(glBufferDataARB);
+
+ Buffer* buffer = _get_buffer(target);
+ if (buffer)
+ {
+ buffer->usage = usage;
+ buffer->size = size;
+ buffer->ptr = realloc(buffer->ptr, size);
+ if (data) memcpy(buffer->ptr, data, size);
+ }
+ else
+ {
+ fprintf(stderr, "unknown buffer/buffer target : %d\n", target);
+ }
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(size), POINTER_TO_ARG(data), INT_TO_ARG(usage) };
+ int args_size[] = { 0, 0, (data) ? size : 0, 0 };
+ do_opengl_call(glBufferDataARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
+{
+ glBufferDataARB(target, size, data, usage);
+}
+
+GLAPI void APIENTRY glBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data)
+{
+ CHECK_PROC(glBufferSubDataARB);
+
+ //log_gl("glBufferSubDataARB %d %d\n", offset, size);
+
+ Buffer* buffer = _get_buffer(target);
+ if (buffer)
+ {
+ assert(offset + size <= buffer->size);
+ assert(buffer->ptr);
+ memcpy(buffer->ptr + offset, data, size);
+ }
+ else
+ {
+ fprintf(stderr, "unknown buffer/buffer target : %d\n", target);
+ }
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(offset), INT_TO_ARG(size), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, size };
+ do_opengl_call(glBufferSubDataARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data)
+{
+ glBufferSubDataARB(target, offset, size, data);
+}
+
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data)
+{
+ CHECK_PROC(glGetBufferSubDataARB);
+
+ Buffer* buffer = _get_buffer(target);
+ if (!buffer) return;
+
+ assert(offset + size <= buffer->size);
+ assert(buffer->ptr);
+
+ memcpy(data, buffer->ptr + offset, size);
+}
+
+GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data)
+{
+ glGetBufferSubDataARB(target, offset, size, data);
+}
+
+GLvoid* glMapBufferARB (GLenum target, GLenum access)
+{
+ CHECK_PROC_WITH_RET(glMapBufferARB);
+
+ Buffer* buffer = _get_buffer(target);
+ if (!buffer) return NULL;
+ if (target == GL_PIXEL_PACK_BUFFER_EXT && (access == GL_READ_ONLY || access == GL_READ_WRITE))
+ {
+ int ret_int = 0;
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(buffer->size), POINTER_TO_ARG(buffer->ptr) };
+ int args_size[] = { 0, 0, buffer->size };
+ do_opengl_call(_glMapBufferARB_fake_func, &ret_int, CHECK_ARGS(args, args_size));
+ if (ret_int == 0)
+ return NULL;
+ }
+ buffer->access = access;
+ buffer->mapped = 1;
+ return buffer->ptr;
+}
+
+GLvoid* glMapBuffer(GLenum target, GLenum access)
+{
+ return glMapBufferARB(target, access);
+}
+
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params)
+{
+ CHECK_PROC(glGetBufferParameterivARB);
+
+ Buffer* buffer = _get_buffer(target);
+ if (!buffer) return;
+
+ switch (pname)
+ {
+ case GL_BUFFER_SIZE_ARB: *params = buffer->size; break;
+ case GL_BUFFER_USAGE_ARB: *params = buffer->usage; break;
+ case GL_BUFFER_ACCESS_ARB: *params = buffer->access; break;
+ case GL_BUFFER_MAPPED_ARB: *params = buffer->mapped; break;
+ default:
+ log_gl("unknown pname = 0x%X\n", pname);
+ }
+}
+
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params)
+{
+ glGetBufferParameterivARB(target, pname, params);
+}
+
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params)
+{
+ CHECK_PROC(glGetBufferPointervARB);
+ if (pname != GL_BUFFER_MAP_POINTER_ARB)
+ {
+ log_gl("glGetBufferPointervARB : unknown buffer data pname : %x\n", pname);
+ return;
+ }
+ Buffer* buffer = _get_buffer(target);
+ if (!buffer) return;
+ if (buffer->mapped) *params = buffer->ptr; else *params = NULL;
+}
+
+GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params)
+{
+ glGetBufferPointervARB(target, pname, params);
+}
+
+GLAPI GLboolean APIENTRY glUnmapBufferARB(GLenum target)
+{
+ CHECK_PROC_WITH_RET(glUnmapBufferARB);
+ Buffer* buffer = _get_buffer(target);
+ if (!buffer) return 0;
+ if (!buffer->mapped)
+ {
+ log_gl("unmapped buffer");
+ return 0;
+ }
+ buffer->mapped = 0;
+ if (buffer->access != GL_READ_ONLY)
+ {
+ glBufferSubDataARB(target, 0, buffer->size, buffer->ptr);
+ }
+ buffer->access = 0;
+ return 1;
+}
+
+GLAPI GLboolean APIENTRY glUnmapBuffer(GLenum target)
+{
+ return glUnmapBufferARB(target);
+}
+
+GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode )
+{
+ long args[] = { INT_TO_ARG(list), INT_TO_ARG(mode) };
+ GET_CURRENT_STATE();
+ alloc_value(state->listAllocator, list);
+ do_opengl_call(glNewList_func, NULL, args, NULL);
+}
+
+GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range )
+{
+ long args[] = { INT_TO_ARG(list), INT_TO_ARG(range) };
+ GET_CURRENT_STATE();
+ delete_consecutive_values(state->listAllocator, list, range);
+ do_opengl_call(glDeleteLists_func, NULL, args, NULL);
+}
+
+GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range )
+{
+ GET_CURRENT_STATE();
+ unsigned int firstValue = alloc_range(state->listAllocator, range, NULL);
+ long args[] = { INT_TO_ARG(range) };
+ do_opengl_call(glGenLists_fake_func, NULL, args, NULL);
+ return firstValue;
+}
+
+GLAPI void APIENTRY glCallLists( GLsizei n,
+ GLenum type,
+ const GLvoid *lists )
+{
+ long args[] = { INT_TO_ARG(n), INT_TO_ARG(type), POINTER_TO_ARG(lists) };
+ int args_size[] = { 0, 0, 0 };
+ int size = n;
+ if (n <= 0) { log_gl("n <= 0\n"); return; }
+ switch(type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ break;
+
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_2_BYTES:
+ size *= 2;
+ break;
+
+ case GL_3_BYTES:
+ size *= 3;
+ break;
+
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_4_BYTES:
+ size *= 4;
+ break;
+
+ default:
+ log_gl("unsupported type = %d\n", type);
+ return;
+ }
+ args_size[2] = size;
+ do_opengl_call(glCallLists_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI const GLubyte * APIENTRY glGetString( GLenum name )
+{
+ int i;
+ static GLubyte* glStrings[6] = {NULL};
+ static const char* glGetStringsName[] = {
+ "GL_VENDOR",
+ "GL_RENDERER",
+ "GL_VERSION",
+ "GL_EXTENSIONS",
+ "GL_SHADING_LANGUAGE_VERSION",
+ };
+
+ if (name >= GL_VENDOR && name <= GL_EXTENSIONS)
+ i = name - GL_VENDOR;
+ else if (name == GL_SHADING_LANGUAGE_VERSION)
+ i = 4;
+ else if (name == GL_PROGRAM_ERROR_STRING_NV)
+ i = 5;
+ else
+ {
+ log_gl("assert(name >= GL_VENDOR && name <= GL_EXTENSIONS || name == GL_SHADING_LANGUAGE_VERSION || name == GL_PROGRAM_ERROR_STRING_NV)\n");
+ return NULL;
+ }
+ LOCK(glGetString_func);
+ if (glStrings[i] == NULL)
+ {
+ if (i <= 4 && getenv(glGetStringsName[i]))
+ {
+ glStrings[i] = (GLubyte*)getenv(glGetStringsName[i]);
+ }
+ else
+ {
+ long args[] = { INT_TO_ARG(name) };
+ do_opengl_call_no_lock(glGetString_func, &glStrings[i], args, NULL);
+ }
+
+ if(debug_gl) log_gl("glGetString(0x%X) = %s\n", name, glStrings[i]);
+ if (name >= GL_VENDOR && name <= GL_EXTENSIONS) {
+ glStrings[name - GL_VENDOR] = (GLubyte*)strdup((char *)glStrings[i]);
+ }
+ else if (name == GL_SHADING_LANGUAGE_VERSION)
+ {
+ glStrings[i] = (GLubyte*)strdup((char *)glStrings[i]);
+ }
+ }
+ UNLOCK(glGetString_func);
+ return glStrings[i];
+}
+
+#define CASE_GL_PIXEL_MAP(x) case GL_PIXEL_MAP_##x: glGetIntegerv(CONCAT(GL_PIXEL_MAP_##x,_SIZE), &value); return value;
+
+static int get_glgetpixelmapv_size(int map)
+{
+ int value;
+ switch (map)
+ {
+ CASE_GL_PIXEL_MAP(I_TO_I);
+ CASE_GL_PIXEL_MAP(S_TO_S);
+ CASE_GL_PIXEL_MAP(I_TO_R);
+ CASE_GL_PIXEL_MAP(I_TO_G);
+ CASE_GL_PIXEL_MAP(I_TO_B);
+ CASE_GL_PIXEL_MAP(I_TO_A);
+ CASE_GL_PIXEL_MAP(R_TO_R);
+ CASE_GL_PIXEL_MAP(G_TO_G);
+ CASE_GL_PIXEL_MAP(B_TO_B);
+ CASE_GL_PIXEL_MAP(A_TO_A);
+ default :
+ {
+ log_gl("unhandled map = %d\n", map);
+ return 0;
+ }
+ }
+}
+
+GLAPI void APIENTRY glGetPixelMapfv( GLenum map, GLfloat *values )
+{
+ long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) };
+ int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(float) };
+ if (args_size[1] == 0) return;
+ do_opengl_call(glGetPixelMapfv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glGetPixelMapuiv( GLenum map, GLuint *values )
+{
+ long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) };
+ int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(int) };
+ if (args_size[1] == 0) return;
+ do_opengl_call(glGetPixelMapuiv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glGetPixelMapusv( GLenum map, GLushort *values )
+{
+ long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) };
+ int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(short) };
+ if (args_size[1] == 0) return;
+ do_opengl_call(glGetPixelMapusv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+static int glMap1_get_multiplier(GLenum target)
+{
+ switch (target)
+ {
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_3:
+ return 3;
+ break;
+
+ case GL_MAP1_VERTEX_4:
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_TEXTURE_COORD_4:
+ return 4;
+ break;
+
+ case GL_MAP1_INDEX:
+ case GL_MAP1_TEXTURE_COORD_1:
+ return 1;
+ break;
+
+ case GL_MAP1_TEXTURE_COORD_2:
+ return 2;
+ break;
+
+ default:
+ if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV && target <= GL_MAP1_VERTEX_ATTRIB15_4_NV)
+ return 4;
+ log_gl("unhandled target = %d\n", target);
+ return 0;
+ }
+}
+
+
+static int glMap2_get_multiplier(GLenum target)
+{
+ switch (target)
+ {
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_3:
+ return 3;
+ break;
+
+ case GL_MAP2_VERTEX_4:
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_TEXTURE_COORD_4:
+ return 4;
+ break;
+
+ case GL_MAP2_INDEX:
+ case GL_MAP2_TEXTURE_COORD_1:
+ return 1;
+ break;
+
+ case GL_MAP2_TEXTURE_COORD_2:
+ return 2;
+ break;
+
+ default:
+ if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV && target <= GL_MAP2_VERTEX_ATTRIB15_4_NV)
+ return 4;
+ log_gl("unhandled target = %d\n", target);
+ return 0;
+ }
+}
+
+static int get_dimensionnal_evaluator(GLenum target)
+{
+ switch(target)
+ {
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_INDEX:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_1:
+ case GL_MAP1_TEXTURE_COORD_2:
+ case GL_MAP1_TEXTURE_COORD_3:
+ case GL_MAP1_TEXTURE_COORD_4:
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_VERTEX_4:
+ return 1;
+
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_INDEX:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_1:
+ case GL_MAP2_TEXTURE_COORD_2:
+ case GL_MAP2_TEXTURE_COORD_3:
+ case GL_MAP2_TEXTURE_COORD_4:
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_VERTEX_4:
+ return 2;
+
+ default:
+ log_gl("unhandled target %d\n", target);
+ return 0;
+ }
+}
+
+GLAPI void APIENTRY glMap1f( GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points )
+{
+ long args[] = { INT_TO_ARG(target), FLOAT_TO_ARG(u1), FLOAT_TO_ARG(u2),
+ INT_TO_ARG(stride), INT_TO_ARG(order), POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0 };
+ int num_points = order;
+ int multiplier = glMap1_get_multiplier(target);
+ if (multiplier)
+ {
+ num_points *= multiplier;
+ args_size[5] = num_points * sizeof(float);
+ do_opengl_call(glMap1f_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glMap1d( GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points )
+{
+ long args[] = { INT_TO_ARG(target), DOUBLE_TO_ARG(u1), DOUBLE_TO_ARG(u2),
+ INT_TO_ARG(stride), INT_TO_ARG(order), POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0 };
+ int num_points = order;
+ int multiplier = glMap1_get_multiplier(target);
+ if (multiplier)
+ {
+ num_points *= multiplier;
+ args_size[5] = num_points * sizeof(double);
+ do_opengl_call(glMap1d_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glMap2f( GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points )
+{
+ long args[] = { INT_TO_ARG(target),
+ FLOAT_TO_ARG(u1), FLOAT_TO_ARG(u2),
+ INT_TO_ARG(ustride), INT_TO_ARG(uorder),
+ FLOAT_TO_ARG(v1), FLOAT_TO_ARG(v2),
+ INT_TO_ARG(vstride), INT_TO_ARG(vorder),
+ POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int num_points = uorder * vorder;
+ int multiplier = glMap2_get_multiplier(target);
+ if (multiplier)
+ {
+ num_points *= multiplier;
+ args_size[9] = num_points * sizeof(float);
+ do_opengl_call(glMap2f_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glMap2d( GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points )
+{
+ long args[] = { INT_TO_ARG(target),
+ DOUBLE_TO_ARG(u1), DOUBLE_TO_ARG(u2),
+ INT_TO_ARG(ustride), INT_TO_ARG(uorder),
+ DOUBLE_TO_ARG(v1), DOUBLE_TO_ARG(v2),
+ INT_TO_ARG(vstride), INT_TO_ARG(vorder),
+ POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ int num_points = uorder * vorder;
+ int multiplier = glMap2_get_multiplier(target);
+ if (multiplier)
+ {
+ num_points *= multiplier;
+ args_size[9] = num_points * sizeof(double);
+ do_opengl_call(glMap2d_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+static int _glGetMapv_get_n_components( GLenum target, GLenum query)
+{
+ int dim = get_dimensionnal_evaluator(target);
+ if (query == GL_COEFF)
+ {
+ int orders[2] = { 1, 1 };
+ glGetMapiv(target, GL_ORDER, orders);
+ return orders[0] * orders[1] * ((dim == 1) ? glMap1_get_multiplier(target) : glMap2_get_multiplier(target));
+ }
+ else if (query == GL_ORDER)
+ {
+ return dim;
+ }
+ else if (query == GL_DOMAIN)
+ {
+ return 2 * dim;
+ }
+ else
+ return 0;
+}
+
+
+GLAPI void APIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v )
+{
+ int dim = get_dimensionnal_evaluator(target);
+ if (dim == 0) return;
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) };
+ int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(double) };
+ do_opengl_call(glGetMapdv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v )
+{
+ int dim = get_dimensionnal_evaluator(target);
+ if (dim == 0) return;
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) };
+ int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(float) };
+ do_opengl_call(glGetMapfv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v )
+{
+ int dim = get_dimensionnal_evaluator(target);
+ if (dim == 0) return;
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) };
+ int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(int) };
+ do_opengl_call(glGetMapiv_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+ CHECK_PROC(glBindTexture);
+ GET_CURRENT_STATE();
+ alloc_value(state->textureAllocator, texture);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(texture) };
+ if (target == GL_TEXTURE_2D)
+ {
+ state->current_server_state.bindTexture2D = texture;
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ state->current_server_state.bindTextureRectangle = texture;
+ }
+ do_opengl_call(glBindTexture_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glBindTextureEXT) (GLenum target, GLuint texture)
+{
+ glFuncTable.fpBindTexture(target, texture);
+}
+
+
+GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures )
+{
+ CHECK_PROC(glGenTextures);
+ GET_CURRENT_STATE();
+ if (n <= 0) { log_gl("n <= 0\n"); return; }
+ alloc_range(state->textureAllocator, n, textures);
+ long args[] = { n };
+ do_opengl_call(glGenTextures_fake_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glGenTexturesEXT( GLsizei n, GLuint *textures )
+{
+ glFuncTable.fpGenTextures(n, textures);
+}
+
+GLAPI void APIENTRY glDeleteTextures ( GLsizei n, const GLuint *textures )
+{
+ CHECK_PROC(glDeleteTextures);
+ GET_CURRENT_STATE();
+ if (n <= 0) { log_gl("n <= 0\n"); return; }
+ delete_range(state->textureAllocator, n, textures);
+ long args[] = { INT_TO_ARG(n), POINTER_TO_ARG(textures) };
+ do_opengl_call(glDeleteTextures_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glDeleteTexturesEXT ( GLsizei n, const GLuint *textures )
+{
+ glFuncTable.fpDeleteTextures(n, textures);
+}
+
+static int getTexImageTypeSizeSimple(int format, int type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ return 1;
+
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ return 2;
+
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_UNSIGNED_INT_24_8_EXT:
+ case GL_FLOAT:
+ return 4;
+
+ default:
+ log_gl("unknown texture type %d for texture format %d\n", type, format);
+ return 0;
+ }
+}
+
+static int getTexImageFactorFromFormatAndType(int format, int type)
+{
+ switch (format)
+ {
+ case GL_COLOR_INDEX:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_DEPTH_COMPONENT:
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_STENCIL_EXT:
+ return 1 * getTexImageTypeSizeSimple(format, type);
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ return 2 * getTexImageTypeSizeSimple(format, type);
+ break;
+
+ case GL_YCBCR_MESA:
+ {
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT_8_8_MESA:
+ case GL_UNSIGNED_SHORT_8_8_REV_MESA:
+ return 2;
+
+ default:
+ log_gl("unknown texture type %d for texture format %d\n", type, format);
+ return 0;
+ }
+ }
+
+ case GL_RGB:
+ case GL_BGR:
+ {
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ return 1 * 3;
+
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ return 2 * 3;
+
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_FLOAT:
+ return 4 * 3;
+
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return 1;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_8_8_MESA:
+ case GL_UNSIGNED_SHORT_8_8_REV_MESA:
+ return 2;
+
+ default:
+ log_gl("unknown texture type %d for texture format %d\n", type, format);
+ return 0;
+ }
+ }
+
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ {
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ return 1 * 4;
+
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ return 2 * 4;
+
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_FLOAT:
+ return 4 * 4;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return 2;
+
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return 4;
+
+ default:
+ log_gl("unknown texture type %d for texture format %d\n", type, format);
+ return 0;
+ }
+ }
+
+ default:
+ log_gl("unknown texture format : %d\n", format);
+ return 0;
+ }
+}
+
+static void* _calcReadSize(int width, int height, int depth, GLenum format, GLenum type, void* pixels, int* p_size)
+{
+ int pack_row_length, pack_alignment, pack_skip_rows, pack_skip_pixels;
+
+ glFuncTable.fpGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
+ glFuncTable.fpGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
+ glFuncTable.fpGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
+ glFuncTable.fpGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
+
+ int w = (pack_row_length == 0) ? width : pack_row_length;
+ int size = ((width * getTexImageFactorFromFormatAndType(format, type) + pack_alignment - 1) & (~(pack_alignment-1))) * depth;
+ if (height >= 1)
+ size += ((w * getTexImageFactorFromFormatAndType(format, type) + pack_alignment - 1) & (~(pack_alignment-1)))* (height-1) * depth ;
+ *p_size = size;
+
+ pixels += (pack_skip_pixels + pack_skip_rows * w) * getTexImageFactorFromFormatAndType(format, type);
+
+ return pixels;
+}
+
+static const void* _calcWriteSize(int width, int height, int depth, GLenum format, GLenum type, const void* pixels, int* p_size)
+{
+ int unpack_row_length, unpack_alignment, unpack_skip_rows, unpack_skip_pixels;
+
+ glFuncTable.fpGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
+ glFuncTable.fpGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
+ glFuncTable.fpGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpack_skip_rows);
+ glFuncTable.fpGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpack_skip_pixels);
+
+ int w = (unpack_row_length == 0) ? width : unpack_row_length;
+ int size = ((width * getTexImageFactorFromFormatAndType(format, type) + unpack_alignment - 1) & (~(unpack_alignment-1))) * depth;
+ if (height >= 1)
+ size += ((w * getTexImageFactorFromFormatAndType(format, type) + unpack_alignment - 1) & (~(unpack_alignment-1))) * (height-1) * depth;
+ *p_size = size;
+
+ pixels += (unpack_skip_pixels + unpack_skip_rows * w) * getTexImageFactorFromFormatAndType(format, type);
+
+ return pixels;
+}
+
+GLAPI void APIENTRY glTexImage1D(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, 1, 1, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size };
+ do_opengl_call(glTexImage1D_func, NULL, CHECK_ARGS(args, args_size));
+
+}
+
+GLAPI void APIENTRY glTexImage1DEXT(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
+}
+
+GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ int size = 0;
+ pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, size };
+ do_opengl_call(fake_gluBuild2DMipmaps_func, NULL, CHECK_ARGS(args, args_size));
+ return 0;
+}
+
+
+GLAPI void APIENTRY glTexImage2D( GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_STATE();
+ int i;
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size);
+
+ if (target == GL_TEXTURE_2D)
+ {
+ for(i=0;i<state->current_server_state.texture2DCacheDim;i++)
+ {
+ if (state->current_server_state.texture2DCache[i].texture == state->current_server_state.bindTexture2D &&
+ state->current_server_state.texture2DCache[i].level == level)
+ {
+ state->current_server_state.texture2DCache[i].width = width;
+ state->current_server_state.texture2DCache[i].height = height;
+ break;
+ }
+ }
+ if (i == state->current_server_state.texture2DCacheDim)
+ {
+ state->current_server_state.texture2DCache =
+ realloc(state->current_server_state.texture2DCache, sizeof(Texture2DDim) *
+ (state->current_server_state.texture2DCacheDim + 1));
+ i = state->current_server_state.texture2DCacheDim;
+ state->current_server_state.texture2DCache[i].texture = state->current_server_state.bindTexture2D;
+ state->current_server_state.texture2DCache[i].level = level;
+ state->current_server_state.texture2DCache[i].width = width;
+ state->current_server_state.texture2DCache[i].height = height;
+ state->current_server_state.texture2DCacheDim++;
+ }
+ }
+ else if (target == GL_PROXY_TEXTURE_2D_EXT)
+ {
+ for(i=0;i<state->current_server_state.textureProxy2DCacheDim;i++)
+ {
+ if (state->current_server_state.textureProxy2DCache[i].level == level)
+ {
+ state->current_server_state.textureProxy2DCache[i].width = width;
+ state->current_server_state.textureProxy2DCache[i].height = height;
+ break;
+ }
+ }
+ if (i == state->current_server_state.textureProxy2DCacheDim)
+ {
+ state->current_server_state.textureProxy2DCache =
+ realloc(state->current_server_state.textureProxy2DCache, sizeof(Texture2DDim) *
+ (state->current_server_state.textureProxy2DCacheDim + 1));
+ i = state->current_server_state.textureProxy2DCacheDim;
+ state->current_server_state.textureProxy2DCache[i].level = level;
+ state->current_server_state.textureProxy2DCache[i].width = width;
+ state->current_server_state.textureProxy2DCache[i].height = height;
+ state->current_server_state.textureProxy2DCacheDim++;
+ }
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ for(i=0;i<state->current_server_state.textureRectangleCacheDim;i++)
+ {
+ if (state->current_server_state.textureRectangleCache[i].texture == state->current_server_state.bindTextureRectangle &&
+ state->current_server_state.textureRectangleCache[i].level == level)
+ {
+ state->current_server_state.textureRectangleCache[i].width = width;
+ state->current_server_state.textureRectangleCache[i].height = height;
+ break;
+ }
+ }
+ if (i == state->current_server_state.textureRectangleCacheDim)
+ {
+ state->current_server_state.textureRectangleCache =
+ realloc(state->current_server_state.textureRectangleCache, sizeof(Texture2DDim) *
+ (state->current_server_state.textureRectangleCacheDim + 1));
+ i = state->current_server_state.textureRectangleCacheDim;
+ state->current_server_state.textureRectangleCache[i].texture = state->current_server_state.bindTextureRectangle;
+ state->current_server_state.textureRectangleCache[i].level = level;
+ state->current_server_state.textureRectangleCache[i].width = width;
+ state->current_server_state.textureRectangleCache[i].height = height;
+ state->current_server_state.textureRectangleCacheDim++;
+ }
+ }
+ else if (target == GL_PROXY_TEXTURE_RECTANGLE_ARB)
+ {
+ for(i=0;i<state->current_server_state.textureProxyRectangleCacheDim;i++)
+ {
+ if (state->current_server_state.textureProxyRectangleCache[i].level == level)
+ {
+ state->current_server_state.textureProxyRectangleCache[i].width = width;
+ state->current_server_state.textureProxyRectangleCache[i].height = height;
+ break;
+ }
+ }
+ if (i == state->current_server_state.textureProxyRectangleCacheDim)
+ {
+ state->current_server_state.textureProxyRectangleCache =
+ realloc(state->current_server_state.textureProxyRectangleCache, sizeof(Texture2DDim) *
+ (state->current_server_state.textureProxyRectangleCacheDim + 1));
+ i = state->current_server_state.textureProxyRectangleCacheDim;
+ state->current_server_state.textureProxyRectangleCache[i].level = level;
+ state->current_server_state.textureProxyRectangleCache[i].width = width;
+ state->current_server_state.textureProxyRectangleCache[i].height = height;
+ state->current_server_state.textureProxyRectangleCacheDim++;
+ }
+ }
+
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size };
+ do_opengl_call(glTexImage2D_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glTexImage2DEXT(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ glFuncTable.fpTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+}
+
+GLAPI void APIENTRY glTexImage3D( GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, height, depth, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size };
+ do_opengl_call(glTexImage3D_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glTexImage3DEXT)(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ CHECK_PROC(glTexImage3DEXT);
+ glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
+}
+
+GLAPI void APIENTRY glTexSubImage1D( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, 1, 1, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset),
+ INT_TO_ARG(width), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, size };
+ do_opengl_call(glTexSubImage1D_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glTexSubImage1DEXT)( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ CHECK_PROC(glTexSubImage1DEXT);
+ glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
+}
+
+GLAPI void APIENTRY glTexSubImage2D( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, size };
+ do_opengl_call(glTexSubImage2D_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glTexSubImage2DEXT)( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ CHECK_PROC(glTexSubImage2DEXT);
+ glFuncTable.fpTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+GLAPI void APIENTRY glTexSubImage3D( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ int size = 0;
+ if (pixels)
+ pixels = _calcWriteSize(width, height, depth, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), INT_TO_ARG(zoffset),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(format), INT_TO_ARG(type),
+ POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, size };
+ do_opengl_call(glTexSubImage3D_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glTexSubImage3DEXT)( GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ CHECK_PROC(glTexSubImage3DEXT);
+ glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+GLAPI void APIENTRY glSelectBuffer( GLsizei size, GLuint *buffer )
+{
+ if (size <= 0) return;
+ GET_CURRENT_STATE();
+ state->client_state.selectBufferSize = size;
+ state->client_state.selectBufferPtr = buffer;
+ long args[] = { INT_TO_ARG(size) };
+ do_opengl_call(_glSelectBuffer_fake_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
+{
+ if (size <= 0) return;
+ GET_CURRENT_STATE();
+ state->client_state.feedbackBufferSize = size;
+ state->client_state.feedbackBufferPtr = buffer;
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type) };
+ do_opengl_call(_glFeedbackBuffer_fake_func, NULL, args, NULL);
+}
+
+GLAPI GLint APIENTRY glRenderMode(GLenum mode)
+{
+ GLint ret;
+ GET_CURRENT_STATE();
+ long args[] = { UNSIGNED_INT_TO_ARG(mode)};
+ do_opengl_call(glRenderMode_func, &ret, args, NULL);
+ if (mode == GL_SELECT && state->client_state.selectBufferPtr)
+ {
+ long args[] = { POINTER_TO_ARG(state->client_state.selectBufferPtr) };
+ int args_size[] = { state->client_state.selectBufferSize * 4 };
+ do_opengl_call(_glGetSelectBuffer_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+ else if (mode == GL_FEEDBACK && state->client_state.selectBufferPtr)
+ {
+ long args[] = { POINTER_TO_ARG(state->client_state.feedbackBufferPtr) };
+ int args_size[] = { state->client_state.feedbackBufferSize * 4 };
+ do_opengl_call(_glGetFeedbackBuffer_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+ return ret;
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetCompressedTexImageARB)(GLenum target, GLint level, GLvoid *img)
+{
+ CHECK_PROC(glGetCompressedTexImageARB);
+
+ int imageSize = 0;
+ glFuncTable.fpGetTexLevelParameteriv(target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &imageSize);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), POINTER_TO_ARG(img) };
+ int args_size[] = { 0, 0, imageSize };
+ do_opengl_call(glGetCompressedTexImageARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetCompressedTexImage)(GLenum target, GLint level, GLvoid *img)
+{
+ glGetCompressedTexImageARB(target, level, img);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage1DARB)(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexImage1DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexImage1DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage1D)(GLenum target,
+ GLint level,
+ GLenum internalFormat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexImage1DARB(target, level, internalFormat, width, border, imageSize, data);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage2DARB)(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexImage2DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexImage2DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage2D)(GLenum target,
+ GLint level,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexImage2DARB(target, level, internalFormat, width, height, border, imageSize, data);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage3DARB)(GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexImage3DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexImage3DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage3D)(GLenum target,
+ GLint level,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexImage3DARB(target, level, internalFormat, width, height, depth, border, imageSize, data);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage1DARB)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexSubImage1DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset),
+ INT_TO_ARG(width), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexSubImage1DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage1D)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexSubImage1DARB(target, level, xoffset, width, format, imageSize, data);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage2DARB)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexSubImage2DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexSubImage2DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage2D)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage3DARB)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ CHECK_PROC(glCompressedTexSubImage3DARB);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), INT_TO_ARG(zoffset),
+ INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, imageSize };
+ do_opengl_call(glCompressedTexSubImage3DARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage3D)(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const GLvoid * data)
+{
+ glCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+
+GLAPI void APIENTRY glGetTexLevelParameteriv( GLenum target,
+ GLint level,
+ GLenum pname,
+ GLint *params )
+{
+ int i;
+ GET_CURRENT_STATE();
+
+ if (target == GL_TEXTURE_2D && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT))
+ {
+ for(i=0;i<state->current_server_state.texture2DCacheDim;i++)
+ {
+ if (state->current_server_state.texture2DCache[i].texture == state->current_server_state.bindTexture2D &&
+ state->current_server_state.texture2DCache[i].level == level)
+ {
+ if (pname == GL_TEXTURE_WIDTH)
+ {
+ *params = state->current_server_state.texture2DCache[i].width;
+ return;
+ }
+ if (pname == GL_TEXTURE_HEIGHT)
+ {
+ *params = state->current_server_state.texture2DCache[i].height;
+ return;
+ }
+ }
+ }
+ }
+ else if (target == GL_PROXY_TEXTURE_2D_EXT && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT))
+ {
+ for(i=0;i<state->current_server_state.textureProxy2DCacheDim;i++)
+ {
+ if (state->current_server_state.textureProxy2DCache[i].level == level)
+ {
+ if (pname == GL_TEXTURE_WIDTH)
+ {
+ *params = state->current_server_state.textureProxy2DCache[i].width;
+ return;
+ }
+ if (pname == GL_TEXTURE_HEIGHT)
+ {
+ *params = state->current_server_state.textureProxy2DCache[i].height;
+ return;
+ }
+ }
+ }
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_ARB && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT))
+ {
+ for(i=0;i<state->current_server_state.textureRectangleCacheDim;i++)
+ {
+ if (state->current_server_state.textureRectangleCache[i].texture == state->current_server_state.bindTextureRectangle &&
+ state->current_server_state.textureRectangleCache[i].level == level)
+ {
+ if (pname == GL_TEXTURE_WIDTH)
+ {
+ *params = state->current_server_state.textureRectangleCache[i].width;
+ return;
+ }
+ if (pname == GL_TEXTURE_HEIGHT)
+ {
+ *params = state->current_server_state.textureRectangleCache[i].height;
+ return;
+ }
+ }
+ }
+ }
+ else if (target == GL_PROXY_TEXTURE_RECTANGLE_ARB && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT))
+ {
+ for(i=0;i<state->current_server_state.textureProxyRectangleCacheDim;i++)
+ {
+ if (state->current_server_state.textureProxyRectangleCache[i].level == level)
+ {
+ if (pname == GL_TEXTURE_WIDTH)
+ {
+ *params = state->current_server_state.textureProxyRectangleCache[i].width;
+ return;
+ }
+ if (pname == GL_TEXTURE_HEIGHT)
+ {
+ *params = state->current_server_state.textureProxyRectangleCache[i].height;
+ return;
+ }
+ }
+ }
+ }
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(pname), POINTER_TO_ARG(params) };
+ do_opengl_call(glGetTexLevelParameteriv_func, NULL, args, NULL);
+
+}
+
+GLAPI void APIENTRY glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
+{
+ if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT)
+ *params = 1;
+ else
+ {
+ int size = __glTexParameter_size(get_err_file(), pname);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(pname), POINTER_TO_ARG(params) };
+ int args_size[] = { 0, 0, size * sizeof(GLfloat) };
+ do_opengl_call(glGetTexParameterfv_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+ GET_CURRENT_STATE();
+ if (pname == GL_FOG_MODE)
+ state->current_server_state.fog.mode = param;
+ else if (pname == GL_FOG_DENSITY)
+ state->current_server_state.fog.density = param;
+ else if (pname == GL_FOG_START)
+ state->current_server_state.fog.start = param;
+ else if (pname == GL_FOG_END)
+ state->current_server_state.fog.end = param;
+ else if (pname == GL_FOG_INDEX)
+ state->current_server_state.fog.index = param;
+ long args[] = { UNSIGNED_INT_TO_ARG(pname), FLOAT_TO_ARG(param)};
+ do_opengl_call(glFogf_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glFogi(GLenum pname, GLint param)
+{
+ GET_CURRENT_STATE();
+ if (pname == GL_FOG_MODE)
+ state->current_server_state.fog.mode = param;
+ else if (pname == GL_FOG_DENSITY)
+ state->current_server_state.fog.density = param;
+ else if (pname == GL_FOG_START)
+ state->current_server_state.fog.start = param;
+ else if (pname == GL_FOG_END)
+ state->current_server_state.fog.end = param;
+ else if (pname == GL_FOG_INDEX)
+ state->current_server_state.fog.index = param;
+ long args[] = { UNSIGNED_INT_TO_ARG(pname), INT_TO_ARG(param)};
+ do_opengl_call(glFogi_func, NULL, args, NULL);
+}
+
+
+GLAPI void APIENTRY glFogfv( GLenum pname, const GLfloat *params )
+{
+ if (pname != GL_FOG_COLOR)
+ {
+ glFuncTable.fpFogf(pname, *params);
+ return;
+ }
+ GET_CURRENT_STATE();
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) };
+ memcpy(state->current_server_state.fog.color, params, 4 * sizeof(float));
+ do_opengl_call(glFogfv_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glFogiv( GLenum pname, const GLint *params )
+{
+ if (pname != GL_FOG_COLOR)
+ {
+ glFuncTable.fpFogi(pname, *params);
+ return;
+ }
+ long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) };
+ do_opengl_call(glFogiv_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 )
+{
+ glRectd(v1[0], v1[1], v2[0], v2[1]);
+}
+GLAPI void APIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 )
+{
+ glRectf(v1[0], v1[1], v2[0], v2[1]);
+}
+GLAPI void APIENTRY glRectiv( const GLint *v1, const GLint *v2 )
+{
+ glRecti(v1[0], v1[1], v2[0], v2[1]);
+}
+GLAPI void APIENTRY glRectsv( const GLshort *v1, const GLshort *v2 )
+{
+ glRects(v1[0], v1[1], v2[0], v2[1]);
+}
+
+
+GLAPI void APIENTRY glBitmap(GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap )
+{
+ GET_CURRENT_STATE();
+ int unpack_alignment, unpack_row_length;
+ glFuncTable.fpGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
+ glFuncTable.fpGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
+ int w = (unpack_row_length == 0) ? width : unpack_row_length;
+ int size = ((w + unpack_alignment - 1) & (~(unpack_alignment-1))) * height;
+ long args[] = { INT_TO_ARG(width), INT_TO_ARG(height), FLOAT_TO_ARG(xorig), FLOAT_TO_ARG(yorig),
+ FLOAT_TO_ARG(xmove), FLOAT_TO_ARG(ymove), POINTER_TO_ARG(bitmap) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, size };
+ do_opengl_call(glBitmap_func, NULL, CHECK_ARGS(args, args_size));
+
+ state->currentRasterPos[0] += xmove;
+ state->currentRasterPos[1] += ymove;
+}
+
+GLAPI void APIENTRY glGetTexImage( GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels )
+{
+ int size = 0, width, height = 1, depth = 1;
+ if (target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_2D || target == GL_PROXY_TEXTURE_3D)
+ {
+ log_gl("unhandled target : %d\n", target);
+ return;
+ }
+ glFuncTable.fpGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+ if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB || target == GL_TEXTURE_3D)
+ glFuncTable.fpGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+ if (target == GL_TEXTURE_3D)
+ glFuncTable.fpGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
+
+ pixels = _calcReadSize(width, height, depth, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, size };
+ do_opengl_call(glGetTexImage_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+
+void glReadPixels_no_lock(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels )
+{
+ GET_CURRENT_STATE();
+ if (state->pixelPackBuffer)
+ {
+ int fake_ret;
+ long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height),
+ INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ /* Make it synchronous, otherwise it floods server */
+ do_opengl_call_no_lock(_glReadPixels_pbo_func, &fake_ret, args, NULL);
+ }
+ else
+ {
+ int size = 0;
+
+ pixels = _calcReadSize(width, height, 1, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height),
+ INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, size };
+
+ do_opengl_call_no_lock(glReadPixels_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glReadPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels )
+{
+ LOCK(glReadPixels_func);
+ glReadPixels_no_lock(x, y, width, height, format, type, pixels);
+ UNLOCK(glReadPixels_func);
+}
+
+GLAPI void APIENTRY glDrawPixels(GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_STATE();
+ if (state->pixelUnpackBuffer)
+ {
+ long args[] = { INT_TO_ARG(width), INT_TO_ARG(height),
+ INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ do_opengl_call(_glDrawPixels_pbo_func, NULL, args, NULL);
+ }
+ else
+ {
+ int size = 0;
+
+ pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size);
+
+ long args[] = { INT_TO_ARG(width), INT_TO_ARG(height),
+ INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) };
+ int args_size[] = { 0, 0, 0, 0, size };
+ do_opengl_call(glDrawPixels_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glInterleavedArrays( GLenum format,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glInterleavedArrays);
+ GET_CURRENT_STATE();
+ if (debug_array_ptr)
+ log_gl("glInterleavedArrays format=%d stride=%d ptr=%p\n", format, stride, ptr);
+ state->client_state.arrays.interleavedArrays.format = format;
+ state->client_state.arrays.interleavedArrays.stride = stride;
+ state->client_state.arrays.interleavedArrays.ptr = ptr;
+}
+
+GLAPI void APIENTRY glVertexPointer( GLint size,
+ GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glVertexPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.vertexArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.vertexArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glVertexPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.vertexArray.size == size &&
+ state->client_state.arrays.vertexArray.type == type &&
+ state->client_state.arrays.vertexArray.stride == stride &&
+ state->client_state.arrays.vertexArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glVertexPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr);
+ state->client_state.arrays.vertexArray.size = size;
+ state->client_state.arrays.vertexArray.type = type;
+ state->client_state.arrays.vertexArray.stride = stride;
+ state->client_state.arrays.vertexArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr));
+
+GLAPI void APIENTRY glNormalPointer( GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glNormalPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.normalArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.normalArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glNormalPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.normalArray.type == type &&
+ state->client_state.arrays.normalArray.stride == stride &&
+ state->client_state.arrays.normalArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glNormalPointer type=%d stride=%d ptr=%p\n", type, stride, ptr);
+ state->client_state.arrays.normalArray.size = 3;
+ state->client_state.arrays.normalArray.type = type;
+ state->client_state.arrays.normalArray.stride = stride;
+ state->client_state.arrays.normalArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr));
+
+GLAPI void APIENTRY glIndexPointer( GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glIndexPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.indexArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.indexArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glIndexPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.indexArray.type == type &&
+ state->client_state.arrays.indexArray.stride == stride &&
+ state->client_state.arrays.indexArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glIndexPointer type=%d stride=%d ptr=%p\n", type, stride, ptr);
+ state->client_state.arrays.indexArray.size = 1;
+ state->client_state.arrays.indexArray.type = type;
+ state->client_state.arrays.indexArray.stride = stride;
+ state->client_state.arrays.indexArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glIndexPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr));
+
+GLAPI void APIENTRY glColorPointer( GLint size,
+ GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glColorPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.colorArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.colorArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glColorPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.colorArray.size == size &&
+ state->client_state.arrays.colorArray.type == type &&
+ state->client_state.arrays.colorArray.stride == stride &&
+ state->client_state.arrays.colorArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glColorPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr);
+ state->client_state.arrays.colorArray.size = size;
+ state->client_state.arrays.colorArray.type = type;
+ state->client_state.arrays.colorArray.stride = stride;
+ state->client_state.arrays.colorArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr));
+
+GLAPI void APIENTRY glSecondaryColorPointer( GLint size,
+ GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr )
+{
+ CHECK_PROC(glSecondaryColorPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.secondaryColorArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.secondaryColorArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glSecondaryColorPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.secondaryColorArray.size == size &&
+ state->client_state.arrays.secondaryColorArray.type == type &&
+ state->client_state.arrays.secondaryColorArray.stride == stride &&
+ state->client_state.arrays.secondaryColorArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glSecondaryColorPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr);
+ state->client_state.arrays.secondaryColorArray.size = size;
+ state->client_state.arrays.secondaryColorArray.type = type;
+ state->client_state.arrays.secondaryColorArray.stride = stride;
+ state->client_state.arrays.secondaryColorArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glSecondaryColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr));
+
+GLAPI void APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr )
+{
+ CHECK_PROC(glTexCoordPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glTexCoordPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size == size &&
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type == type &&
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride == stride &&
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glTexCoordPointer[%d] size=%d type=%d stride=%d ptr=%p\n",
+ state->client_state.clientActiveTexture, size, type, stride, ptr);
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].index =
+ state->client_state.clientActiveTexture;
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size = size;
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type = type;
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride = stride;
+ state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr));
+
+GLAPI void APIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr )
+{
+ CHECK_PROC(glEdgeFlagPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.edgeFlagArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.edgeFlagArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glEdgeFlagPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.edgeFlagArray.stride == stride &&
+ state->client_state.arrays.edgeFlagArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("edgeFlagArray stride=%d ptr=%p\n", stride, ptr);
+ state->client_state.arrays.edgeFlagArray.size = 1;
+ state->client_state.arrays.edgeFlagArray.type = GL_BYTE;
+ state->client_state.arrays.edgeFlagArray.stride = stride;
+ state->client_state.arrays.edgeFlagArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glEdgeFlagPointer, (GLsizei stride, const GLvoid *ptr), (stride, ptr));
+
+GLAPI void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ CHECK_PROC(glFogCoordPointer);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.fogCoordArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.fogCoordArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glFogCoordPointer_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (state->client_state.arrays.fogCoordArray.type == type &&
+ state->client_state.arrays.fogCoordArray.stride == stride &&
+ state->client_state.arrays.fogCoordArray.ptr == ptr)
+ {
+ }
+ else
+ {
+ if (debug_array_ptr)
+ log_gl("glFogCoordPointer type=%d stride=%d ptr=%p\n", type, stride, ptr);
+ state->client_state.arrays.fogCoordArray.size = 1;
+ state->client_state.arrays.fogCoordArray.type = type;
+ state->client_state.arrays.fogCoordArray.stride = stride;
+ state->client_state.arrays.fogCoordArray.ptr = ptr;
+ }
+}
+
+DEFINE_EXT(glFogCoordPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr));
+
+GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ CHECK_PROC(glWeightPointerARB);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.weightArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.weightArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glWeightPointerARB_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ log_gl("glWeightPointerARB\n");
+ fflush(get_err_file());
+ if (debug_array_ptr)
+ log_gl("weightArray size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr);
+ state->client_state.arrays.weightArray.size = size;
+ state->client_state.arrays.weightArray.type = type;
+ state->client_state.arrays.weightArray.stride = stride;
+ state->client_state.arrays.weightArray.ptr = ptr;
+}
+
+
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ CHECK_PROC(glMatrixIndexPointerARB);
+ GET_CURRENT_STATE();
+
+ state->client_state.arrays.matrixIndexArray.vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.matrixIndexArray.vbo_name)
+ {
+ long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glMatrixIndexPointerARB_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ log_gl("glMatrixIndexPointerARB\n");
+ fflush(get_err_file());
+ if (debug_array_ptr)
+ log_gl("matrixIndexArray size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr);
+ state->client_state.arrays.matrixIndexArray.size = size;
+ state->client_state.arrays.matrixIndexArray.type = type;
+ state->client_state.arrays.matrixIndexArray.stride = stride;
+ state->client_state.arrays.matrixIndexArray.ptr = ptr;
+}
+
+#define glMatrixIndexvARB(name, type) \
+GLAPI void APIENTRY name (GLint size, const type *indices) \
+{ \
+ CHECK_PROC(name); \
+ long args[] = { INT_TO_ARG(size), POINTER_TO_ARG(indices) }; \
+ int args_size[] = { 0, size * sizeof(type) }; \
+ do_opengl_call(CONCAT(name, _func), NULL, CHECK_ARGS(args, args_size)); \
+}
+
+glMatrixIndexvARB(glMatrixIndexubvARB, GLubyte);
+glMatrixIndexvARB(glMatrixIndexusvARB, GLushort);
+glMatrixIndexvARB(glMatrixIndexuivARB, GLuint);
+
+
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight)
+{
+ log_gl("glVertexWeightfEXT : deprecated API. unimplemented\n");
+}
+
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight)
+{
+ log_gl("glVertexWeightfvEXT : deprecated API. unimplemented\n");
+}
+
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ log_gl("glVertexWeightPointerEXT : deprecated API. unimplemented\n");
+}
+
+
+
+GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointerARB)(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const GLvoid *ptr)
+{
+ CHECK_PROC(glVertexAttribPointerARB);
+
+ GET_CURRENT_STATE();
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ state->client_state.arrays.vertexAttribArray[index].vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.vertexAttribArray[index].vbo_name)
+ {
+ long args[] = { INT_TO_ARG(index), INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(normalized), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glVertexAttribPointerARB_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (debug_array_ptr)
+ log_gl("glVertexAttribPointerARB[%d] size=%d type=%d normalized=%d stride=%d ptr=%p\n",
+ index, size, type, normalized, stride, ptr);
+ state->client_state.arrays.vertexAttribArray[index].index = index;
+ state->client_state.arrays.vertexAttribArray[index].size = size;
+ state->client_state.arrays.vertexAttribArray[index].type = type;
+ state->client_state.arrays.vertexAttribArray[index].normalized = normalized;
+ state->client_state.arrays.vertexAttribArray[index].stride = stride;
+ state->client_state.arrays.vertexAttribArray[index].ptr = ptr;
+ }
+ else
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "3",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointer)(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const GLvoid *ptr)
+{
+ glVertexAttribPointerARB(index, size, type, normalized, stride, ptr);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointerNV)(GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const GLvoid *ptr)
+{
+ CHECK_PROC(glVertexAttribPointerNV);
+
+ GET_CURRENT_STATE();
+ if (index < MY_GL_MAX_VERTEX_ATTRIBS_NV)
+ {
+ if (debug_array_ptr)
+ log_gl("glVertexAttribPointerNV[%d] size=%d type=%d stride=%d ptr=%p\n",
+ index, size, type, stride, ptr);
+ state->client_state.arrays.vertexAttribArrayNV[index].index = index;
+ state->client_state.arrays.vertexAttribArrayNV[index].size = size;
+ state->client_state.arrays.vertexAttribArrayNV[index].type = type;
+ state->client_state.arrays.vertexAttribArrayNV[index].stride = stride;
+ state->client_state.arrays.vertexAttribArrayNV[index].ptr = ptr;
+ }
+ else
+ {
+ log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_NV\n");
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glElementPointerATI) (GLenum type, const GLvoid * ptr)
+{
+ CHECK_PROC(glElementPointerATI);
+ GET_CURRENT_STATE();
+ state->client_state.arrays.elementArrayATI.size = 1;
+ state->client_state.arrays.elementArrayATI.type = type;
+ state->client_state.arrays.elementArrayATI.stride = 0;
+ state->client_state.arrays.elementArrayATI.ptr = ptr;
+}
+
+GLAPI void APIENTRY glGetPointerv( GLenum pname, void **params )
+{
+ GET_CURRENT_STATE();
+ switch (pname)
+ {
+ case GL_COLOR_ARRAY_POINTER: *params = (void*)state->client_state.arrays.colorArray.ptr; break;
+ case GL_SECONDARY_COLOR_ARRAY_POINTER: *params = (void*)state->client_state.arrays.secondaryColorArray.ptr; break;
+ case GL_NORMAL_ARRAY_POINTER: *params = (void*)state->client_state.arrays.normalArray.ptr; break;
+ case GL_INDEX_ARRAY_POINTER: *params = (void*)state->client_state.arrays.indexArray.ptr; break;
+ case GL_TEXTURE_COORD_ARRAY_POINTER: *params = (void*)state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr; break;
+ case GL_VERTEX_ARRAY_POINTER: *params = (void*)state->client_state.arrays.vertexArray.ptr; break;
+ case GL_EDGE_FLAG_ARRAY_POINTER: *params = (void*)state->client_state.arrays.edgeFlagArray.ptr; break;
+ case GL_WEIGHT_ARRAY_POINTER_ARB: *params = (void*)state->client_state.arrays.weightArray.ptr; break;
+ case GL_MATRIX_INDEX_ARRAY_POINTER_ARB: *params = (void*)state->client_state.arrays.matrixIndexArray.ptr; break;
+ case GL_FOG_COORD_ARRAY_POINTER: *params = (void*)state->client_state.arrays.fogCoordArray.ptr; break;
+ case GL_ELEMENT_ARRAY_POINTER_ATI: *params = (void*)state->client_state.arrays.elementArrayATI.ptr; break;
+ case GL_SELECTION_BUFFER_POINTER: *params = (void*)state->client_state.selectBufferPtr; break;
+ case GL_FEEDBACK_BUFFER_POINTER: *params = (void*)state->client_state.feedbackBufferPtr; break;
+ default:
+ {
+ log_gl("not yet handled pname %d\n", pname);
+ *params = NULL;
+ }
+ }
+}
+
+GLAPI void APIENTRY glGetPointervEXT( GLenum pname, void **params )
+{
+ glFuncTable.fpGetPointerv(pname, params);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointervARB)(GLuint index,
+ GLenum pname,
+ GLvoid **pointer)
+{
+ GET_CURRENT_STATE();
+
+ if (index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ "4",
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB:
+ {
+ *pointer = (void*)state->client_state.arrays.vertexAttribArray[index].ptr;
+ break;
+ }
+ default:
+ log_gl("glGetVertexAttribPointervARB : bad pname=0x%X", pname);
+ break;
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointerv)(GLuint index,
+ GLenum pname,
+ GLvoid **pointer)
+{
+ glGetVertexAttribPointervARB(index, pname, pointer);
+}
+
+GLAPI void APIENTRY EXT_FUNC(_glGetVertexAttribiv)(int func_number, GLuint index, GLenum pname, GLint *params)
+{
+ if (index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB)
+ {
+ log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB. (index = %d; MAX=%d)\n",
+ tab_opengl_calls_name[func_number],
+ index, MY_GL_MAX_VERTEX_ATTRIBS_ARB);
+ return;
+ }
+
+ GET_CURRENT_STATE();
+ switch (pname)
+ {
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].size;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].stride;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].type;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].normalized;
+ break;
+ case GL_CURRENT_VERTEX_ATTRIB_ARB:
+ *params = state->client_state.arrays.vertexAttribArray[index].vbo_name;
+ break;
+ default:
+ log_gl("%s : bad pname=0x%X", tab_opengl_calls_name[func_number], pname);
+ break;
+ }
+}
+
+#define DEFINE_glGetVertexAttribv(funcName, type) \
+GLAPI void APIENTRY EXT_FUNC(funcName)(GLuint index, GLenum pname, type *params) \
+{ \
+ CHECK_PROC(funcName); \
+ if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) \
+ { \
+ long args[] = { UNSIGNED_INT_TO_ARG(index), UNSIGNED_INT_TO_ARG(pname), POINTER_TO_ARG(params)}; \
+ do_opengl_call(CONCAT(funcName,_func), NULL, args, NULL); \
+ return; \
+ } \
+ int i_params; \
+ _glGetVertexAttribiv(CONCAT(funcName,_func), index, pname, &i_params); \
+ *params = i_params; \
+}
+
+DEFINE_glGetVertexAttribv(glGetVertexAttribivARB, GLint);
+DEFINE_glGetVertexAttribv(glGetVertexAttribiv, GLint);
+DEFINE_glGetVertexAttribv(glGetVertexAttribfvARB, GLfloat);
+DEFINE_glGetVertexAttribv(glGetVertexAttribfv, GLfloat);
+DEFINE_glGetVertexAttribv(glGetVertexAttribdvARB, GLdouble);
+DEFINE_glGetVertexAttribv(glGetVertexAttribdv, GLdouble);
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointervNV)(GLuint index,
+ GLenum pname,
+ GLvoid **pointer)
+{
+ CHECK_PROC(glGetVertexAttribPointervNV);
+ GET_CURRENT_STATE();
+ if (index >= MY_GL_MAX_VERTEX_ATTRIBS_NV)
+ {
+ log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_NV\n");
+ return;
+ }
+ switch (pname)
+ {
+ case GL_ATTRIB_ARRAY_POINTER_NV:
+ {
+ *pointer = (void*)state->client_state.arrays.vertexAttribArrayNV[index].ptr;
+ break;
+ }
+ default:
+ log_gl("glGetVertexAttribPointervNV : bad pname=0x%X", pname);
+ break;
+ }
+}
+
+static int getGlTypeByteSize(int type)
+{
+ switch(type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ break;
+
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ return 2;
+ break;
+
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return 4;
+ break;
+
+ case GL_DOUBLE:
+ return 8;
+ break;
+
+ default:
+ log_gl("unsupported type = %d\n", type);
+ return 0;
+ }
+}
+
+static int getMulFactorFromPointerArray(ClientArray* array)
+{
+ if (array->stride)
+ return array->stride;
+
+ return getGlTypeByteSize(array->type) * array->size;
+}
+
+
+static void _glArraySend(GLState* state, const char* func_name, int func, ClientArray* array, int first, int last)
+{
+ if (array->ptr == NULL || array->vbo_name || array->enabled == 0) return;
+ int offset = first * getMulFactorFromPointerArray(array);
+ int size = (last - first + 1) * getMulFactorFromPointerArray(array);
+ if (size == 0) return;
+
+ int currentArrayBuffer = state->arrayBuffer;
+ if (currentArrayBuffer)
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
+ switch(func)
+ {
+ case glEdgeFlagPointer_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ case glNormalPointer_fake_func:
+ case glIndexPointer_fake_func:
+ case glFogCoordPointer_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->type),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ case glVertexPointer_fake_func:
+ case glColorPointer_fake_func:
+ case glSecondaryColorPointer_fake_func:
+ case glWeightPointerARB_fake_func:
+ case glMatrixIndexPointerARB_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->size),
+ INT_TO_ARG(array->type),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ case glTexCoordPointer_fake_func:
+ case glVertexAttribPointerNV_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->index),
+ INT_TO_ARG(array->size),
+ INT_TO_ARG(array->type),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ case glVertexAttribPointerARB_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->index),
+ INT_TO_ARG(array->size),
+ INT_TO_ARG(array->type),
+ INT_TO_ARG(array->normalized),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ case glVariantPointerEXT_fake_func:
+ {
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(array->index),
+ INT_TO_ARG(array->type),
+ INT_TO_ARG(array->stride),
+ INT_TO_ARG(size),
+ POINTER_TO_ARG(array->ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, size};
+ do_opengl_call(func, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+
+ default:
+ log_gl("shoudln't reach that point\n");
+ break;
+ }
+
+ if (currentArrayBuffer)
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, currentArrayBuffer);
+ }
+}
+
+
+#define ARRAY_SEND_FUNC(x) #x, CONCAT(x,_fake_func)
+
+static int _calc_interleaved_arrays_stride(GLenum format)
+{
+ switch(format)
+ {
+ case GL_V2F: return 2 * sizeof(float); break;
+ case GL_V3F: return 3 * sizeof(float); break;
+ case GL_C4UB_V2F: return 4 * sizeof(char) + 2 * sizeof(float); break;
+ case GL_C4UB_V3F: return 4 * sizeof(char) + 3 * sizeof(float); break;
+ case GL_C3F_V3F: return 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_N3F_V3F: return 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_C4F_N3F_V3F: return 4 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_T2F_V3F: return 2 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_T4F_V4F: return 4 * sizeof(float) + 4 * sizeof(float); break;
+ case GL_T2F_C4UB_V3F: return 2 * sizeof(float) + 4 * sizeof(char) + 3 * sizeof(float); break;
+ case GL_T2F_C3F_V3F: return 2 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_T2F_N3F_V3F: return 2 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_T2F_C4F_N3F_V3F: return 2 * sizeof(float) + 4 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break;
+ case GL_T4F_C4F_N3F_V4F: return 4 * sizeof(float) + 4 * sizeof(float) + 3 * sizeof(float) + 4 * sizeof(float); break;
+ default: log_gl("unknown interleaved array format : %d\n", format); return 0;
+ }
+}
+
+enum
+{
+ TEXCOORD_FUNC,
+ COLOR_FUNC,
+ NORMAL_FUNC,
+ INDEX_FUNC,
+ VERTEX_FUNC
+};
+
+typedef void (*vector_func_type)(const void*);
+
+typedef struct
+{
+ int type;
+ int size;
+ int typeFunc;
+ vector_func_type vector_func;
+} VectorFuncStruct;
+
+VectorFuncStruct vectorFuncArray[] =
+{
+ { GL_DOUBLE, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1dv },
+ { GL_DOUBLE, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2dv },
+ { GL_DOUBLE, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3dv },
+ { GL_DOUBLE, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4dv },
+ { GL_FLOAT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1fv },
+ { GL_FLOAT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2fv },
+ { GL_FLOAT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3fv },
+ { GL_FLOAT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4fv },
+ { GL_INT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1iv },
+ { GL_INT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2iv },
+ { GL_INT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3iv },
+ { GL_INT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4iv },
+ { GL_SHORT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1sv },
+ { GL_SHORT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2sv },
+ { GL_SHORT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3sv },
+ { GL_SHORT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4sv },
+
+ { GL_BYTE, 3, COLOR_FUNC, (vector_func_type)glColor3bv },
+ { GL_DOUBLE, 3, COLOR_FUNC, (vector_func_type)glColor3dv },
+ { GL_FLOAT, 3, COLOR_FUNC, (vector_func_type)glColor3fv },
+ { GL_INT, 3, COLOR_FUNC, (vector_func_type)glColor3iv },
+ { GL_SHORT, 3, COLOR_FUNC, (vector_func_type)glColor3sv },
+ { GL_UNSIGNED_BYTE, 3, COLOR_FUNC, (vector_func_type)glColor3ubv },
+ { GL_UNSIGNED_INT, 3, COLOR_FUNC, (vector_func_type)glColor3uiv },
+ { GL_UNSIGNED_SHORT, 3, COLOR_FUNC, (vector_func_type)glColor3usv },
+ { GL_BYTE, 4, COLOR_FUNC, (vector_func_type)glColor4bv },
+ { GL_DOUBLE, 4, COLOR_FUNC, (vector_func_type)glColor4dv },
+ { GL_FLOAT, 4, COLOR_FUNC, (vector_func_type)glColor4fv },
+ { GL_INT, 4, COLOR_FUNC, (vector_func_type)glColor4iv },
+ { GL_SHORT, 4, COLOR_FUNC, (vector_func_type)glColor4sv },
+ { GL_UNSIGNED_BYTE, 4, COLOR_FUNC, (vector_func_type)glColor4ubv },
+ { GL_UNSIGNED_INT, 4, COLOR_FUNC, (vector_func_type)glColor4uiv },
+ { GL_UNSIGNED_SHORT, 4, COLOR_FUNC, (vector_func_type)glColor4usv },
+
+ { GL_BYTE, 3, NORMAL_FUNC, (vector_func_type)glNormal3bv },
+ { GL_DOUBLE, 3, NORMAL_FUNC, (vector_func_type)glNormal3dv },
+ { GL_FLOAT, 3, NORMAL_FUNC, (vector_func_type)glNormal3fv },
+ { GL_INT, 3, NORMAL_FUNC, (vector_func_type)glNormal3iv },
+ { GL_SHORT, 3, NORMAL_FUNC, (vector_func_type)glNormal3sv },
+
+ { GL_DOUBLE, 1, INDEX_FUNC, (vector_func_type)glIndexdv },
+ { GL_FLOAT, 1, INDEX_FUNC, (vector_func_type)glIndexfv },
+ { GL_INT, 1, INDEX_FUNC, (vector_func_type)glIndexiv },
+ { GL_SHORT, 1, INDEX_FUNC, (vector_func_type)glIndexsv },
+ { GL_UNSIGNED_BYTE, 1, INDEX_FUNC, (vector_func_type)glIndexubv },
+
+ { GL_DOUBLE, 2, VERTEX_FUNC, (vector_func_type)glVertex2dv },
+ { GL_FLOAT, 2, VERTEX_FUNC, (vector_func_type)glVertex2fv },
+ { GL_INT, 2, VERTEX_FUNC, (vector_func_type)glVertex2iv },
+ { GL_SHORT, 2, VERTEX_FUNC, (vector_func_type)glVertex2sv },
+ { GL_DOUBLE, 3, VERTEX_FUNC, (vector_func_type)glVertex3dv },
+ { GL_FLOAT, 3, VERTEX_FUNC, (vector_func_type)glVertex3fv },
+ { GL_INT, 3, VERTEX_FUNC, (vector_func_type)glVertex3iv },
+ { GL_SHORT, 4, VERTEX_FUNC, (vector_func_type)glVertex4sv },
+ { GL_DOUBLE, 4, VERTEX_FUNC, (vector_func_type)glVertex4dv },
+ { GL_FLOAT, 4, VERTEX_FUNC, (vector_func_type)glVertex4fv },
+ { GL_INT, 4, VERTEX_FUNC, (vector_func_type)glVertex4iv },
+ { GL_SHORT, 4, VERTEX_FUNC, (vector_func_type)glVertex4sv },
+};
+
+static vector_func_type _get_vector_func(int type, int size, int typeFunc)
+{
+ int i;
+ for(i=0;i<sizeof(vectorFuncArray)/sizeof(vectorFuncArray[0]);i++)
+ {
+ if (vectorFuncArray[i].type == type &&
+ vectorFuncArray[i].size == size &&
+ vectorFuncArray[i].typeFunc == typeFunc)
+ return vectorFuncArray[i].vector_func;
+ }
+ log_gl("can't find vector_func(type=%X, size=%d, typeFunc=%d)\n", type, size, typeFunc);
+ return NULL;
+}
+
+static void _glElementArrayImmediate_one(ClientArray* array, int indice, int typeFunc)
+{
+ if (array->enabled)
+ {
+ vector_func_type vector_func =
+ _get_vector_func(array->type, array->size, typeFunc);
+ if (vector_func)
+ {
+ vector_func(array->ptr + getMulFactorFromPointerArray(array) * indice);
+ }
+ }
+}
+
+static void _glElementArrayImmediate(int indice)
+{
+ GET_CURRENT_STATE();
+
+ if (state->client_state.arrays.interleavedArrays.ptr != NULL &&
+ state->client_state.arrays.vertexArray.ptr == NULL)
+ {
+ GLboolean tflag, cflag, nflag; /* enable/disable flags */
+ GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
+ GLenum ctype = 0; /* color type */
+ GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
+ const GLint toffset = 0; /* always zero */
+ GLint defstride; /* default stride */
+ GLint c, f;
+
+ int stride = state->client_state.arrays.interleavedArrays.stride;
+
+ f = sizeof(GLfloat);
+ c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
+
+ switch (state->client_state.arrays.interleavedArrays.format) {
+ case GL_V2F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 0; vcomps = 2;
+ voffset = 0;
+ defstride = 2*f;
+ break;
+ case GL_V3F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 0; vcomps = 3;
+ voffset = 0;
+ defstride = 3*f;
+ break;
+ case GL_C4UB_V2F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 4; vcomps = 2;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 0;
+ voffset = c;
+ defstride = c + 2*f;
+ break;
+ case GL_C4UB_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 4; vcomps = 3;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 0;
+ voffset = c;
+ defstride = c + 3*f;
+ break;
+ case GL_C3F_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 3; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 0;
+ voffset = 3*f;
+ defstride = 6*f;
+ break;
+ case GL_N3F_V3F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
+ tcomps = 0; ccomps = 0; vcomps = 3;
+ noffset = 0;
+ voffset = 3*f;
+ defstride = 6*f;
+ break;
+ case GL_C4F_N3F_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 0; ccomps = 4; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 0;
+ noffset = 4*f;
+ voffset = 7*f;
+ defstride = 10*f;
+ break;
+ case GL_T2F_V3F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 0; vcomps = 3;
+ voffset = 2*f;
+ defstride = 5*f;
+ break;
+ case GL_T4F_V4F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 4; ccomps = 0; vcomps = 4;
+ voffset = 4*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_C4UB_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 4; vcomps = 3;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 2*f;
+ voffset = c+2*f;
+ defstride = c+5*f;
+ break;
+ case GL_T2F_C3F_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 3; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 2*f;
+ voffset = 5*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_N3F_V3F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
+ tcomps = 2; ccomps = 0; vcomps = 3;
+ noffset = 2*f;
+ voffset = 5*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_C4F_N3F_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 2; ccomps = 4; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 2*f;
+ noffset = 6*f;
+ voffset = 9*f;
+ defstride = 12*f;
+ break;
+ case GL_T4F_C4F_N3F_V4F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 4; ccomps = 4; vcomps = 4;
+ ctype = GL_FLOAT;
+ coffset = 4*f;
+ noffset = 8*f;
+ voffset = 11*f;
+ defstride = 15*f;
+ break;
+ default:
+ log_gl("unknown interleaved array format : %d\n", state->client_state.arrays.interleavedArrays.format);
+ return;
+ }
+ if (stride==0) {
+ stride = defstride;
+ }
+
+ const void* ptr = state->client_state.arrays.interleavedArrays.ptr + indice * stride;
+
+ if (tflag)
+ {
+ if (tcomps == 2)
+ glTexCoord2fv(ptr + toffset);
+ else if (tcomps == 4)
+ glTexCoord4fv(ptr + toffset);
+ else
+ assert(0);
+ }
+
+ if (cflag)
+ {
+ if (ctype == GL_FLOAT)
+ {
+ if (ccomps == 3)
+ glColor3fv(ptr + coffset);
+ else if (ccomps == 4)
+ glColor4fv(ptr + coffset);
+ else
+ assert(0);
+ }
+ else if (ctype == GL_UNSIGNED_BYTE)
+ {
+ if (ccomps == 4)
+ glColor4ubv(ptr + coffset);
+ else
+ assert(0);
+ }
+ else
+ assert(0);
+ }
+
+ if (nflag)
+ glNormal3fv(ptr + noffset);
+
+ if (vcomps == 2)
+ glVertex2fv(ptr + voffset);
+ else if (vcomps == 3)
+ glVertex3fv(ptr + voffset);
+ else if (vcomps == 4)
+ glVertex4fv(ptr + voffset);
+ else
+ assert(0);
+
+ return;
+ }
+ int i;
+
+ int prevActiveTexture = state->activeTexture;
+ for(i=0;i<NB_MAX_TEXTURES;i++)
+ {
+ if (state->client_state.arrays.texCoordArray[i].enabled)
+ {
+ if (i != 0 || state->activeTexture != GL_TEXTURE0_ARB)
+ glActiveTextureARB(GL_TEXTURE0_ARB + i);
+ _glElementArrayImmediate_one(&state->client_state.arrays.texCoordArray[i], indice, TEXCOORD_FUNC);
+ }
+ }
+ glActiveTextureARB(prevActiveTexture);
+
+ _glElementArrayImmediate_one(&state->client_state.arrays.normalArray, indice, NORMAL_FUNC);
+ _glElementArrayImmediate_one(&state->client_state.arrays.colorArray, indice, COLOR_FUNC);
+ _glElementArrayImmediate_one(&state->client_state.arrays.indexArray, indice, INDEX_FUNC);
+ _glElementArrayImmediate_one(&state->client_state.arrays.vertexArray, indice, VERTEX_FUNC);
+}
+
+static void _glArraysSend(int first, int last)
+{
+ GET_CURRENT_STATE();
+ if (debug_array_ptr)
+ {
+ log_gl("_glArraysSend from %d to %d\n", first, last);
+ }
+
+
+ int startIndiceTextureToDealtWith = 0;
+ int i;
+ int nbElts = 1 + last;
+
+ if (glFuncTable.fpIsEnabled(GL_VERTEX_PROGRAM_NV))
+ {
+ int vertexProgramNV = 0;
+ for(i=0;i<MY_GL_MAX_VERTEX_ATTRIBS_NV;i++)
+ {
+ ClientArray* array = &state->client_state.arrays.vertexAttribArrayNV[i];
+ if (!(array->ptr == NULL || array->enabled == 0))
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glVertexAttribPointerNV), array, first, last);
+ vertexProgramNV = 1;
+ }
+ }
+ if (vertexProgramNV)
+ return;
+ }
+
+ if (state->client_state.arrays.interleavedArrays.ptr != NULL &&
+ state->client_state.arrays.vertexArray.ptr == NULL)
+ {
+ int stride;
+ if (state->client_state.arrays.interleavedArrays.stride)
+ stride = state->client_state.arrays.interleavedArrays.stride;
+ else
+ stride = _calc_interleaved_arrays_stride(state->client_state.arrays.interleavedArrays.format);
+ if (stride == 0) return;
+ int offset = stride * first;
+ int size = (last - first + 1) * stride;
+ long args[] = { offset,
+ state->client_state.arrays.interleavedArrays.format,
+ state->client_state.arrays.interleavedArrays.stride,
+ size,
+ POINTER_TO_ARG(state->client_state.arrays.interleavedArrays.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, size };
+ do_opengl_call(glInterleavedArrays_fake_func, NULL, CHECK_ARGS(args, args_size));
+ return;
+ }
+ int normalArrayOffset = (long)state->client_state.arrays.normalArray.ptr -
+ (long)state->client_state.arrays.vertexArray.ptr;
+ int colorArrayOffset = (long)state->client_state.arrays.colorArray.ptr -
+ (long)state->client_state.arrays.vertexArray.ptr;
+ int texCoord0PointerOffset = (long)state->client_state.arrays.texCoordArray[0].ptr -
+ (long)state->client_state.arrays.vertexArray.ptr;
+ int texCoord1PointerOffset = (long)state->client_state.arrays.texCoordArray[1].ptr -
+ (long)state->client_state.arrays.vertexArray.ptr;
+ int texCoord2PointerOffset = (long)state->client_state.arrays.texCoordArray[2].ptr -
+ (long)state->client_state.arrays.vertexArray.ptr;
+
+ if (state->client_state.arrays.vertexArray.vbo_name ||
+ state->client_state.arrays.colorArray.vbo_name ||
+ state->client_state.arrays.normalArray.vbo_name ||
+ state->client_state.arrays.texCoordArray[0].vbo_name ||
+ state->client_state.arrays.texCoordArray[1].vbo_name ||
+ state->client_state.arrays.texCoordArray[2].vbo_name)
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glVertexPointer), &state->client_state.arrays.vertexArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glNormalPointer), &state->client_state.arrays.normalArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last);
+ }
+ else
+ if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled == 0 &&
+ state->client_state.arrays.colorArray.enabled &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexColorTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(colorArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.colorArray.size),
+ INT_TO_ARG(state->client_state.arrays.colorArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexColorTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 1;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.texCoordArray[2].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[2].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord1PointerOffset >= 0 &&
+ texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord2PointerOffset >= 0 &&
+ texCoord2PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 4 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalColorTexCoord012PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(colorArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.colorArray.size),
+ INT_TO_ARG(state->client_state.arrays.colorArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(texCoord1PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type),
+ INT_TO_ARG(texCoord2PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[2].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[2].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalColorTexCoord012PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 3;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord1PointerOffset >= 0 &&
+ texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalColorTexCoord01PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(colorArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.colorArray.size),
+ INT_TO_ARG(state->client_state.arrays.colorArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(texCoord1PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalColorTexCoord01PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 2;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled == 0 &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.texCoordArray[2].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[2].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord1PointerOffset >= 0 &&
+ texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord2PointerOffset >= 0 &&
+ texCoord2PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalTexCoord012PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(texCoord1PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type),
+ INT_TO_ARG(texCoord2PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[2].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[2].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalTexCoord012PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 3;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled == 0 &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord1PointerOffset >= 0 &&
+ texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalTexCoord01PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(texCoord1PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalTexCoord01PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 2;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled == 0 &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 1;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.colorArray.enabled &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ texCoord0PointerOffset >= 0 &&
+ texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalColorTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(colorArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.colorArray.size),
+ INT_TO_ARG(state->client_state.arrays.colorArray.type),
+ INT_TO_ARG(texCoord0PointerOffset),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalColorTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 1;
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ getMulFactorFromPointerArray(&state->client_state.arrays.vertexArray) ==
+ getMulFactorFromPointerArray(&state->client_state.arrays.normalArray) &&
+ state->client_state.arrays.vertexArray.ptr == state->client_state.arrays.normalArray.ptr)
+ {
+ /* Special optimization for earth3d */
+ int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.vertexArray);
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexAndNormalPointer_fake_func sending %d bytes from %d\n",
+ data_size,
+ 0);
+ }
+
+ long args[] = { INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(state->client_state.arrays.normalArray.stride),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, data_size };
+ do_opengl_call(glVertexAndNormalPointer_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ /*state->client_state.arrays.colorArray.enabled && */
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* Special optimization for tuxracer */
+ /*
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer( 3, GL_FLOAT, STRIDE_GL_ARRAY, vnc_array );
+
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer( GL_FLOAT, STRIDE_GL_ARRAY,
+ vnc_array + 4*sizeof(GLfloat) );
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer( 4, GL_UNSIGNED_BYTE, STRIDE_GL_ARRAY,
+ vnc_array + 8*sizeof(GLfloat) );
+ */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalColorPointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(colorArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.colorArray.size),
+ INT_TO_ARG(state->client_state.arrays.colorArray.type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ data_size};
+ do_opengl_call(glVertexNormalColorPointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+ else if (state->client_state.arrays.vertexArray.enabled &&
+ state->client_state.arrays.normalArray.enabled &&
+ state->client_state.arrays.vertexArray.ptr != NULL &&
+ state->client_state.arrays.vertexArray.stride != 0 &&
+ state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < state->client_state.arrays.vertexArray.stride)
+ {
+ /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int offset = first * state->client_state.arrays.vertexArray.stride;
+ int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride;
+
+ if (debug_array_ptr)
+ {
+ log_gl("glVertexNormalPointerInterlaced_fake_func sending %d bytes from %d\n",
+ data_size,
+ offset);
+ }
+ long args[] = { INT_TO_ARG(offset),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.size),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.type),
+ INT_TO_ARG(state->client_state.arrays.vertexArray.stride),
+ INT_TO_ARG(normalArrayOffset),
+ INT_TO_ARG(state->client_state.arrays.normalArray.type),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) };
+ int args_size[] = { 0, 0, 0, 0, 0, 0, 0, data_size};
+ do_opengl_call(glVertexNormalPointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last);
+ }
+ else
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glVertexPointer), &state->client_state.arrays.vertexArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glNormalPointer), &state->client_state.arrays.normalArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last);
+ }
+ _glArraySend(state, ARRAY_SEND_FUNC(glSecondaryColorPointer), &state->client_state.arrays.secondaryColorArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glEdgeFlagPointer), &state->client_state.arrays.edgeFlagArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glIndexPointer), &state->client_state.arrays.indexArray, first, last);
+
+ for(i=0;i<MY_GL_MAX_VERTEX_ATTRIBS_ARB;i++)
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glVertexAttribPointerARB), &state->client_state.arrays.vertexAttribArray[i], first, last);
+ }
+ for(i=0;i<MY_GL_MAX_VARIANT_POINTER_EXT;i++)
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glVariantPointerEXT), &state->client_state.arrays.variantPointer[i], first, last);
+ }
+
+ if (startIndiceTextureToDealtWith == 0 &&
+ state->client_state.arrays.texCoordArray[0].vbo_name == 0 &&
+ state->client_state.arrays.texCoordArray[1].vbo_name == 0 &&
+ state->client_state.arrays.texCoordArray[2].vbo_name == 0 &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.texCoordArray[2].enabled &&
+ state->client_state.arrays.texCoordArray[0].ptr &&
+ state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[1].ptr &&
+ state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[1].size &&
+ state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[1].type &&
+ state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[1].stride &&
+ state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[2].ptr &&
+ state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[2].size &&
+ state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[2].type &&
+ state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[2].stride)
+ {
+ /* For unreal tournament 4 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */
+ int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.texCoordArray[0]);
+ if (debug_array_ptr)
+ {
+ log_gl("glTexCoordPointer012_fake_func sending %d bytes from %d\n",
+ data_size,
+ 0);
+ }
+
+ long args[] = { INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].stride),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.texCoordArray[0].ptr) };
+ int args_size[] = { 0, 0, 0, 0, data_size };
+ do_opengl_call(glTexCoordPointer012_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 3;
+ }
+ else
+ if (startIndiceTextureToDealtWith == 0 &&
+ state->client_state.arrays.texCoordArray[0].vbo_name == 0 &&
+ state->client_state.arrays.texCoordArray[1].vbo_name == 0 &&
+ state->client_state.arrays.texCoordArray[0].enabled &&
+ state->client_state.arrays.texCoordArray[1].enabled &&
+ state->client_state.arrays.texCoordArray[0].ptr &&
+ state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[1].ptr &&
+ state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[1].size &&
+ state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[1].type &&
+ state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[1].stride)
+ {
+ /* Special optimization for earth3d */
+ int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.texCoordArray[0]);
+ if (debug_array_ptr)
+ {
+ log_gl("glTexCoordPointer01_fake_func sending %d bytes from %d\n",
+ data_size,
+ 0);
+ }
+
+ long args[] = { INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type),
+ INT_TO_ARG(state->client_state.arrays.texCoordArray[0].stride),
+ INT_TO_ARG(data_size),
+ POINTER_TO_ARG(state->client_state.arrays.texCoordArray[0].ptr) };
+ int args_size[] = { 0, 0, 0, 0, data_size };
+ do_opengl_call(glTexCoordPointer01_fake_func, NULL, CHECK_ARGS(args, args_size));
+
+ startIndiceTextureToDealtWith = 2;
+ }
+
+ for(i=startIndiceTextureToDealtWith;i<NB_MAX_TEXTURES;i++)
+ {
+ _glArraySend(state, ARRAY_SEND_FUNC(glTexCoordPointer), &state->client_state.arrays.texCoordArray[i], first, last);
+ }
+
+ _glArraySend(state, ARRAY_SEND_FUNC(glWeightPointerARB), &state->client_state.arrays.weightArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glMatrixIndexPointerARB), &state->client_state.arrays.matrixIndexArray, first, last);
+ _glArraySend(state, ARRAY_SEND_FUNC(glFogCoordPointer), &state->client_state.arrays.fogCoordArray, first, last);
+}
+
+#define ASSERT_COND(cond, val) do { if (!(val)) { state->lastGlError = val; return; } } while(0)
+#define CLEAR_ERROR_STATE() do { state->lastGlError = 0; } while(0)
+
+
+GLAPI void APIENTRY EXT_FUNC(glLockArraysEXT) (GLint first, GLsizei count)
+{
+ /* Quite difficult to be correctly implemented IMHO for a doubtful performance gain */
+ /* You need to send data for enabled arrays at this moment, but then for */
+ /* the glDrawArrays, glDrawElements, etc... you need to check if enough data has been sent */
+ /* For ex consider the following code :
+ glVertexPointer(.....);
+ glColorPointer(......);
+ glNormalPointer(.....);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glLockArraysEXT(0, 16); (1)
+ glEnableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glDrawArrays(GL_TRIANGLE, 0, 20); (2)
+ glUnlockArraysEXT();
+ */
+ /* At (1), you need to send 16 vertices, but at (2) you need to send the */
+ /* 4 following ones, or either the whole 20... */
+ CHECK_PROC(glLockArraysEXT);
+ GET_CURRENT_STATE();
+ ASSERT_COND(first >= 0, GL_INVALID_VALUE);
+ ASSERT_COND(count > 0, GL_INVALID_VALUE);
+ ASSERT_COND(state->isBetweenLockArrays == 0, GL_INVALID_OPERATION);
+ ASSERT_COND(state->isBetweenBegin == 0, GL_INVALID_OPERATION);
+
+ if (debug_array_ptr)
+ {
+ log_gl("glLockArraysEXT(%d,%d)\n", first, count);
+ }
+
+ state->isBetweenLockArrays = 1;
+
+ state->locked_first = first;
+ state->locked_count = count;
+
+ CLEAR_ERROR_STATE();
+}
+
+GLAPI void APIENTRY EXT_FUNC(glUnlockArraysEXT) ()
+{
+ CHECK_PROC(glUnlockArraysEXT);
+ GET_CURRENT_STATE();
+ ASSERT_COND(state->isBetweenLockArrays == 1, GL_INVALID_OPERATION);
+ ASSERT_COND(state->isBetweenBegin == 0, GL_INVALID_OPERATION);
+
+ if (debug_array_ptr)
+ {
+ log_gl("glUnlockArraysEXT()\n");
+ }
+
+ state->isBetweenLockArrays = 0;
+
+ CLEAR_ERROR_STATE();
+}
+
+GLAPI void APIENTRY glArrayElement( GLint i )
+{
+ Buffer* buffer = _get_buffer(GL_ARRAY_BUFFER_ARB);
+ if (buffer)
+ {
+ long args[] = { INT_TO_ARG(i) };
+ do_opengl_call(glArrayElement_func, NULL, args, NULL);
+ }
+ else
+ {
+ _glElementArrayImmediate(i);
+ }
+}
+
+GLAPI void APIENTRY glDrawArrays( GLenum mode,
+ GLint first,
+ GLsizei count )
+{
+ if (debug_array_ptr) log_gl("glDrawArrays(%d,%d,%d)\n", mode, first, count);
+
+ _glArraysSend(first, first + count - 1);
+
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(first), INT_TO_ARG(count) };
+ do_opengl_call(glDrawArrays_func, NULL, args, NULL);
+}
+
+static int _isTuxRacer(GLState* state)
+{
+ int i;
+ ClientArrays* arrays = &state->client_state.arrays;
+ if (arrays->vertexArray.vbo_name ||
+ arrays->normalArray.vbo_name ||
+ arrays->colorArray.vbo_name ||
+ arrays->vertexArray.enabled == 0 ||
+ arrays->normalArray.enabled == 0)
+ return 0;
+
+ int normalArrayOffset = (long)arrays->normalArray.ptr - (long)arrays->vertexArray.ptr;
+ int colorArrayOffset = (long)arrays->colorArray.ptr - (long)arrays->vertexArray.ptr;
+
+ if (!(arrays->vertexArray.ptr != NULL &&
+ arrays->vertexArray.stride != 0 &&
+ arrays->vertexArray.stride == arrays->normalArray.stride &&
+ arrays->vertexArray.stride == arrays->colorArray.stride &&
+ normalArrayOffset >= 0 &&
+ normalArrayOffset < arrays->vertexArray.stride &&
+ colorArrayOffset >= 0 &&
+ colorArrayOffset < arrays->vertexArray.stride))
+ return 0;
+
+ if (!(arrays->vertexArray.type == GL_FLOAT && arrays->vertexArray.size == 3 &&
+ arrays->normalArray.type == GL_FLOAT &&
+ arrays->colorArray.type == GL_UNSIGNED_BYTE && arrays->colorArray.size == 4))
+ return 0;
+
+ if (arrays->secondaryColorArray.enabled ||
+ arrays->indexArray.enabled ||
+ arrays->edgeFlagArray.enabled ||
+ arrays->weightArray.enabled ||
+ arrays->matrixIndexArray.enabled ||
+ arrays->fogCoordArray.enabled)
+ return 0;
+
+ for(i=0;i<NB_MAX_TEXTURES;i++)
+ {
+ if (arrays->texCoordArray[i].enabled)
+ return 0;
+ }
+ for(i=0;i<MY_GL_MAX_VERTEX_ATTRIBS_ARB;i++)
+ {
+ if (arrays->vertexAttribArray[i].enabled)
+ return 0;
+ }
+ return 1;
+}
+
+static int _check_if_enabled_non_vbo_array()
+{
+ int i;
+ GET_CURRENT_STATE();
+ ClientArrays* arrays = &state->client_state.arrays;
+
+ if (arrays->vertexArray.vbo_name == 0 && arrays->vertexArray.enabled)
+ return 1;
+ if (arrays->normalArray.vbo_name == 0 && arrays->normalArray.enabled)
+ return 1;
+ if (arrays->colorArray.vbo_name == 0 && arrays->colorArray.enabled)
+ return 1;
+ if (arrays->secondaryColorArray.vbo_name == 0 && arrays->secondaryColorArray.enabled)
+ return 1;
+ if (arrays->indexArray.vbo_name == 0 && arrays->indexArray.enabled)
+ return 1;
+ if (arrays->edgeFlagArray.vbo_name == 0 && arrays->edgeFlagArray.enabled)
+ return 1;
+ if (arrays->weightArray.vbo_name == 0 && arrays->weightArray.enabled)
+ return 1;
+ if (arrays->matrixIndexArray.vbo_name == 0 && arrays->matrixIndexArray.enabled)
+ return 1;
+ if (arrays->fogCoordArray.vbo_name == 0 && arrays->fogCoordArray.enabled)
+ return 1;
+ for(i=0;i<NB_MAX_TEXTURES;i++)
+ {
+ if (arrays->texCoordArray[i].vbo_name == 0 && arrays->texCoordArray[i].enabled)
+ return 1;
+ }
+ for(i=0;i<MY_GL_MAX_VERTEX_ATTRIBS_ARB;i++)
+ {
+ if (arrays->vertexAttribArray[i].vbo_name == 0 && arrays->vertexAttribArray[i].enabled)
+ return 1;
+ }
+ for(i=0;i<MY_GL_MAX_VARIANT_POINTER_EXT;i++)
+ {
+ if (arrays->variantPointer[i].vbo_name == 0 && arrays->variantPointer[i].enabled)
+ return 1;
+ }
+
+ return 0;
+}
+
+GLAPI void APIENTRY glDrawElements( GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices )
+{
+ CHECK_PROC(glDrawElements);
+ int i;
+ int size = count;
+ //Buffer* bufferArray;
+ Buffer* bufferElement;
+
+ if (debug_array_ptr) log_gl("glDrawElements(%d,%d,%d,%p)\n", mode, count, type, indices);
+
+ if (count == 0) return;
+
+ //bufferArray = _get_buffer(GL_ARRAY_BUFFER_ARB);
+ bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ if (bufferElement)
+ {
+ if (_check_if_enabled_non_vbo_array())
+ {
+ log_gl("sorry : unsupported : glDrawElements in EBO with a non VBO array enabled\n");
+ return;
+ }
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) };
+ do_opengl_call(_glDrawElements_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+
+ int minIndice = 0;
+ int maxIndice = -1;
+
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ //if (!bufferArray)
+ {
+ unsigned char* tab_indices = (unsigned char*)indices;
+ minIndice = tab_indices[0];
+ maxIndice = tab_indices[0];
+ for(i=1;i<count;i++)
+ {
+ if (tab_indices[i] < minIndice) minIndice = tab_indices[i];
+ if (tab_indices[i] > maxIndice) maxIndice = tab_indices[i];
+ }
+ }
+ break;
+ }
+
+ case GL_UNSIGNED_SHORT:
+ {
+ size *= 2;
+ //if (!bufferArray)
+ {
+ unsigned short* tab_indices = (unsigned short*)indices;
+ minIndice = tab_indices[0];
+ maxIndice = tab_indices[0];
+ for(i=1;i<count;i++)
+ {
+ if (tab_indices[i] < minIndice) minIndice = tab_indices[i];
+ if (tab_indices[i] > maxIndice) maxIndice = tab_indices[i];
+ }
+ }
+ break;
+ }
+
+ case GL_UNSIGNED_INT:
+ {
+ size *= 4;
+ //if (!bufferArray)
+ {
+ unsigned int* tab_indices = (unsigned int*)indices;
+ minIndice = tab_indices[0];
+ maxIndice = tab_indices[0];
+ for(i=1;i<count;i++)
+ {
+ if (tab_indices[i] < minIndice) minIndice = tab_indices[i];
+ if (tab_indices[i] > maxIndice) maxIndice = tab_indices[i];
+ }
+ //log_gl("maxIndice = %d\n", maxIndice);
+ if (maxIndice > 100 * 1024 * 1024)
+ {
+ log_gl("too big indice : %d\n",maxIndice);
+ return;
+ }
+ }
+ break;
+ }
+
+ default:
+ log_gl("unsupported type = %d\n", type);
+ return;
+ }
+
+ GET_CURRENT_STATE();
+ if (_isTuxRacer(state) && type == GL_UNSIGNED_INT)
+ {
+ /* Special optimization for tuxracer */
+ /*
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer( 3, GL_FLOAT, STRIDE_GL_ARRAY, vnc_array );
+
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer( GL_FLOAT, STRIDE_GL_ARRAY,
+ vnc_array + 4*sizeof(GLfloat) );
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer( 4, GL_UNSIGNED_BYTE, STRIDE_GL_ARRAY,
+ vnc_array + 8*sizeof(GLfloat) );
+ */
+ ClientArrays* arrays = &state->client_state.arrays;
+ int stride = arrays->vertexArray.stride;
+ int bufferSize = (maxIndice - minIndice + 1) * stride + sizeof(int) * count;
+ int eltSize = 6 * sizeof(float) + ((arrays->colorArray.enabled) ? 4 * sizeof(unsigned char) : 0);
+ int singleCommandSize = count * eltSize;
+ if (count < bufferSize)
+ {
+ unsigned int* tab_indices = (unsigned int*)indices;
+ const char* vertexArray = (const char*)arrays->vertexArray.ptr;
+ int normalArrayOffset = (long)arrays->normalArray.ptr - (long)arrays->vertexArray.ptr;
+ int colorArrayOffset = (long)arrays->colorArray.ptr - (long)arrays->vertexArray.ptr;
+ state->tuxRacerBuffer = realloc(state->tuxRacerBuffer, singleCommandSize);
+
+ for(i=0;i<count;i++)
+ {
+ int ind = tab_indices[i];
+ memcpy(&state->tuxRacerBuffer[i * eltSize], &vertexArray[ind * stride], 3 * sizeof(float));
+ memcpy(&state->tuxRacerBuffer[i * eltSize + 3 * sizeof(float)],
+ &vertexArray[ind * stride + normalArrayOffset], 3 * sizeof(float));
+ if (arrays->colorArray.enabled)
+ memcpy(&state->tuxRacerBuffer[i * eltSize + 6 * sizeof(float)],
+ &vertexArray[ind * stride + colorArrayOffset], 4 * sizeof(unsigned char));
+ }
+
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(arrays->colorArray.enabled), POINTER_TO_ARG(state->tuxRacerBuffer) };
+ int args_size[] = { 0, 0, 0, singleCommandSize} ;
+ do_opengl_call(glTuxRacerDrawElements_fake_func, NULL, CHECK_ARGS(args, args_size));
+ return;
+ }
+ }
+ _glArraysSend(minIndice, maxIndice);
+
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) };
+ int args_size[] = { 0, 0, 0, (indices) ? size : 0 } ;
+ do_opengl_call(glDrawElements_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glDrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices )
+{
+ CHECK_PROC(glDrawRangeElements);
+ int size = count;
+ Buffer* bufferElement;
+
+ if (debug_array_ptr) log_gl("glDrawRangeElements(0x%X, %d, %d, %d, %d, %p)\n", mode, start, end, count, type, indices);
+
+ if (count == 0) return;
+
+ /* Yes : try to send regular arrays even if GL_ELEMENT_ARRAY_BUFFER_ARB is enabled.
+ This is necessary for nexuiz 2.3 where in GL_ELEMENT_ARRAY_BUFFER_ARB some arrays are regular array pointers,
+ and some others are stored in VBO... */
+ _glArraysSend(start, end);
+
+ bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ if (bufferElement)
+ {
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) };
+ do_opengl_call(_glDrawRangeElements_buffer_func, NULL, args, NULL);
+ return;
+ }
+#if 0
+ int i;
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ unsigned char* tab_indices = (unsigned char*)indices;
+ for(i=0;i<count;i++)
+ {
+ if (tab_indices[i] < start || tab_indices[i] > end)
+ {
+ log_gl("indice out of bounds at offset %d\n", i);
+ }
+ }
+ break;
+ }
+
+ case GL_UNSIGNED_SHORT:
+ {
+ size *= 2;
+ unsigned short* tab_indices = (unsigned short*)indices;
+ for(i=0;i<count;i++)
+ {
+ if (tab_indices[i] < start || tab_indices[i] > end)
+ {
+ log_gl("indice out of bounds at offset %d\n", i);
+ }
+ }
+ break;
+ }
+
+ case GL_UNSIGNED_INT:
+ {
+ size *= 4;
+ unsigned int* tab_indices = (unsigned int*)indices;
+ for(i=0;i<count;i++)
+ {
+ if (tab_indices[i] < start || tab_indices[i] > end)
+ {
+ log_gl("indice out of bounds at offset %d\n", i);
+ }
+ }
+ break;
+ }
+
+ default:
+ log_gl("unsupported type = %d\n", type);
+ return;
+ }
+#else
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ }
+
+ case GL_UNSIGNED_SHORT:
+ {
+ size *= 2;
+ break;
+ }
+
+ case GL_UNSIGNED_INT:
+ {
+ size *= 4;
+ break;
+ }
+
+ default:
+ log_gl("unsupported type = %d\n", type);
+ return;
+ }
+#endif
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end),
+ INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) };
+ int args_size[] = { 0, 0, 0, 0, 0, size } ;
+ do_opengl_call(glDrawRangeElements_func, NULL, CHECK_ARGS(args, args_size));
+
+}
+
+DEFINE_EXT(glDrawRangeElements, ( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices ),
+ (mode, start, end, count, type, indices) )
+
+
+GLAPI void APIENTRY glMultiDrawArrays( GLenum mode, GLint *first,
+ GLsizei *count, GLsizei primcount )
+{
+ GLint i;
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ glFuncTable.fpDrawArrays(mode, first[i], count[i]);
+ }
+ }
+}
+
+DEFINE_EXT(glMultiDrawArrays, ( GLenum mode, GLint *first,
+ GLsizei *count, GLsizei primcount ),
+ (mode, first, count, primcount) )
+
+GLAPI void APIENTRY glMultiDrawElements( GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount )
+{
+ GLint i;
+ CHECK_PROC(glMultiDrawElements);
+
+ Buffer* bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ if (bufferElement && primcount > 1)
+ {
+ if (_check_if_enabled_non_vbo_array())
+ {
+ log_gl("sorry : unsupported : glMultiDrawElements in EBO with a non VBO array enabled\n");
+ return;
+ }
+ long args[] = { INT_TO_ARG(mode), POINTER_TO_ARG(count), INT_TO_ARG(type),
+ POINTER_TO_ARG(indices), INT_TO_ARG(primcount) };
+ int args_size[] = { 0, primcount * sizeof(int), 0, primcount * sizeof(void*), 0 };
+ do_opengl_call(_glMultiDrawElements_buffer_func, NULL, args, args_size);
+ return;
+ }
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ glFuncTable.fpDrawElements(mode, count[i], type, indices[i]);
+ }
+ }
+}
+
+DEFINE_EXT(glMultiDrawElements, ( GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount ),
+ (mode, count, type, indices, primcount) )
+
+
+#if 0
+GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset)
+{
+ CHECK_PROC(glArrayObjectATI);
+ //log_gl("glArrayObjectATI(array=%p, size=%d, type=%p, stride=%d, buffer=%d, offset=%d)\n", array, size, type, stride, buffer, offset);
+ long args[] = { UNSIGNED_INT_TO_ARG(array), INT_TO_ARG(size), UNSIGNED_INT_TO_ARG(type), INT_TO_ARG(stride), UNSIGNED_INT_TO_ARG(buffer), UNSIGNED_INT_TO_ARG(offset)};
+ do_opengl_call(glArrayObjectATI_func, NULL, args, NULL);
+}
+#endif
+
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count)
+{
+ CHECK_PROC(glDrawElementArrayATI);
+ GET_CURRENT_STATE();
+
+ if (state->client_state.arrays.elementArrayATI.enabled &&
+ state->client_state.arrays.elementArrayATI.ptr != NULL)
+ {
+ int size = count * getMulFactorFromPointerArray(&state->client_state.arrays.elementArrayATI);
+ long args[] = { INT_TO_ARG(state->client_state.arrays.elementArrayATI.type),
+ INT_TO_ARG(size),
+ INT_TO_ARG(state->client_state.arrays.elementArrayATI.ptr) };
+ int args_size[] = {0, 0, size};
+ do_opengl_call(glElementPointerATI_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count) };
+ do_opengl_call(glDrawElementArrayATI_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count)
+{
+ CHECK_PROC(glDrawRangeElementArrayATI);
+ GET_CURRENT_STATE();
+
+ if (state->client_state.arrays.elementArrayATI.enabled &&
+ state->client_state.arrays.elementArrayATI.ptr != NULL)
+ {
+ int size = count * getMulFactorFromPointerArray(&state->client_state.arrays.elementArrayATI);
+ long args[] = { INT_TO_ARG(state->client_state.arrays.elementArrayATI.type),
+ INT_TO_ARG(size),
+ INT_TO_ARG(state->client_state.arrays.elementArrayATI.ptr) };
+ int args_size[] = {0, 0, size};
+ do_opengl_call(glElementPointerATI_fake_func, NULL, CHECK_ARGS(args, args_size));
+ }
+
+ long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end), INT_TO_ARG(count) };
+ do_opengl_call(glDrawRangeElementArrayATI_func, NULL, args, NULL);
+}
+
+GLAPI GLuint APIENTRY glGenSymbolsEXT(GLenum datatype, GLenum storagetype, GLenum range, GLuint components)
+{
+ GLuint id = 0;
+ CHECK_PROC_WITH_RET(glGenSymbolsEXT);
+ GET_CURRENT_STATE();
+ long args[] = { datatype, storagetype, range, components };
+ do_opengl_call(glGenSymbolsEXT_func, &id, args, NULL);
+ if (id != 0)
+ {
+ state->symbols.tab = realloc(state->symbols.tab, (state->symbols.count+1) * sizeof(Symbol));
+ state->symbols.tab[state->symbols.count].id = id;
+ state->symbols.tab[state->symbols.count].datatype = datatype;
+ state->symbols.tab[state->symbols.count].components = components;
+ state->symbols.count++;
+ }
+ return id;
+}
+
+static int get_vertex_shader_var_nb_composants(GLuint id)
+{
+ GET_CURRENT_STATE();
+ int i;
+ for(i=0;i<state->symbols.count;i++)
+ {
+ if (id >= state->symbols.tab[i].id && id < state->symbols.tab[i].id + state->symbols.tab[i].components)
+ {
+ int size = 0;
+
+ if (state->symbols.tab[i].datatype == GL_SCALAR_EXT)
+ size = 1;
+ else if (state->symbols.tab[i].datatype == GL_VECTOR_EXT)
+ size = 4;
+ else if (state->symbols.tab[i].datatype == GL_MATRIX_EXT)
+ size = 16;
+ else
+ {
+ log_gl("unknown datatype %d\n", state->symbols.tab[i].datatype);
+ return 0;
+ }
+
+ return size;
+ }
+ }
+ log_gl("unknown id %d\n", id);
+ return 0;
+}
+
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr)
+{
+ CHECK_PROC(glSetLocalConstantEXT);
+ int size = get_vertex_shader_var_nb_composants(id) * getGlTypeByteSize(type);
+ if (size)
+ {
+ long args[] = { id, type, POINTER_TO_ARG(addr) };
+ int args_size[] = { 0, 0, size };
+
+ do_opengl_call(glSetLocalConstantEXT_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr)
+{
+ CHECK_PROC(glSetInvariantEXT);
+ int size = get_vertex_shader_var_nb_composants(id) * getGlTypeByteSize(type);
+ if (size)
+ {
+ long args[] = { id, type, POINTER_TO_ARG(addr) };
+ int args_size[] = { 0, 0, size };
+
+ do_opengl_call(glSetInvariantEXT_func, NULL, CHECK_ARGS(args, args_size));
+ }
+}
+
+#define glVariantGeneric(func_name, gltype) \
+GLAPI void APIENTRY func_name (GLuint id, const gltype * addr)\
+{\
+ CHECK_PROC(func_name); \
+ int size = get_vertex_shader_var_nb_composants(id) * sizeof(gltype); \
+ if (size) \
+ { \
+ long args[] = { id, POINTER_TO_ARG(addr) }; \
+ int args_size[] = { 0, size }; \
+ do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \
+ } \
+}
+
+glVariantGeneric(glVariantbvEXT, GLbyte);
+glVariantGeneric(glVariantsvEXT, GLshort);
+glVariantGeneric(glVariantivEXT, GLint);
+glVariantGeneric(glVariantfvEXT, GLfloat);
+glVariantGeneric(glVariantdvEXT, GLdouble);
+glVariantGeneric(glVariantubvEXT, GLubyte);
+glVariantGeneric(glVariantusvEXT, GLushort);
+glVariantGeneric(glVariantuivEXT, GLuint);
+
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id)
+{
+ CHECK_PROC(glEnableVariantClientStateEXT);
+ long args[] = { id };
+ do_opengl_call(glEnableVariantClientStateEXT_func, NULL, args, NULL);
+ if (id < MY_GL_MAX_VARIANT_POINTER_EXT)
+ {
+ GET_CURRENT_STATE();
+ state->client_state.arrays.variantPointer[id].enabled = 1;
+ }
+}
+
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id)
+{
+ CHECK_PROC(glDisableVariantClientStateEXT);
+ long args[] = { id };
+ do_opengl_call(glDisableVariantClientStateEXT_func, NULL, args, NULL);
+ if (id < MY_GL_MAX_VARIANT_POINTER_EXT)
+ {
+ GET_CURRENT_STATE();
+ state->client_state.arrays.variantPointer[id].enabled = 0;
+ }
+}
+
+GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *ptr)
+{
+ CHECK_PROC(glVariantPointerEXT);
+
+ GET_CURRENT_STATE();
+ if (id < MY_GL_MAX_VARIANT_POINTER_EXT)
+ {
+ state->client_state.arrays.variantPointer[id].vbo_name = state->arrayBuffer;
+ if (state->client_state.arrays.variantPointer[id].vbo_name)
+ {
+ long args[] = { INT_TO_ARG(id), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) };
+ do_opengl_call(_glVariantPointerEXT_buffer_func, NULL, args, NULL);
+ return;
+ }
+
+ if (debug_array_ptr)
+ log_gl("glVariantPointerEXT[%d] type=%dstride=%d ptr=%p\n",
+ id, type, stride, ptr);
+ state->client_state.arrays.variantPointer[id].index = id;
+ state->client_state.arrays.variantPointer[id].size = 4;
+ state->client_state.arrays.variantPointer[id].type = type;
+ state->client_state.arrays.variantPointer[id].stride = stride;
+ state->client_state.arrays.variantPointer[id].ptr = ptr;
+ }
+ else
+ {
+ log_gl("id >= MY_GL_MAX_VARIANT_POINTER_EXT\n");
+ }
+}
+
+#define glGetVariantGeneric(func_name, gltype) \
+GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\
+{\
+ CHECK_PROC(func_name); \
+ int size = (name == GL_VARIANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \
+ if (size) \
+ { \
+ long args[] = { id, name, POINTER_TO_ARG(addr) }; \
+ int args_size[] = { 0, 0, size }; \
+ do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \
+ } \
+}
+
+glGetVariantGeneric(glGetVariantBooleanvEXT, GLboolean);
+glGetVariantGeneric(glGetVariantIntegervEXT, GLint);
+glGetVariantGeneric(glGetVariantFloatvEXT, GLfloat);
+
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum name, GLvoid* *addr)
+{
+ CHECK_PROC(glGetVariantPointervEXT);
+
+ GET_CURRENT_STATE();
+ if (id < MY_GL_MAX_VARIANT_POINTER_EXT)
+ {
+ if (name == GL_VARIANT_ARRAY_POINTER_EXT)
+ *addr = (void*)state->client_state.arrays.variantPointer[id].ptr;
+ }
+ else
+ {
+ log_gl("id >= MY_GL_MAX_VARIANT_POINTER_EXT\n");
+ }
+}
+
+#define glGetInvariantGeneric(func_name, gltype) \
+GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\
+{\
+ CHECK_PROC(func_name); \
+ int size = (name == GL_INVARIANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \
+ if (size) \
+ { \
+ long args[] = { id, name, POINTER_TO_ARG(addr) }; \
+ int args_size[] = { 0, 0, size }; \
+ do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \
+ } \
+}
+
+glGetInvariantGeneric(glGetInvariantBooleanvEXT, GLboolean);
+glGetInvariantGeneric(glGetInvariantIntegervEXT, GLint);
+glGetInvariantGeneric(glGetInvariantFloatvEXT, GLfloat);
+
+#define glGetLocalConstantGeneric(func_name, gltype) \
+GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\
+{\
+ CHECK_PROC(func_name); \
+ int size = (name == GL_LOCAL_CONSTANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \
+ if (size) \
+ { \
+ long args[] = { id, name, POINTER_TO_ARG(addr) }; \
+ int args_size[] = { 0, 0, size }; \
+ do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \
+ } \
+}
+
+glGetLocalConstantGeneric(glGetLocalConstantBooleanvEXT, GLboolean);
+glGetLocalConstantGeneric(glGetLocalConstantIntegervEXT, GLint);
+glGetLocalConstantGeneric(glGetLocalConstantFloatvEXT, GLfloat);
+
+static void _glShaderSource(int func_number, GLhandleARB handle, GLsizei size, const GLcharARB** tab_prog, const GLint* tab_length)
+{
+ int i;
+ int* my_tab_length;
+ int total_length = 0;
+ int acc_length = 0;
+ GLcharARB* all_progs;
+
+ if (size <= 0 || tab_prog == NULL)
+ {
+ log_gl("size <= 0 || tab_prog == NULL\n");
+ return;
+ }
+ my_tab_length = malloc(sizeof(int) * size);
+ for(i=0;i<size;i++)
+ {
+ if (tab_prog[i] == NULL)
+ {
+ log_gl("tab_prog[%d] == NULL\n", i);
+ free(my_tab_length);
+ return ;
+ }
+ my_tab_length[i] = (tab_length && tab_length[i]) ? tab_length[i] : strlen(tab_prog[i]);
+ total_length += my_tab_length[i];
+ }
+ all_progs = malloc(total_length+1);
+ all_progs[total_length] = 0;
+ total_length ++;
+ for(i=0;i<size;i++)
+ {
+ char* str_tmp = all_progs + acc_length;
+ memcpy(str_tmp, tab_prog[i], my_tab_length[i]);
+ if (debug_gl) log_gl("glShaderSource[%d] : %s\n", i, str_tmp);
+ char* version_ptr = strstr(str_tmp, "#version");
+ if (version_ptr && version_ptr != str_tmp)
+ {
+ /* ATI driver won't be happy if "#version" is not at beginning of program */
+ /* Necessary for "Danger from the Deep 0.3.0" */
+ int offset = version_ptr - str_tmp;
+ char* eol = strchr(version_ptr, '\n');
+ if (eol)
+ {
+ int len = eol - version_ptr + 1;
+ memcpy(str_tmp, tab_prog[i] + offset, len);
+ memcpy(str_tmp + len, tab_prog[i], offset);
+ }
+ }
+ acc_length += my_tab_length[i];
+ }
+ long args[] = { INT_TO_ARG(handle), INT_TO_ARG(size), POINTER_TO_ARG(all_progs), POINTER_TO_ARG(my_tab_length) } ;
+ int args_size[] = { 0, 0, total_length, sizeof(int) * size };
+ do_opengl_call(func_number, NULL, CHECK_ARGS(args, args_size));
+ free(my_tab_length);
+ free(all_progs);
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glShaderSourceARB) (GLhandleARB handle, GLsizei size, const GLcharARB** tab_prog, const GLint* tab_length)
+{
+ CHECK_PROC(glShaderSourceARB);
+ _glShaderSource(glShaderSourceARB_fake_func, handle, size, tab_prog, tab_length);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glShaderSource) (GLhandleARB handle, GLsizei size, const GLcharARB** tab_prog, const GLint* tab_length)
+{
+ CHECK_PROC(glShaderSource);
+ _glShaderSource(glShaderSource_fake_func, handle, size, tab_prog, tab_length);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetProgramInfoLog)(GLuint program,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ CHECK_PROC(glGetProgramInfoLog);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(infoLog) };
+ int args_size[] = { 0, 0, sizeof(int), maxLength };
+ do_opengl_call(glGetProgramInfoLog_func, NULL, CHECK_ARGS(args, args_size));
+ log_gl("glGetProgramInfoLog: %s\n", infoLog);
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetProgramStringARB) (GLenum target, GLenum pname, GLvoid *string)
+{
+ int size = 0;
+ CHECK_PROC(glGetProgramStringARB);
+ glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &size);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(pname), POINTER_TO_ARG(string) };
+ int args_size[] = { 0, 0, size };
+ do_opengl_call(glGetProgramStringARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetProgramStringNV) (GLenum target, GLenum pname, GLvoid *string)
+{
+ int size = 0;
+ CHECK_PROC(glGetProgramStringNV);
+ glGetProgramivNV(target, GL_PROGRAM_LENGTH_NV, &size);
+ long args[] = { INT_TO_ARG(target), INT_TO_ARG(pname), POINTER_TO_ARG(string) };
+ int args_size[] = { 0, 0, size };
+ do_opengl_call(glGetProgramStringNV_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetInfoLogARB)(GLhandleARB object,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLcharARB *infoLog)
+{
+ CHECK_PROC(glGetInfoLogARB);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(object), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(infoLog) };
+ /*int size = 0;
+ glGetObjectParameterARBiv(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);*/
+ int args_size[] = { 0, 0, sizeof(int), maxLength };
+ do_opengl_call(glGetInfoLogARB_func, NULL, CHECK_ARGS(args, args_size));
+ log_gl("glGetInfoLogARB : %s\n", infoLog);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetAttachedObjectsARB)(GLhandleARB program,
+ GLsizei maxCount,
+ GLsizei *count,
+ GLhandleARB *objects)
+{
+ CHECK_PROC(glGetAttachedObjectsARB);
+ int fake_count;
+ if (count == NULL) count = &fake_count;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(maxCount), POINTER_TO_ARG(count), POINTER_TO_ARG(objects) };
+ /*int size = 0;
+ glGetObjectParameterARBiv(object, GL_OBJECT_ATTACHED_OBJECTS_ARB, &size);*/
+ int args_size[] = { 0, 0, sizeof(int), maxCount * sizeof(int) };
+ do_opengl_call(glGetAttachedObjectsARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetAttachedShaders)(GLuint program,
+ GLsizei maxCount,
+ GLsizei *count,
+ GLuint *shaders)
+{
+ CHECK_PROC(glGetAttachedShaders);
+ int fake_count;
+ if (count == NULL) count = &fake_count;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(maxCount), POINTER_TO_ARG(count), POINTER_TO_ARG(shaders) };
+ int args_size[] = { 0, 0, sizeof(int), maxCount * sizeof(int) };
+ do_opengl_call(glGetAttachedShaders_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI GLint EXT_FUNC(glGetUniformLocationARB) (GLuint program, const GLcharARB *txt)
+{
+ int i;
+ int ret = -1;
+ GET_CURRENT_STATE();
+ for(i=0;i<state->countUniformLocations;i++)
+ {
+ if (state->uniformLocations[i].program == program &&
+ strcmp(state->uniformLocations[i].txt, txt) == 0)
+ {
+ return state->uniformLocations[i].location;
+ }
+ }
+
+ CHECK_PROC_WITH_RET(glGetUniformLocationARB);
+ long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(txt) } ;
+ do_opengl_call(glGetUniformLocationARB_func, &ret, args, NULL);
+
+ state->uniformLocations = realloc(state->uniformLocations, sizeof(UniformLocation) * (state->countUniformLocations+1));
+ state->uniformLocations[state->countUniformLocations].program = program;
+ state->uniformLocations[state->countUniformLocations].txt = strdup(txt);
+ state->uniformLocations[state->countUniformLocations].location = ret;
+ state->countUniformLocations++;
+
+ return ret;
+}
+
+GLAPI GLint EXT_FUNC(glGetUniformLocation) (GLuint program, const GLcharARB *txt)
+{
+ int i;
+ int ret = -1;
+ GET_CURRENT_STATE();
+ for(i=0;i<state->countUniformLocations;i++)
+ {
+ if (state->uniformLocations[i].program == program &&
+ strcmp(state->uniformLocations[i].txt, txt) == 0)
+ {
+ return state->uniformLocations[i].location;
+ }
+ }
+
+ CHECK_PROC_WITH_RET(glGetUniformLocation);
+ long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(txt) } ;
+ do_opengl_call(glGetUniformLocation_func, &ret, args, NULL);
+
+ state->uniformLocations = realloc(state->uniformLocations, sizeof(UniformLocation) * (state->countUniformLocations+1));
+ state->uniformLocations[state->countUniformLocations].program = program;
+ state->uniformLocations[state->countUniformLocations].txt = strdup(txt);
+ state->uniformLocations[state->countUniformLocations].location = ret;
+ state->countUniformLocations++;
+
+ return ret;
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetActiveUniformARB)(GLuint program,
+ GLuint index,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLcharARB *name)
+{
+ CHECK_PROC(glGetActiveUniformARB);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) };
+ int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength };
+ do_opengl_call(glGetActiveUniformARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetActiveUniform)(GLuint program,
+ GLuint index,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLcharARB *name)
+{
+ CHECK_PROC(glGetActiveUniform);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) };
+ int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength };
+ do_opengl_call(glGetActiveUniform_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetActiveVaryingNV)(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name)
+{
+ CHECK_PROC(glGetActiveVaryingNV);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(bufSize), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) };
+ int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), bufSize };
+ do_opengl_call(glGetActiveVaryingNV_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+static int _get_size_of_gl_uniform_variables(GLenum type)
+{
+ switch(type)
+ {
+ case GL_FLOAT: return sizeof(float);
+ case GL_FLOAT_VEC2: return 2*sizeof(float);
+ case GL_FLOAT_VEC3: return 3*sizeof(float);
+ case GL_FLOAT_VEC4: return 4*sizeof(float);
+ case GL_INT: return sizeof(int);
+ case GL_INT_VEC2: return 2*sizeof(int);
+ case GL_INT_VEC3: return 3*sizeof(int);
+ case GL_INT_VEC4: return 4*sizeof(int);
+ case GL_BOOL: return sizeof(int);
+ case GL_BOOL_VEC2: return 2*sizeof(int);
+ case GL_BOOL_VEC3: return 3*sizeof(int);
+ case GL_BOOL_VEC4: return 4*sizeof(int);
+ case GL_FLOAT_MAT2: return 2*2*sizeof(float);
+ case GL_FLOAT_MAT3: return 3*3*sizeof(float);
+ case GL_FLOAT_MAT4: return 4*4*sizeof(float);
+ case GL_FLOAT_MAT2x3:return 2*3*sizeof(float);
+ case GL_FLOAT_MAT2x4:return 2*4*sizeof(float);
+ case GL_FLOAT_MAT3x2:return 3*2*sizeof(float);
+ case GL_FLOAT_MAT3x4:return 3*4*sizeof(float);
+ case GL_FLOAT_MAT4x2:return 4*2*sizeof(float);
+ case GL_FLOAT_MAT4x3:return 4*3*sizeof(float);
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ return sizeof(int);
+
+ default:
+ log_gl("unknown type for a uniform variable : %X\n", type);
+ return 0;
+ }
+}
+
+static void _gl_get_uniform(PFNGLGETPROGRAMIVPROC getProgramiv,
+ PFNGLGETACTIVEUNIFORMPROC getActiveUniform,
+ int func_number,
+ GLuint program,
+ GLint location,
+ void* params)
+{
+ GET_CURRENT_STATE();
+ int nActiveUniforms = 0;
+ int nameMaxLength = 0;
+ int i;
+
+ getProgramiv(program, GL_ACTIVE_UNIFORMS, &nActiveUniforms);
+ getProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &nameMaxLength);
+
+ char* name = malloc(nameMaxLength+1);
+ char* uniformName = NULL;
+ for(i=0;i<state->countUniformLocations;i++)
+ {
+ if (state->uniformLocations[i].program == program &&
+ state->uniformLocations[i].location == location)
+ {
+ uniformName = state->uniformLocations[i].txt;
+ break;
+ }
+ }
+ if (uniformName == NULL)
+ {
+ log_gl("unknown uniform location : %d\n", location);
+ return;
+ }
+ char* uniformName2 = NULL;
+ if (strchr(uniformName, '[') == 0)
+ {
+ uniformName2 = malloc(strlen(uniformName) + 3 + 1);
+ strcpy(uniformName2, uniformName);
+ strcat(uniformName2, "[0]");
+ }
+ /*log_gl("nActiveUniforms=%d\n", nActiveUniforms);*/
+ for(i=0;i<nActiveUniforms;i++)
+ {
+ int actualLength, size;
+ unsigned int type;
+ int index = (i == 0 && location < nActiveUniforms) ? location : (i == location) ? 0 : i;
+ getActiveUniform(program, index, nameMaxLength, &actualLength, &size, &type, name);
+ /*log_gl("[%d] %s\n", i, name);*/
+ if (strcmp(name, uniformName) == 0 || (uniformName2 && strcmp(name, uniformName2) == 0))
+ {
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(location), POINTER_TO_ARG(params) };
+ int args_size[] = { 0, 0, size * _get_size_of_gl_uniform_variables(type) };
+ do_opengl_call(func_number, NULL, CHECK_ARGS(args, args_size));
+ break;
+ }
+ }
+ if (i == nActiveUniforms)
+ {
+ log_gl("sorry : I can't retrieve %s in the list of active uniforms\n", uniformName);
+ }
+ free(uniformName2);
+ free(name);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetUniformfvARB)(GLuint program,
+ GLint location,
+ GLfloat *params)
+{
+ CHECK_PROC(glGetUniformfvARB);
+ _gl_get_uniform(glGetProgramivARB, glGetActiveUniformARB, glGetUniformfvARB_func, program, location, params);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetUniformfv)(GLuint program,
+ GLint location,
+ GLfloat *params)
+{
+ CHECK_PROC(glGetUniformfv);
+ _gl_get_uniform(glGetProgramiv, glGetActiveUniform, glGetUniformfv_func, program, location, params);
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetUniformivARB)(GLuint program,
+ GLint location,
+ GLint *params)
+{
+ CHECK_PROC(glGetUniformivARB);
+ _gl_get_uniform(glGetProgramivARB, glGetActiveUniformARB, glGetUniformivARB_func, program, location, params);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetUniformuivEXT)(GLuint program,
+ GLint location,
+ GLuint *params)
+{
+ CHECK_PROC(glGetUniformuivEXT);
+ _gl_get_uniform(glGetProgramivARB, glGetActiveUniformARB, glGetUniformuivEXT_func, program, location, params);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetUniformiv)(GLuint program,
+ GLint location,
+ GLint *params)
+{
+ CHECK_PROC(glGetUniformiv);
+ _gl_get_uniform(glGetProgramiv, glGetActiveUniform, glGetUniformiv_func, program, location, params);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetShaderSourceARB)(GLuint shader,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLcharARB *source)
+{
+ CHECK_PROC(glGetShaderSourceARB);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(shader), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(source) };
+ int args_size[] = { 0, 0, sizeof(int), maxLength };
+ do_opengl_call(glGetShaderSourceARB_func, NULL, CHECK_ARGS(args, args_size));
+ log_gl("glGetShaderSourceARB : %s\n", source);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetShaderSource)(GLuint shader,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLcharARB *source)
+{
+ CHECK_PROC(glGetShaderSource);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(shader), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(source) };
+ int args_size[] = { 0, 0, sizeof(int), maxLength };
+ do_opengl_call(glGetShaderSource_func, NULL, CHECK_ARGS(args, args_size));
+ log_gl("glGetShaderSource : %s\n", source);
+}
+
+
+GLAPI void APIENTRY EXT_FUNC(glGetShaderInfoLog)(GLuint shader,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ CHECK_PROC(glGetShaderInfoLog);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(shader), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(infoLog) };
+ int args_size[] = { 0, 0, sizeof(int), maxLength };
+ do_opengl_call(glGetShaderInfoLog_func, NULL, CHECK_ARGS(args, args_size));
+ log_gl("glGetShaderInfoLog: %s\n", infoLog);
+}
+
+
+static ObjectBufferATI* _new_object_buffer_ATI()
+{
+ GET_CURRENT_STATE();
+ int i;
+ for(i=0;i<32768;i++)
+ {
+ if (state->objectBuffersATI[i].bufferid == 0)
+ {
+ memset(&state->objectBuffersATI[i], 0, sizeof(ObjectBufferATI));
+ return &state->objectBuffersATI[i];
+ }
+ }
+ return NULL;
+}
+
+static ObjectBufferATI* _find_object_buffer_ATI_from_id(GLuint buffer)
+{
+ GET_CURRENT_STATE();
+ int i;
+ for(i=0;i<32768;i++)
+ {
+ if (state->objectBuffersATI[i].bufferid == buffer)
+ {
+ return &state->objectBuffersATI[i];
+ }
+ }
+ return NULL;
+}
+
+static void _free_object_buffer_ATI(ObjectBufferATI* objectBufferATI)
+{
+ if (objectBufferATI == NULL) return;
+
+ if (objectBufferATI->ptr)
+ free(objectBufferATI->ptr);
+ objectBufferATI->ptr = NULL;
+ if (objectBufferATI->ptrMapped)
+ free(objectBufferATI->ptrMapped);
+ objectBufferATI->ptrMapped = NULL;
+ if (objectBufferATI->ptrUpdatedWhileMapped)
+ free(objectBufferATI->ptrUpdatedWhileMapped);
+ objectBufferATI->ptrUpdatedWhileMapped = NULL;
+ if (objectBufferATI->updatedRangesAfterMapping.ranges)
+ free(objectBufferATI->updatedRangesAfterMapping.ranges);
+ objectBufferATI->updatedRangesAfterMapping.ranges = NULL;
+ objectBufferATI->updatedRangesAfterMapping.nb = 0;
+ objectBufferATI->bufferid = 0;
+ objectBufferATI->size = 0;
+}
+
+GLAPI GLuint APIENTRY EXT_FUNC(glNewObjectBufferATI) (GLsizei size, const GLvoid *pointer, GLenum usage)
+{
+ int buffer = 0;
+ CHECK_PROC_WITH_RET(glNewObjectBufferATI);
+ long args[] = { INT_TO_ARG(size), POINTER_TO_ARG(pointer), INT_TO_ARG(usage) };
+ int args_size[] = { 0, (pointer) ? size : 0, 0 };
+ do_opengl_call(glNewObjectBufferATI_func, &buffer, CHECK_ARGS(args, args_size));
+ //log_gl("glNewObjectBufferATI(%d,%p) --> %d\n", size, pointer, buffer);
+
+ if (buffer != 0)
+ {
+ ObjectBufferATI* objectBufferATI = _new_object_buffer_ATI();
+ if (objectBufferATI)
+ {
+ objectBufferATI->bufferid = buffer;
+ objectBufferATI->size = size;
+ objectBufferATI->ptr = malloc(size);
+ objectBufferATI->ptrMapped = NULL;
+ if (pointer)
+ memcpy(objectBufferATI->ptr, pointer, size);
+ }
+ }
+
+ return buffer;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glFreeObjectBufferATI) (GLuint buffer)
+{
+ CHECK_PROC(glFreeObjectBufferATI);
+ long args[] = { UNSIGNED_INT_TO_ARG(buffer)};
+ do_opengl_call(glFreeObjectBufferATI_func, NULL, args, NULL);
+ _free_object_buffer_ATI(_find_object_buffer_ATI_from_id(buffer));
+}
+
+static void _add_int_range_to_ranges(IntSetRanges* ranges, int start, int length)
+{
+ int i,j;
+ for(i=0;i<ranges->nb;i++)
+ {
+ IntRange* range = &ranges->ranges[i];
+ if (start <= range->start)
+ {
+ if (start + length < range->start)
+ {
+ if (ranges->nb == ranges->maxNb)
+ ranges->ranges = realloc(ranges->ranges, sizeof(IntRange) * (ranges->nb+1));
+ memmove(&ranges->ranges[i+1], &ranges->ranges[i], sizeof(IntRange) * (ranges->nb - i));
+ ranges->nb++;
+ if (ranges->nb > ranges->maxNb)
+ ranges->maxNb = ranges->nb;
+ ranges->ranges[i].start = start;
+ ranges->ranges[i].length = length;
+ return;
+ }
+ else if (start + length <= range->start + range->length)
+ {
+ range->length = range->start + range->length - start;
+ range->start = start;
+ return;
+ }
+ else
+ {
+ j = i + 1;
+ range->start = start;
+ range->length = start + length - range->start;
+ while(j < ranges->nb && start + length >= ranges->ranges[j].start)
+ {
+ if (start + length <= ranges->ranges[j].start + ranges->ranges[j].length)
+ {
+ range->length = ranges->ranges[j].start + ranges->ranges[j].length - range->start;
+ j++;
+ break;
+ }
+ j++;
+ }
+ if (i+1<j && j < ranges->nb)
+ memmove(&ranges->ranges[i+1], &ranges->ranges[j], sizeof(IntRange) * (j - (i + 1)));
+ ranges->nb -= j - (i+1);
+ return;
+ }
+ }
+ else
+ {
+ if (start > range->start + range->length)
+ {
+ continue;
+ }
+ else if (start + length <= range->start + range->length)
+ {
+ return;
+ }
+ else
+ {
+ j = i + 1;
+ range->length = start + length - range->start;
+ while(j < ranges->nb && start + length >= ranges->ranges[j].start)
+ {
+ if (start + length <= ranges->ranges[j].start + ranges->ranges[j].length)
+ {
+ range->length = ranges->ranges[j].start + ranges->ranges[j].length - range->start;
+ j++;
+ break;
+ }
+ j++;
+ }
+ if (i+1<j && j < ranges->nb)
+ memmove(&ranges->ranges[i+1], &ranges->ranges[j], sizeof(IntRange) * (j - (i + 1)));
+ ranges->nb -= j - (i+1);
+ return;
+ }
+ }
+ }
+ if (ranges->nb == ranges->maxNb)
+ ranges->ranges = realloc(ranges->ranges, sizeof(IntRange) * (ranges->nb+1));
+ ranges->ranges[ranges->nb].start = start;
+ ranges->ranges[ranges->nb].length = length;
+ ranges->nb++;
+ if (ranges->nb > ranges->maxNb)
+ ranges->maxNb = ranges->nb;
+ return;
+}
+
+static IntSetRanges _get_empty_ranges(IntSetRanges* inRanges, int start, int length)
+{
+ IntSetRanges outRanges = {0};
+ int i;
+ int end = start+length;
+ int last_end = 0x80000000;
+ for(i=0;i<=inRanges->nb;i++)
+ {
+ int cur_start, cur_end;
+ if (i == inRanges->nb)
+ {
+ cur_start = cur_end = 0x7FFFFFFF;
+ }
+ else
+ {
+ IntRange* range = &inRanges->ranges[i];
+ cur_start = range->start;
+ cur_end = range->start + range->length;
+ }
+
+ /* [last_end,cur_start[ inter [start,end[ */
+ if ((last_end >= start && last_end < end) || (start >= last_end && start < cur_start))
+ {
+ outRanges.ranges = realloc(outRanges.ranges, sizeof(IntRange) * (outRanges.nb+1));
+ outRanges.ranges[outRanges.nb].start = MAX(start,last_end);
+ outRanges.ranges[outRanges.nb].length = MIN(end,cur_start) - outRanges.ranges[outRanges.nb].start;
+ outRanges.nb++;
+ }
+
+ last_end = cur_end;
+ }
+ return outRanges;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glUpdateObjectBufferATI) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve)
+{
+ CHECK_PROC(glUpdateObjectBufferATI);
+ //log_gl("glUpdateObjectBufferATI(%d, %d, %d)\n", buffer, offset, size);
+ long args[] = { INT_TO_ARG(buffer), INT_TO_ARG(offset), INT_TO_ARG(size), POINTER_TO_ARG(pointer), INT_TO_ARG(preserve) };
+ int args_size[] = { 0, 0, 0, size, 0 };
+ do_opengl_call(glUpdateObjectBufferATI_func, NULL, CHECK_ARGS(args, args_size));
+ ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer);
+ if (objectBufferATI)
+ {
+ if (offset >= 0 && offset + size <= objectBufferATI->size)
+ {
+ if (objectBufferATI->ptrMapped)
+ {
+ log_gl("you shouldn't call glUpdateObjectBufferATI after glMapObjectBufferATI. we're emulating ATI fglrx (strange) behaviour\n");
+ objectBufferATI->updatedRangesAfterMapping.nb = 0;
+ _add_int_range_to_ranges(&objectBufferATI->updatedRangesAfterMapping, offset, size);
+ objectBufferATI->ptrUpdatedWhileMapped = realloc(objectBufferATI->ptrUpdatedWhileMapped, size);
+ memcpy(objectBufferATI->ptrUpdatedWhileMapped, pointer, size);
+ }
+ else
+ {
+ memcpy(objectBufferATI->ptr + offset, pointer, size);
+ }
+ }
+ else
+ {
+ log_gl("offset >= 0 && offset + size <= state->objectBuffersATI[i].size failed\n");
+ }
+ }
+}
+
+GLAPI GLvoid* APIENTRY EXT_FUNC(glMapObjectBufferATI) (GLuint buffer)
+{
+ CHECK_PROC_WITH_RET(glMapObjectBufferATI);
+ //log_gl("glMapObjectBufferATI(%d)\n", buffer);
+ ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer);
+ if (objectBufferATI)
+ {
+ if (objectBufferATI->ptrMapped == NULL)
+ {
+ objectBufferATI->ptrMapped = malloc(objectBufferATI->size);
+ memcpy(objectBufferATI->ptrMapped,
+ objectBufferATI->ptr,
+ objectBufferATI->size);
+ return objectBufferATI->ptrMapped;
+ }
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glUnmapObjectBufferATI) (GLuint buffer)
+{
+ CHECK_PROC(glUnmapObjectBufferATI);
+ //log_gl("glUnmapObjectBufferATI(%d)\n", buffer);
+ ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer);
+ if (objectBufferATI)
+ {
+ if (objectBufferATI->ptrMapped)
+ {
+ IntSetRanges outRanges = _get_empty_ranges(&objectBufferATI->updatedRangesAfterMapping, 0, objectBufferATI->size);
+ int i;
+ void* ptrMapped = objectBufferATI->ptrMapped;
+ if (objectBufferATI->ptrUpdatedWhileMapped)
+ {
+ assert(objectBufferATI->updatedRangesAfterMapping.nb == 1);
+ memcpy(objectBufferATI->ptr + objectBufferATI->updatedRangesAfterMapping.ranges[0].start,
+ objectBufferATI->ptrUpdatedWhileMapped,
+ objectBufferATI->updatedRangesAfterMapping.ranges[0].length);
+ free(objectBufferATI->ptrUpdatedWhileMapped);
+ objectBufferATI->ptrUpdatedWhileMapped = NULL;
+ }
+ objectBufferATI->updatedRangesAfterMapping.nb = 0;
+ objectBufferATI->ptrMapped = NULL;
+ for(i=0;i<outRanges.nb;i++)
+ {
+ glUpdateObjectBufferATI(buffer, outRanges.ranges[i].start, outRanges.ranges[i].length,
+ ptrMapped, GL_DISCARD_ATI);
+ }
+ free(outRanges.ranges);
+ free(ptrMapped);
+ }
+ }
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetActiveAttribARB)(GLhandleARB program,
+ GLuint index,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLcharARB *name)
+{
+ CHECK_PROC(glGetActiveAttribARB);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) };
+ int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength };
+ do_opengl_call(glGetActiveAttribARB_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetActiveAttrib)(GLhandleARB program,
+ GLuint index,
+ GLsizei maxLength,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLcharARB *name)
+{
+ CHECK_PROC(glGetActiveAttrib);
+ int fake_length;
+ if (length == NULL) length = &fake_length;
+ long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) };
+ int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength };
+ do_opengl_call(glGetActiveAttrib_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI GLint APIENTRY EXT_FUNC(glGetAttribLocationARB)(GLhandleARB program,
+ const GLcharARB *name)
+{
+ CHECK_PROC_WITH_RET(glGetAttribLocationARB);
+ int ret = 0;
+ long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(name) };
+ do_opengl_call(glGetAttribLocationARB_func, &ret, args, NULL);
+ return ret;
+}
+
+GLAPI GLint APIENTRY EXT_FUNC(glGetAttribLocation)(GLhandleARB program,
+ const GLcharARB *name)
+{
+ CHECK_PROC_WITH_RET(glGetAttribLocation);
+ int ret = 0;
+ long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(name) };
+ do_opengl_call(glGetAttribLocation_func, &ret, args, NULL);
+ return ret;
+}
+
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points)
+{
+ int npoints = 0;
+ CHECK_PROC(glGetDetailTexFuncSGIS);
+ glFuncTable.fpGetTexParameteriv(target, GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS, &npoints);
+ long args[] = { INT_TO_ARG(target), POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 2 * npoints * sizeof(float) };
+ do_opengl_call(glGetDetailTexFuncSGIS_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points)
+{
+ int npoints = 0;
+ CHECK_PROC(glGetSharpenTexFuncSGIS);
+ glFuncTable.fpGetTexParameteriv(target, GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS, &npoints);
+ long args[] = { INT_TO_ARG(target), POINTER_TO_ARG(points) };
+ int args_size[] = { 0, 2 * npoints * sizeof(float) };
+ do_opengl_call(glGetSharpenTexFuncSGIS_func, NULL, CHECK_ARGS(args, args_size));
+}
+
+GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
+{
+ NOT_IMPLEMENTED(glColorTable);
+}
+
+GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
+{
+ NOT_IMPLEMENTED(glColorTableEXT);
+}
+
+
+GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data)
+{
+ NOT_IMPLEMENTED(glColorSubTable);
+}
+
+GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data)
+{
+ NOT_IMPLEMENTED(glColorSubTableEXT);
+}
+
+
+GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table)
+{
+ NOT_IMPLEMENTED(glGetColorTable);
+}
+
+GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *table)
+{
+ NOT_IMPLEMENTED(glGetColorTableEXT);
+}
+
+
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image)
+{
+ NOT_IMPLEMENTED(glConvolutionFilter1D);
+}
+
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image)
+{
+ NOT_IMPLEMENTED(glConvolutionFilter1DEXT);
+}
+
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image)
+{
+ NOT_IMPLEMENTED(glConvolutionFilter2D);
+}
+
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image)
+{
+ NOT_IMPLEMENTED(glConvolutionFilter2DEXT);
+}
+
+
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image)
+{
+ NOT_IMPLEMENTED(glGetConvolutionFilter);
+}
+
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image)
+{
+ NOT_IMPLEMENTED(glGetConvolutionFilterEXT);
+}
+
+GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span)
+{
+ NOT_IMPLEMENTED(glGetSeparableFilter);
+}
+
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span)
+{
+ NOT_IMPLEMENTED(glGetSeparableFilterEXT);
+}
+
+GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column)
+{
+ NOT_IMPLEMENTED(glSeparableFilter2D);
+}
+
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column)
+{
+ NOT_IMPLEMENTED(glSeparableFilter2DEXT);
+}
+
+
+GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ NOT_IMPLEMENTED(glGetHistogram);
+}
+
+GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ NOT_IMPLEMENTED(glGetHistogramEXT);
+}
+
+
+GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ NOT_IMPLEMENTED(glGetMinmax);
+}
+
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ NOT_IMPLEMENTED(glGetMinmaxEXT);
+}
+
+GLAPI void* APIENTRY glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority)
+{
+ return malloc(size);
+}
+
+GLAPI void APIENTRY glXFreeMemoryNV(GLvoid *pointer)
+{
+ free(pointer);
+}
+
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer)
+{
+ CHECK_PROC(glPixelDataRangeNV);
+ /* do nothing is a possible implementation... */
+}
+
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target)
+{
+ CHECK_PROC(glFlushPixelDataRangeNV);
+ /* do nothing is a possible implementation... */
+}
+
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei size, const GLvoid *ptr)
+{
+ CHECK_PROC(glVertexArrayRangeNV);
+ /* do nothing is a possible implementation... */
+}
+
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void)
+{
+ CHECK_PROC(glFlushVertexArrayRangeNV);
+ /* do nothing is a possible implementation... */
+}
+
+// added to support extension api
+GLAPI void APIENTRY EXT_FUNC(glGetRenderbufferParameteriv) (GLenum arg_0, GLenum arg_1, GLint * arg_2)
+{
+ CHECK_PROC(glGetRenderbufferParameterivEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1), POINTER_TO_ARG(arg_2)};
+ do_opengl_call(glGetRenderbufferParameterivEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGenRenderbuffers) (GLsizei arg_0, GLuint * arg_1)
+{
+ CHECK_PROC(glGenRenderbuffersEXT);
+ long args[] = { INT_TO_ARG(arg_0), POINTER_TO_ARG(arg_1)};
+ do_opengl_call(glGenRenderbuffersEXT_func, NULL, args, NULL);
+}
+
+GLAPI GLenum APIENTRY EXT_FUNC(glCheckFramebufferStatus) (GLenum arg_0)
+{
+ GLenum ret;
+ CHECK_PROC_WITH_RET(glCheckFramebufferStatusEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0)};
+ do_opengl_call(glCheckFramebufferStatusEXT_func, &ret, args, NULL);
+ return ret;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGenFramebuffers) (GLsizei arg_0, GLuint * arg_1)
+{
+ CHECK_PROC(glGenFramebuffersEXT);
+ long args[] = { INT_TO_ARG(arg_0), POINTER_TO_ARG(arg_1)};
+ do_opengl_call(glGenFramebuffersEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glRenderbufferStorage) (GLenum arg_0, GLenum arg_1, GLsizei arg_2, GLsizei arg_3)
+{
+ CHECK_PROC(glRenderbufferStorageEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1), INT_TO_ARG(arg_2), INT_TO_ARG(arg_3)};
+ do_opengl_call(glRenderbufferStorageEXT_func, NULL, args, NULL);
+}
+
+GLAPI GLboolean APIENTRY EXT_FUNC(glIsRenderbuffer) (GLuint arg_0)
+{
+ GLboolean ret;
+ CHECK_PROC_WITH_RET(glIsRenderbufferEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0)};
+ do_opengl_call(glIsRenderbufferEXT_func, &ret, args, NULL);
+ return ret;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGenerateMipmap) (GLenum arg_0)
+{
+ CHECK_PROC(glGenerateMipmapEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0)};
+ do_opengl_call(glGenerateMipmapEXT_func, NULL, args, NULL);
+}
+
+GLAPI GLboolean APIENTRY EXT_FUNC(glIsFramebuffer) (GLuint arg_0)
+{
+ GLboolean ret;
+ CHECK_PROC_WITH_RET(glIsFramebufferEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0)};
+ do_opengl_call(glIsFramebufferEXT_func, &ret, args, NULL);
+ return ret;
+}
+
+GLAPI void APIENTRY EXT_FUNC(glGetFramebufferAttachmentParameteriv) (GLenum arg_0, GLenum arg_1, GLenum arg_2, GLint * arg_3)
+{
+ CHECK_PROC(glGetFramebufferAttachmentParameterivEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1), UNSIGNED_INT_TO_ARG(arg_2), POINTER_TO_ARG(arg_3)};
+ do_opengl_call(glGetFramebufferAttachmentParameterivEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glDeleteFramebuffers) (GLsizei arg_0, const GLuint * arg_1)
+{
+ CHECK_PROC(glDeleteFramebuffersEXT);
+ long args[] = { INT_TO_ARG(arg_0), POINTER_TO_ARG(arg_1)};
+ do_opengl_call(glDeleteFramebuffersEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glFramebufferRenderbuffer) (GLenum arg_0, GLenum arg_1, GLenum arg_2, GLuint arg_3)
+{
+ CHECK_PROC(glFramebufferRenderbufferEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1), UNSIGNED_INT_TO_ARG(arg_2), UNSIGNED_INT_TO_ARG(arg_3)};
+ do_opengl_call(glFramebufferRenderbufferEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glDeleteRenderbuffers) (GLsizei arg_0, const GLuint * arg_1)
+{
+ CHECK_PROC(glDeleteRenderbuffersEXT);
+ long args[] = { INT_TO_ARG(arg_0), POINTER_TO_ARG(arg_1)};
+ do_opengl_call(glDeleteRenderbuffersEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glBindRenderbuffer) (GLenum arg_0, GLuint arg_1)
+{
+ CHECK_PROC(glBindRenderbufferEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1)};
+ do_opengl_call(glBindRenderbufferEXT_func, NULL, args, NULL);
+}
+
+GLAPI void APIENTRY EXT_FUNC(glBindFramebuffer) (GLenum arg_0, GLuint arg_1)
+{
+ CHECK_PROC(glBindFramebufferEXT);
+ long args[] = { UNSIGNED_INT_TO_ARG(arg_0), UNSIGNED_INT_TO_ARG(arg_1)};
+ do_opengl_call(glBindFramebufferEXT_func, NULL, args, NULL);
+}