/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
** $Date$ $Revision$
** $Header: //depot/main/glx/lib/vertarr.c#11 $
*/
#include "glxclient.h"
#include "packrender.h"
#include <string.h>
#include <limits.h> /* INT_MAX */
/* macros for setting function pointers */
#define __GL_VERTEX_FUNC(NAME, let) \
case GL_##NAME: \
if (size == 2) \
vertexPointer->proc = (void (*)(const void *))glVertex2##let##v; \
else if (size == 3) \
vertexPointer->proc = (void (*)(const void *))glVertex3##let##v; \
else if (size == 4) \
vertexPointer->proc = (void (*)(const void *))glVertex4##let##v; \
break
#define __GL_NORMAL_FUNC(NAME, let) \
case GL_##NAME: \
normalPointer->proc = (void (*)(const void *))glNormal3##let##v; \
break
#define __GL_COLOR_FUNC(NAME, let) \
case GL_##NAME: \
if (size == 3) \
colorPointer->proc = (void (*)(const void *))glColor3##let##v; \
else if (size == 4)\
colorPointer->proc = (void (*)(const void *))glColor4##let##v; \
break
#define __GL_INDEX_FUNC(NAME, let) \
case GL_##NAME: \
indexPointer->proc = (void (*)(const void *))glIndex##let##v; \
break
#define __GL_TEXTURE_FUNC(NAME, let) \
case GL_##NAME: \
if (size == 1) \
texCoordPointer->proc = (void (*)(const void *))glTexCoord1##let##v; \
else if (size == 2) \
texCoordPointer->proc = (void (*)(const void *))glTexCoord2##let##v; \
else if (size == 3) \
texCoordPointer->proc = (void (*)(const void *))glTexCoord3##let##v; \
else if (size == 4) \
texCoordPointer->proc = (void (*)(const void *))glTexCoord4##let##v; \
break
static GLuint __glXTypeSize(GLenum enm)
{
switch (enm) {
case __GL_BOOLEAN_ARRAY: return sizeof(GLboolean);
case GL_BYTE: return sizeof(GLbyte);
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
case GL_SHORT: return sizeof(GLshort);
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
case GL_INT: return sizeof(GLint);
case GL_UNSIGNED_INT: return sizeof(GLint);
case GL_FLOAT: return sizeof(GLfloat);
case GL_DOUBLE: return sizeof(GLdouble);
default: return 0;
}
}
void __glXInitVertexArrayState(__GLXcontext *gc)
{
__GLXvertArrayState *va = &gc->state.vertArray;
GLint i;
va->vertex.enable = GL_FALSE;
va->vertex.proc = NULL;
va->vertex.skip = 0;
va->vertex.ptr = 0;
va->vertex.size = 4;
va->vertex.type = GL_FLOAT;
va->vertex.stride = 0;
va->normal.enable = GL_FALSE;
va->normal.proc = NULL;
va->normal.skip = 0;
va->normal.ptr = 0;
va->normal.size = 3;
va->normal.type = GL_FLOAT;
va->normal.stride = 0;
va->color.enable = GL_FALSE;
va->color.proc = NULL;
va->color.skip = 0;
va->color.ptr = 0;
va->color.size = 4;
va->color.type = GL_FLOAT;
va->color.stride = 0;
va->index.enable = GL_FALSE;
va->index.proc = NULL;
va->index.skip = 0;
va->index.ptr = 0;
va->index.size = 1;
va->index.type = GL_FLOAT;
va->index.stride = 0;
for (i=0; i<__GLX_MAX_TEXTURE_UNITS; ++i) {
__GLXvertexArrayPointerState *texCoord = &va->texCoord[i];
texCoord->enable = GL_FALSE;
texCoord->proc = NULL;
texCoord->skip = 0;
texCoord->ptr = 0;
texCoord->size = 4;
texCoord->type = GL_FLOAT;
texCoord->stride = 0;
}
va->edgeFlag.enable = GL_FALSE;
va->edgeFlag.proc = NULL;
va->edgeFlag.skip = 0;
va->edgeFlag.ptr = 0;
va->edgeFlag.size = 1;
va->edgeFlag.type = GL_UNSIGNED_BYTE;
va->edgeFlag.stride = 0;
va->maxElementsVertices = INT_MAX;
va->maxElementsIndices = INT_MAX;
}
/*****************************************************************************/
void glVertexPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *vertexPointer = &gc->state.vertArray.vertex;
/* Check arguments */
if (size < 2 || size > 4 || stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
switch(type) {
__GL_VERTEX_FUNC(SHORT, s);
__GL_VERTEX_FUNC(INT, i);
__GL_VERTEX_FUNC(FLOAT, f);
__GL_VERTEX_FUNC(DOUBLE, d);
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
vertexPointer->size = size;
vertexPointer->type = type;
vertexPointer->stride = stride;
vertexPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
vertexPointer->skip = __glXTypeSize(type) * size;
} else {
vertexPointer->skip = stride;
}
}
void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *normalPointer = &gc->state.vertArray.normal;
/* Check arguments */
if (stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
switch(type) {
__GL_NORMAL_FUNC(BYTE, b);
__GL_NORMAL_FUNC(SHORT, s);
__GL_NORMAL_FUNC(INT, i);
__GL_NORMAL_FUNC(FLOAT, f);
__GL_NORMAL_FUNC(DOUBLE, d);
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
normalPointer->type = type;
normalPointer->stride = stride;
normalPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
normalPointer->skip = 3 * __glXTypeSize(type);
} else {
normalPointer->skip = stride;
}
}
void glColorPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *colorPointer = &gc->state.vertArray.color;
/* Check arguments */
if (stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
switch(type) {
__GL_COLOR_FUNC(BYTE, b);
__GL_COLOR_FUNC(UNSIGNED_BYTE, ub);
__GL_COLOR_FUNC(SHORT, s);
__GL_COLOR_FUNC(UNSIGNED_SHORT, us);
__GL_COLOR_FUNC(INT, i);
__GL_COLOR_FUNC(UNSIGNED_INT, ui);
__GL_COLOR_FUNC(FLOAT, f);
__GL_COLOR_FUNC(DOUBLE, d);
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
colorPointer->size = size;
colorPointer->type = type;
colorPointer->stride = stride;
colorPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
colorPointer->skip = size * __glXTypeSize(type);
} else {
colorPointer->skip = stride;
}
}
void glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *indexPointer = &gc->state.vertArray.index;
/* Check arguments */
if (stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
switch(type) {
__GL_INDEX_FUNC(UNSIGNED_BYTE, ub);
__GL_INDEX_FUNC(SHORT, s);
__GL_INDEX_FUNC(INT, i);
__GL_INDEX_FUNC(FLOAT, f);
__GL_INDEX_FUNC(DOUBLE, d);
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
indexPointer->type = type;
indexPointer->stride = stride;
indexPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
indexPointer->skip = __glXTypeSize(type);
} else {
indexPointer->skip = stride;
}
}
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *texCoordPointer =
&gc->state.vertArray.texCoord[gc->state.vertArray.activeTexture];
/* Check arguments */
if (size < 1 || size > 4 || stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
switch(type) {
__GL_TEXTURE_FUNC(SHORT, s);
__GL_TEXTURE_FUNC(INT, i);
__GL_TEXTURE_FUNC(FLOAT, f);
__GL_TEXTURE_FUNC(DOUBLE, d);
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
texCoordPointer->size = size;
texCoordPointer->type = type;
texCoordPointer->stride = stride;
texCoordPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
texCoordPointer->skip = __glXTypeSize(type) * size;
} else {
texCoordPointer->skip = stride;
}
}
void glEdgeFlagPointer(GLsizei stride, const GLboolean *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertexArrayPointerState *edgeFlagPointer = &gc->state.vertArray.edgeFlag;
/* Check arguments */
if (stride < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/* Choose appropriate api proc */
edgeFlagPointer->proc = (void (*)(const void *))glEdgeFlagv;
edgeFlagPointer->stride = stride;
edgeFlagPointer->ptr = pointer;
/* Set internal state */
if (stride == 0) {
edgeFlagPointer->skip = sizeof(GLboolean);
} else {
edgeFlagPointer->skip = stride;
}
}
void glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
{
__GLXcontext *gc = __glXGetCurrentContext();
GLboolean tEnable = GL_FALSE, cEnable = GL_FALSE, nEnable = GL_FALSE;
GLenum tType = GL_FLOAT, nType = GL_FLOAT, vType = GL_FLOAT;
GLenum cType = GL_FALSE;
GLint tSize = 0, cSize = 0, nSize = 3, vSize;
int cOffset = 0, nOffset = 0, vOffset = 0;
GLint trueStride, size;
switch (format) {
case GL_V2F:
vSize = 2;
size = __glXTypeSize(vType) * vSize;
break;
case GL_V3F:
vSize = 3;
size = __glXTypeSize(vType) * vSize;
break;
case GL_C4UB_V2F:
cEnable = GL_TRUE;
cSize = 4;
cType = GL_UNSIGNED_BYTE;
vSize = 2;
vOffset = __glXTypeSize(cType) * cSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_C4UB_V3F:
cEnable = GL_TRUE;
cSize = 4;
cType = GL_UNSIGNED_BYTE;
vSize = 3;
vOffset = __glXTypeSize(vType) * cSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_C3F_V3F:
cEnable = GL_TRUE;
cSize = 3;
cType = GL_FLOAT;
vSize = 3;
vOffset = __glXTypeSize(cType) * cSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_N3F_V3F:
nEnable = GL_TRUE;
vSize = 3;
vOffset = __glXTypeSize(nType) * nSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_C4F_N3F_V3F:
cEnable = GL_TRUE;
cSize = 4;
cType = GL_FLOAT;
nEnable = GL_TRUE;
nOffset = __glXTypeSize(cType) * cSize;
vSize = 3;
vOffset = nOffset + __glXTypeSize(nType) * nSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T2F_V3F:
tEnable = GL_TRUE;
tSize = 2;
vSize = 3;
vOffset = __glXTypeSize(tType) * tSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T4F_V4F:
tEnable = GL_TRUE;
tSize = 4;
vSize = 4;
vOffset = __glXTypeSize(tType) * tSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T2F_C4UB_V3F:
tEnable = GL_TRUE;
tSize = 2;
cEnable = GL_TRUE;
cSize = 4;
cType = GL_UNSIGNED_BYTE;
cOffset = __glXTypeSize(tType) * tSize;
vSize = 3;
vOffset = cOffset + __glXTypeSize(cType) * cSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T2F_C3F_V3F:
tEnable = GL_TRUE;
tSize = 2;
cEnable = GL_TRUE;
cSize = 3;
cType = GL_FLOAT;
cOffset = __glXTypeSize(tType) * tSize;
vSize = 3;
vOffset = cOffset + __glXTypeSize(cType) * cSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T2F_N3F_V3F:
tEnable = GL_TRUE;
tSize = 2;
nEnable = GL_TRUE;
nOffset = __glXTypeSize(tType) * tSize;
vSize = 3;
vOffset = nOffset + __glXTypeSize(nType) * nSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T2F_C4F_N3F_V3F:
tEnable = GL_TRUE;
tSize = 2;
cEnable = GL_TRUE;
cSize = 4;
cType = GL_FLOAT;
cOffset = __glXTypeSize(tType) * tSize;
nEnable = GL_TRUE;
nOffset = cOffset + __glXTypeSize(cType) * cSize;
vSize = 3;
vOffset = nOffset + __glXTypeSize(nType) * nSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
case GL_T4F_C4F_N3F_V4F:
tEnable = GL_TRUE;
tSize = 4;
cEnable = GL_TRUE;
cSize = 4;
cType = GL_FLOAT;
cOffset = __glXTypeSize(tType) * tSize;
nEnable = GL_TRUE;
nOffset = cOffset + __glXTypeSize(cType) * cSize;
vSize = 4;
vOffset = nOffset + __glXTypeSize(nType) * nSize;
size = vOffset + __glXTypeSize(vType) * vSize;
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
trueStride = (stride == 0) ? size : stride;
glDisableClientState(GL_EDGE_FLAG_ARRAY);
glDisableClientState(GL_INDEX_ARRAY);
if (tEnable) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(tSize, tType, trueStride, (const char *)pointer);
} else {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (cEnable) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(cSize, cType, trueStride, (const char *)pointer+cOffset);
} else {
glDisableClientState(GL_COLOR_ARRAY);
}
if (nEnable) {
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(nType, trueStride, (const char *)pointer+nOffset);
} else {
glDisableClientState(GL_NORMAL_ARRAY);
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(vSize, vType, trueStride, (const char *)pointer+vOffset);
}
/*****************************************************************************/
void glArrayElement(GLint i)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertArrayState *va = &gc->state.vertArray;
GLint j;
if (va->edgeFlag.enable == GL_TRUE) {
(*va->edgeFlag.proc)(va->edgeFlag.ptr+i*va->edgeFlag.skip);
}
for (j=0; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
if (va->texCoord[j].enable == GL_TRUE) {
(*va->texCoord[j].proc)(va->texCoord[j].ptr+i*va->texCoord[j].skip);
}
}
if (va->color.enable == GL_TRUE) {
(*va->color.proc)(va->color.ptr+i*va->color.skip);
}
if (va->index.enable == GL_TRUE) {
(*va->index.proc)(va->index.ptr+i*va->index.skip);
}
if (va->normal.enable == GL_TRUE) {
(*va->normal.proc)(va->normal.ptr+i*va->normal.skip);
}
if (va->vertex.enable == GL_TRUE) {
(*va->vertex.proc)(va->vertex.ptr+i*va->vertex.skip);
}
}
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertArrayState *va = &gc->state.vertArray;
const char *vaPtr = NULL, *naPtr = NULL, *caPtr = NULL,
*iaPtr = NULL, *tcaPtr[__GLX_MAX_TEXTURE_UNITS];
const GLboolean *efaPtr = NULL;
GLint i, j;
switch(mode) {
case GL_POINTS:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
case GL_LINES:
case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN:
case GL_TRIANGLES:
case GL_QUAD_STRIP:
case GL_QUADS:
case GL_POLYGON:
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
if (count < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
/*
** Set up pointers for quick array traversal.
*/
if (va->normal.enable == GL_TRUE)
naPtr = va->normal.ptr + first * va->normal.skip;
if (va->color.enable == GL_TRUE)
caPtr = va->color.ptr + first * va->color.skip;
if (va->index.enable == GL_TRUE)
iaPtr = va->index.ptr + first * va->index.skip;
for (j=0; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
if (va->texCoord[j].enable == GL_TRUE)
tcaPtr[j] = va->texCoord[j].ptr + first * va->texCoord[j].skip;
}
if (va->edgeFlag.enable == GL_TRUE)
efaPtr = va->edgeFlag.ptr + first * va->edgeFlag.skip;
if (va->vertex.enable == GL_TRUE)
vaPtr = va->vertex.ptr + first * va->vertex.skip;
glBegin(mode);
for (i = 0; i < count; i++) {
if (va->edgeFlag.enable == GL_TRUE) {
(*va->edgeFlag.proc)(efaPtr);
efaPtr += va->edgeFlag.skip;
}
for (j=0; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
if (va->texCoord[j].enable == GL_TRUE) {
(*va->texCoord[j].proc)(tcaPtr[j]);
tcaPtr[j] += va->texCoord[j].skip;
}
}
if (va->color.enable == GL_TRUE) {
(*va->color.proc)(caPtr);
caPtr += va->color.skip;
}
if (va->index.enable == GL_TRUE) {
(*va->index.proc)(iaPtr);
iaPtr += va->index.skip;
}
if (va->normal.enable == GL_TRUE) {
(*va->normal.proc)(naPtr);
naPtr += va->normal.skip;
}
if (va->vertex.enable == GL_TRUE) {
(*va->vertex.proc)(vaPtr);
vaPtr += va->vertex.skip;
}
}
glEnd();
}
void glDrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXvertArrayState *va = &gc->state.vertArray;
const GLubyte *iPtr1 = NULL;
const GLushort *iPtr2 = NULL;
const GLuint *iPtr3 = NULL;
GLint i, j, offset = 0;
switch (mode) {
case GL_POINTS:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
case GL_LINES:
case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN:
case GL_TRIANGLES:
case GL_QUAD_STRIP:
case GL_QUADS:
case GL_POLYGON:
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
if (count < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
switch (type) {
case GL_UNSIGNED_BYTE:
iPtr1 = (const GLubyte *)indices;
break;
case GL_UNSIGNED_SHORT:
iPtr2 = (const GLushort *)indices;
break;
case GL_UNSIGNED_INT:
iPtr3 = (const GLuint *)indices;
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
glBegin(mode);
for (i = 0; i < count; i++) {
switch (type) {
case GL_UNSIGNED_BYTE:
offset = (GLint)(*iPtr1++);
break;
case GL_UNSIGNED_SHORT:
offset = (GLint)(*iPtr2++);
break;
case GL_UNSIGNED_INT:
offset = (GLint)(*iPtr3++);
break;
}
if (va->edgeFlag.enable == GL_TRUE) {
(*va->edgeFlag.proc)(va->edgeFlag.ptr+(offset*va->edgeFlag.skip));
}
for (j=0; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
if (va->texCoord[j].enable == GL_TRUE) {
(*va->texCoord[j].proc)(va->texCoord[j].ptr+
(offset*va->texCoord[j].skip));
}
}
if (va->color.enable == GL_TRUE) {
(*va->color.proc)(va->color.ptr+(offset*va->color.skip));
}
if (va->index.enable == GL_TRUE) {
(*va->index.proc)(va->index.ptr+(offset*va->index.skip));
}
if (va->normal.enable == GL_TRUE) {
(*va->normal.proc)(va->normal.ptr+(offset*va->normal.skip));
}
if (va->vertex.enable == GL_TRUE) {
(*va->vertex.proc)(va->vertex.ptr+(offset*va->vertex.skip));
}
}
glEnd();
}
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type,
const GLvoid *indices)
{
__GLXcontext *gc = __glXGetCurrentContext();
if (end < start) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
glDrawElements(mode,count,type,indices);
}
void glClientActiveTextureARB(GLenum texture)
{
__GLXcontext *gc = __glXGetCurrentContext();
GLint unit = (GLint) texture - GL_TEXTURE0_ARB;
if (unit < 0 || __GLX_MAX_TEXTURE_UNITS <= unit) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
gc->state.vertArray.activeTexture = unit;
}