Added __glExtensionBiIsEnabled and __GLXcontext::gl_extension_bits. This
enables libGL to query which extension are exported to applications. Refactored array-query functionality (from glGet*v) in src/glx/x11/single2.c. Massive re-write of indirect vertex array support. The most noticable effect is that glDrawElements now generates DrawArrays protocol. The side-effects (and the main reasons for the re-work) are that it is much easier to add support for new arrays (e.g., GL_VERTEX_ATTRIB_ARRAY, GL_WEIGHT_ARRAY_ARB, etc.) and it is much easier to add support for the new DrawArrays protocol (required to support ARB_vertex_buffer_object). These changes were primarilly tested with progs/demos/isosurf.
This commit is contained in:
parent
cb83f62e30
commit
fdb07636f2
|
@ -36,77 +36,34 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include "glxclient.h"
|
||||
#include "indirect_vertex_array.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void __indirect_glEnableClientState(GLenum array)
|
||||
static void
|
||||
do_enable_disable(GLenum array, GLboolean val )
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
unsigned index = 0;
|
||||
|
||||
switch (array) {
|
||||
case GL_COLOR_ARRAY:
|
||||
ENABLE_ARRAY(state, color);
|
||||
break;
|
||||
case GL_EDGE_FLAG_ARRAY:
|
||||
ENABLE_ARRAY(state, edgeFlag);
|
||||
break;
|
||||
case GL_INDEX_ARRAY:
|
||||
ENABLE_ARRAY(state, index);
|
||||
break;
|
||||
case GL_NORMAL_ARRAY:
|
||||
ENABLE_ARRAY(state, normal);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
ENABLE_TEXARRAY(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_VERTEX_ARRAY:
|
||||
ENABLE_ARRAY(state, vertex);
|
||||
break;
|
||||
case GL_SECONDARY_COLOR_ARRAY:
|
||||
ENABLE_ARRAY(state, secondaryColor);
|
||||
break;
|
||||
case GL_FOG_COORD_ARRAY:
|
||||
ENABLE_ARRAY(state, fogCoord);
|
||||
break;
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
if ( array == GL_TEXTURE_COORD_ARRAY ) {
|
||||
index = __glXGetActiveTextureUnit( state );
|
||||
}
|
||||
|
||||
if ( ! __glXSetArrayEnable( state, array, index, val ) ) {
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
void __indirect_glEnableClientState(GLenum array)
|
||||
{
|
||||
do_enable_disable( array, GL_TRUE );
|
||||
}
|
||||
|
||||
void __indirect_glDisableClientState(GLenum array)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
|
||||
switch (array) {
|
||||
case GL_COLOR_ARRAY:
|
||||
DISABLE_ARRAY(state, color);
|
||||
break;
|
||||
case GL_EDGE_FLAG_ARRAY:
|
||||
DISABLE_ARRAY(state, edgeFlag);
|
||||
break;
|
||||
case GL_INDEX_ARRAY:
|
||||
DISABLE_ARRAY(state, index);
|
||||
break;
|
||||
case GL_NORMAL_ARRAY:
|
||||
DISABLE_ARRAY(state, normal);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
DISABLE_TEXARRAY(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_VERTEX_ARRAY:
|
||||
DISABLE_ARRAY(state, vertex);
|
||||
break;
|
||||
case GL_SECONDARY_COLOR_ARRAY:
|
||||
DISABLE_ARRAY(state, secondaryColor);
|
||||
break;
|
||||
case GL_FOG_COORD_ARRAY:
|
||||
DISABLE_ARRAY(state, fogCoord);
|
||||
break;
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
}
|
||||
do_enable_disable( array, GL_FALSE );
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -129,7 +86,7 @@ void __indirect_glPushClientAttrib(GLuint mask)
|
|||
sp->storeUnpack = state->storeUnpack;
|
||||
}
|
||||
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
|
||||
sp->vertArray = state->vertArray;
|
||||
__glXPushArrayState( state );
|
||||
}
|
||||
} else {
|
||||
__glXSetError(gc, GL_STACK_OVERFLOW);
|
||||
|
@ -156,7 +113,7 @@ void __indirect_glPopClientAttrib(void)
|
|||
state->storeUnpack = sp->storeUnpack;
|
||||
}
|
||||
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
|
||||
state->vertArray = sp->vertArray;
|
||||
__glXPopArrayState( state );
|
||||
}
|
||||
|
||||
sp->mask = 0;
|
||||
|
@ -181,5 +138,3 @@ void __glFreeAttributeState(__GLXcontext *gc)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "GL/glxproto.h"
|
||||
#include "GL/internal/glcore.h"
|
||||
#include "glapitable.h"
|
||||
#include "glxextensions.h"
|
||||
#ifdef XTHREADS
|
||||
#include "Xthreads.h"
|
||||
#endif
|
||||
|
@ -220,110 +221,29 @@ typedef struct __GLXattributeRecDEPRECATED {
|
|||
__GLXvertArrayStateDEPRECATED vertArray;
|
||||
} __GLXattributeDEPRECATED;
|
||||
|
||||
typedef struct __GLXvertexArrayPointerStateRec {
|
||||
void (*proc)(const void *);
|
||||
void (*mtex_proc)(GLenum, const void *);
|
||||
const GLubyte *ptr;
|
||||
GLsizei skip;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLsizei stride;
|
||||
} __GLXvertexArrayPointerState;
|
||||
|
||||
/**
|
||||
* Define which entries of \c __GLXvertArrayState::arrays match which
|
||||
* vertex arrays in the client-state vector. These are only the one-of
|
||||
* arrays. See the \c __GLXvertArrayState::arrays documentation for more
|
||||
* details.
|
||||
*
|
||||
* \sa __GLXvertArrayState
|
||||
*/
|
||||
enum {
|
||||
edgeFlag_ARRAY, /**< \c GL_EDGE_FLAG_ARRAY */
|
||||
index_ARRAY, /**< \c GL_INDEX_ARRAY */
|
||||
fogCoord_ARRAY, /**< \c GL_FOG_COORD_ARRAY */
|
||||
secondaryColor_ARRAY, /**< \c GL_SECONDARY_COLOR_ARRAY */
|
||||
color_ARRAY, /**< \c GL_COLOR_ARRAY */
|
||||
normal_ARRAY, /**< \c GL_NORMAL_ARRAY */
|
||||
|
||||
/**
|
||||
* \c GL_VERTEX_ARRAY \b must be last! All of the code for emitting arrays
|
||||
* and array elements is written based on the assumption that the vertex
|
||||
* array is last.
|
||||
*/
|
||||
vertex_ARRAY,
|
||||
|
||||
__GLX_MAX_ARRAYS /**< Place holder entry. */
|
||||
};
|
||||
|
||||
#define ENABLE_ARRAY(state,a) \
|
||||
do { (state)->vertArray.enables |= (1U << (a ## _ARRAY)); } while( 0 )
|
||||
#define DISABLE_ARRAY(state,a) \
|
||||
do { (state)->vertArray.enables &= ~(1U << (a ## _ARRAY)); } while( 0 )
|
||||
#define IS_ARRAY_ENABLED_BY_INDEX(state, i) \
|
||||
(((state)->vertArray.enables & (1U << (i))) != 0)
|
||||
#define IS_ARRAY_ENABLED(state, a) \
|
||||
IS_ARRAY_ENABLED_BY_INDEX(state, a ## _ARRAY)
|
||||
|
||||
#define ENABLE_TEXARRAY(state,a) \
|
||||
do { (state)->vertArray.texture_enables |= (1U << a); } while( 0 )
|
||||
#define DISABLE_TEXARRAY(state,a) \
|
||||
do { (state)->vertArray.texture_enables &= ~(1U << a); } while( 0 )
|
||||
#define IS_TEXARRAY_ENABLED(state, a) \
|
||||
(((state)->vertArray.texture_enables & (1U << a)) != 0)
|
||||
|
||||
/**
|
||||
* Client-side vertex array state.
|
||||
*/
|
||||
typedef struct __GLXvertArrayStateRec {
|
||||
/**
|
||||
* Which client-side arrays are enabled? These are the flag bits for
|
||||
* all of the non-texture coordinate arrays.
|
||||
*/
|
||||
GLuint enables;
|
||||
|
||||
/**
|
||||
* Which of the texture coordinate arrays are enabled?
|
||||
*/
|
||||
GLuint texture_enables;
|
||||
|
||||
/**
|
||||
* State for "one-of" arrays. These are the arrays, such as
|
||||
* GL_COLOR_ARRAY or GL_FOG_COORD_ARRAY for which there is only one
|
||||
* array. There are also "many-of" arrays, such as
|
||||
* GL_TEXTURE_COORD_ARRAY.
|
||||
*/
|
||||
__GLXvertexArrayPointerState arrays[__GLX_MAX_ARRAYS];
|
||||
|
||||
__GLXvertexArrayPointerState texCoord[__GLX_MAX_TEXTURE_UNITS];
|
||||
|
||||
GLint maxElementsVertices;
|
||||
GLint maxElementsIndices;
|
||||
GLint activeTexture;
|
||||
} __GLXvertArrayState;
|
||||
|
||||
typedef struct __GLXattributeRec {
|
||||
GLuint mask;
|
||||
GLuint mask;
|
||||
|
||||
/*
|
||||
** Pixel storage state. Most of the pixel store mode state is kept
|
||||
** here and used by the client code to manage the packing and
|
||||
** unpacking of data sent to/received from the server.
|
||||
*/
|
||||
__GLXpixelStoreMode storePack, storeUnpack;
|
||||
/**
|
||||
* Pixel storage state. Most of the pixel store mode state is kept
|
||||
* here and used by the client code to manage the packing and
|
||||
* unpacking of data sent to/received from the server.
|
||||
*/
|
||||
__GLXpixelStoreMode storePack, storeUnpack;
|
||||
|
||||
/*
|
||||
** Vertex Array storage state. The vertex array component
|
||||
** state is stored here and is used to manage the packing of
|
||||
** DrawArrays data sent to the server.
|
||||
*/
|
||||
__GLXvertArrayState vertArray;
|
||||
|
||||
/**
|
||||
* Is EXT_vertex_array / GL 1.1 DrawArrays protocol specifically
|
||||
* disabled?
|
||||
*/
|
||||
GLboolean NoDrawArraysProtocol;
|
||||
/**
|
||||
* Is EXT_vertex_array / GL 1.1 DrawArrays protocol specifically
|
||||
* disabled?
|
||||
*/
|
||||
GLboolean NoDrawArraysProtocol;
|
||||
|
||||
/**
|
||||
* Vertex Array storage state. The vertex array component
|
||||
* state is stored here and is used to manage the packing of
|
||||
* DrawArrays data sent to the server.
|
||||
*/
|
||||
struct array_state_vector * array_state;
|
||||
} __GLXattribute;
|
||||
|
||||
typedef struct __GLXattributeMachineRec {
|
||||
|
@ -529,7 +449,7 @@ struct __GLXcontextRec {
|
|||
* drivers should NEVER use this data or even care that it exists.
|
||||
*/
|
||||
void * client_state_private;
|
||||
|
||||
|
||||
/**
|
||||
* Stored value for \c glXQueryContext attribute \c GLX_RENDER_TYPE.
|
||||
*/
|
||||
|
@ -546,6 +466,8 @@ struct __GLXcontextRec {
|
|||
int server_major; /**< Major version number. */
|
||||
int server_minor; /**< Minor version number. */
|
||||
/*@}*/
|
||||
|
||||
char gl_extension_bits[ __GL_EXT_BYTES ];
|
||||
};
|
||||
|
||||
#define __glXSetError(gc,code) \
|
||||
|
|
|
@ -375,8 +375,6 @@ GLXContext AllocateGLXContext( Display *dpy )
|
|||
state->storePack.alignment = 4;
|
||||
state->storeUnpack.alignment = 4;
|
||||
|
||||
__glXInitVertexArrayState(gc);
|
||||
|
||||
gc->attributes.stackPointer = &gc->attributes.stack[0];
|
||||
|
||||
/*
|
||||
|
|
|
@ -237,8 +237,6 @@ static const struct extension_info known_gl_extensions[] = {
|
|||
};
|
||||
|
||||
|
||||
#define __GL_EXT_BYTES ((__NUM_GL_EXTS + 7) / 8)
|
||||
|
||||
/* global bit-fields of available extensions and their characteristics */
|
||||
static unsigned char client_glx_support[8];
|
||||
static unsigned char client_glx_only[8];
|
||||
|
@ -493,6 +491,24 @@ __glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a certain extension is enabled in a given context.
|
||||
*
|
||||
*/
|
||||
GLboolean
|
||||
__glExtensionBitIsEnabled( const __GLXcontext * gc, unsigned bit )
|
||||
{
|
||||
GLboolean enabled = GL_FALSE;
|
||||
|
||||
if ( gc != NULL ) {
|
||||
enabled = EXT_ENABLED( bit, gc->gl_extension_bits );
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert a bit-field to a string of supported extensions.
|
||||
*/
|
||||
|
@ -680,6 +696,7 @@ __glXCalculateUsableGLExtensions( __GLXcontext * gc,
|
|||
|
||||
gc->extensions = (unsigned char *)
|
||||
__glXGetStringFromTable( known_gl_extensions, usable );
|
||||
(void) memcpy( gc->gl_extension_bits, usable, sizeof( usable ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -216,16 +216,25 @@ enum {
|
|||
GL_SUN_multi_draw_arrays_bit = GL_EXT_multi_draw_arrays_bit
|
||||
};
|
||||
|
||||
extern GLboolean __glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit );
|
||||
#define __GL_EXT_BYTES ((__NUM_GL_EXTS + 7) / 8)
|
||||
|
||||
struct __GLXscreenConfigsRec;
|
||||
struct __GLXcontextRec;
|
||||
|
||||
extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc, unsigned bit );
|
||||
extern const char * __glXGetClientExtensions( void );
|
||||
extern void __glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
|
||||
extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc,
|
||||
GLboolean display_is_direct_capable, int server_minor_version );
|
||||
extern void __glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name );
|
||||
extern void __glXCalculateUsableGLExtensions( __GLXcontext * gc,
|
||||
extern void __glXScrEnableExtension( struct __GLXscreenConfigsRec *psc, const char * name );
|
||||
extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc,
|
||||
const char * server_string, int major_version, int minor_version );
|
||||
extern void __glXGetGLVersion( int * major_version, int * minor_version );
|
||||
extern char * __glXGetClientGLExtensionString( void );
|
||||
|
||||
extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc,
|
||||
unsigned bit );
|
||||
|
||||
|
||||
/* Source-level backwards compatibility with old drivers. They won't
|
||||
* find the respective functions, though.
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corporation 2004, 2005
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 (including the next
|
||||
* paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* IBM,
|
||||
* AND/OR THEIR SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
#ifndef INDIRECT_VERTEX_ARRAY_H
|
||||
#define INDIRECT_VERTEX_ARRAY_H
|
||||
|
||||
extern const GLuint __glXTypeSize_table[16];
|
||||
|
||||
#define __glXTypeSize(e) ((((e) & ~0x0f) != 0x1400) \
|
||||
? 0 : __glXTypeSize_table[ (e) & 0x0f ])
|
||||
|
||||
extern void __glXArrayDisableAll( __GLXattribute * state );
|
||||
|
||||
extern GLboolean __glXSetArrayEnable( __GLXattribute * state,
|
||||
GLenum key, unsigned index, GLboolean enable );
|
||||
|
||||
extern GLboolean __glXGetArrayEnable( const __GLXattribute * const state,
|
||||
GLenum key, unsigned index, GLintptr * dest );
|
||||
extern GLboolean __glXGetArraySize( const __GLXattribute * const state,
|
||||
GLenum key, unsigned index, GLintptr * dest );
|
||||
extern GLboolean __glXGetArrayType( const __GLXattribute * const state,
|
||||
GLenum key, unsigned index, GLintptr * dest );
|
||||
extern GLboolean __glXGetArrayStride( const __GLXattribute * const state,
|
||||
GLenum key, unsigned index, GLintptr * dest );
|
||||
extern GLboolean __glXGetArrayPointer( const __GLXattribute * const state,
|
||||
GLenum key, unsigned index, void ** dest );
|
||||
|
||||
extern void __glXPushArrayState( __GLXattribute * state );
|
||||
extern void __glXPopArrayState( __GLXattribute * state );
|
||||
|
||||
extern GLuint __glXGetActiveTextureUnit( const __GLXattribute * const state );
|
||||
|
||||
#endif /* INDIRECT_VERTEX_ARRAY_H */
|
|
@ -35,9 +35,11 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "glxclient.h"
|
||||
#include "packsingle.h"
|
||||
#include "glxextensions.h"
|
||||
#include "indirect_vertex_array.h"
|
||||
|
||||
/* Used for GL_ARB_transpose_matrix */
|
||||
static void TransposeMatrixf(GLfloat m[16])
|
||||
|
@ -134,24 +136,106 @@ GLenum __indirect_glGetError(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
#define CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type) \
|
||||
case GL_ ## enum_name ## _ARRAY: \
|
||||
*dest = (gl_type) (IS_ARRAY_ENABLED(state, array)); break
|
||||
#define CASE_ARRAY_SIZE(enum_name,array,dest,gl_type) \
|
||||
case GL_ ## enum_name ## _ARRAY_SIZE: \
|
||||
*dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].size ; break
|
||||
#define CASE_ARRAY_TYPE(enum_name,array,dest,gl_type) \
|
||||
case GL_ ## enum_name ## _ARRAY_TYPE: \
|
||||
*dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].type ; break
|
||||
#define CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type) \
|
||||
case GL_ ## enum_name ## _ARRAY_STRIDE: \
|
||||
*dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].stride ; break
|
||||
|
||||
#define CASE_ARRAY_ALL(enum_name,array,dest,gl_type) \
|
||||
CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type); \
|
||||
CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type); \
|
||||
CASE_ARRAY_TYPE(enum_name,array,dest,gl_type); \
|
||||
CASE_ARRAY_SIZE(enum_name,array,dest,gl_type)
|
||||
/**
|
||||
* Get the selected attribute from the vertex array state vector.
|
||||
*
|
||||
* \returns
|
||||
* On success \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
|
||||
*/
|
||||
static GLboolean
|
||||
get_array_data( __GLXattribute * state, GLenum cap, GLintptr * data )
|
||||
{
|
||||
GLboolean retval = GL_FALSE;
|
||||
const GLint tex_unit = __glXGetActiveTextureUnit( state );
|
||||
|
||||
|
||||
switch( cap ) {
|
||||
case GL_VERTEX_ARRAY:
|
||||
case GL_NORMAL_ARRAY:
|
||||
case GL_COLOR_ARRAY:
|
||||
case GL_INDEX_ARRAY:
|
||||
case GL_EDGE_FLAG_ARRAY:
|
||||
case GL_SECONDARY_COLOR_ARRAY:
|
||||
case GL_FOG_COORD_ARRAY:
|
||||
retval = __glXGetArrayEnable( state, cap, 0, data );
|
||||
break;
|
||||
|
||||
case GL_VERTEX_ARRAY_SIZE:
|
||||
retval = __glXGetArraySize( state, GL_VERTEX_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_COLOR_ARRAY_SIZE:
|
||||
retval = __glXGetArraySize( state, GL_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_SECONDARY_COLOR_ARRAY_SIZE:
|
||||
retval = __glXGetArraySize( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
|
||||
case GL_VERTEX_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_VERTEX_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_NORMAL_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_NORMAL_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_INDEX_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_INDEX_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_COLOR_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_SECONDARY_COLOR_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_FOG_COORD_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_FOG_COORD_ARRAY, 0, data );
|
||||
break;
|
||||
|
||||
case GL_VERTEX_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_VERTEX_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_NORMAL_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_NORMAL_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_INDEX_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_INDEX_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_EDGE_FLAG_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_EDGE_FLAG_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_COLOR_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_SECONDARY_COLOR_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
|
||||
break;
|
||||
case GL_FOG_COORD_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_FOG_COORD_ARRAY, 0, data );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
retval = __glXGetArrayEnable( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE:
|
||||
retval = __glXGetArraySize( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE:
|
||||
retval = __glXGetArrayType( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE:
|
||||
retval = __glXGetArrayStride( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
|
||||
break;
|
||||
|
||||
case GL_MAX_ELEMENTS_VERTICES:
|
||||
case GL_MAX_ELEMENTS_INDICES:
|
||||
retval = GL_TRUE;
|
||||
*data = ~0UL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
|
||||
{
|
||||
|
@ -173,6 +257,8 @@ void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
|
|||
** Error occured; don't modify user's buffer.
|
||||
*/
|
||||
} else {
|
||||
GLintptr data;
|
||||
|
||||
/*
|
||||
** For all the queries listed here, we use the locally stored
|
||||
** values rather than the one returned by the server. Note that
|
||||
|
@ -180,6 +266,12 @@ void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
|
|||
** find out whether it was legal to make a query (it's illegal,
|
||||
** for example, to call a query between glBegin() and glEnd()).
|
||||
*/
|
||||
|
||||
if ( get_array_data( state, val, & data ) ) {
|
||||
*b = (GLboolean) data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case GL_PACK_ROW_LENGTH:
|
||||
*b = (GLboolean)state->storePack.rowLength;
|
||||
|
@ -229,52 +321,11 @@ void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
|
|||
case GL_UNPACK_LSB_FIRST:
|
||||
*b = (GLboolean)state->storeUnpack.lsbFirst;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ALL(VERTEX, vertex, b, GLboolean);
|
||||
|
||||
CASE_ARRAY_ENABLE(NORMAL, normal, b, GLboolean);
|
||||
CASE_ARRAY_TYPE(NORMAL, normal, b, GLboolean);
|
||||
CASE_ARRAY_STRIDE(NORMAL, normal, b, GLboolean);
|
||||
|
||||
CASE_ARRAY_ALL(COLOR, color, b, GLboolean);
|
||||
|
||||
CASE_ARRAY_ENABLE(INDEX, index, b, GLboolean);
|
||||
CASE_ARRAY_TYPE(INDEX, index, b, GLboolean);
|
||||
CASE_ARRAY_STRIDE(INDEX, index, b, GLboolean);
|
||||
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
*b = (GLboolean)IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE:
|
||||
*b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].size;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE:
|
||||
*b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].type;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE:
|
||||
*b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, b, GLboolean);
|
||||
CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, b, GLboolean);
|
||||
|
||||
CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, b, GLboolean);
|
||||
|
||||
CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, b, GLboolean);
|
||||
CASE_ARRAY_TYPE(FOG_COORD, fogCoord, b, GLboolean);
|
||||
CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, b, GLboolean);
|
||||
|
||||
case GL_MAX_ELEMENTS_VERTICES:
|
||||
*b = (GLboolean)state->vertArray.maxElementsVertices;
|
||||
break;
|
||||
case GL_MAX_ELEMENTS_INDICES:
|
||||
*b = (GLboolean)state->vertArray.maxElementsIndices;
|
||||
break;
|
||||
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
*b = (GLboolean)__GL_CLIENT_ATTRIB_STACK_DEPTH;
|
||||
break;
|
||||
case GL_CLIENT_ACTIVE_TEXTURE_ARB:
|
||||
*b = (GLboolean)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
|
||||
case GL_CLIENT_ACTIVE_TEXTURE:
|
||||
*b = (GLboolean)(__glXGetActiveTextureUnit(state) + GL_TEXTURE0);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
@ -314,6 +365,8 @@ void __indirect_glGetDoublev(GLenum val, GLdouble *d)
|
|||
** Error occured; don't modify user's buffer.
|
||||
*/
|
||||
} else {
|
||||
GLintptr data;
|
||||
|
||||
/*
|
||||
** For all the queries listed here, we use the locally stored
|
||||
** values rather than the one returned by the server. Note that
|
||||
|
@ -321,6 +374,12 @@ void __indirect_glGetDoublev(GLenum val, GLdouble *d)
|
|||
** find out whether it was legal to make a query (it's illegal,
|
||||
** for example, to call a query between glBegin() and glEnd()).
|
||||
*/
|
||||
|
||||
if ( get_array_data( state, val, & data ) ) {
|
||||
*d = (GLdouble) data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case GL_PACK_ROW_LENGTH:
|
||||
*d = (GLdouble)state->storePack.rowLength;
|
||||
|
@ -370,52 +429,11 @@ void __indirect_glGetDoublev(GLenum val, GLdouble *d)
|
|||
case GL_UNPACK_LSB_FIRST:
|
||||
*d = (GLdouble)state->storeUnpack.lsbFirst;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ALL(VERTEX, vertex, d, GLdouble);
|
||||
|
||||
CASE_ARRAY_ENABLE(NORMAL, normal, d, GLdouble);
|
||||
CASE_ARRAY_TYPE(NORMAL, normal, d, GLdouble);
|
||||
CASE_ARRAY_STRIDE(NORMAL, normal, d, GLdouble);
|
||||
|
||||
CASE_ARRAY_ALL(COLOR, color, d, GLdouble);
|
||||
|
||||
CASE_ARRAY_ENABLE(INDEX, index, d, GLdouble);
|
||||
CASE_ARRAY_TYPE(INDEX, index, d, GLdouble);
|
||||
CASE_ARRAY_STRIDE(INDEX, index, d, GLdouble);
|
||||
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
*d = (GLdouble) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE:
|
||||
*d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].size;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE:
|
||||
*d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].type;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE:
|
||||
*d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, d, GLdouble);
|
||||
CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, d, GLdouble);
|
||||
|
||||
CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, d, GLdouble);
|
||||
|
||||
CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, d, GLdouble);
|
||||
CASE_ARRAY_TYPE(FOG_COORD, fogCoord, d, GLdouble);
|
||||
CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, d, GLdouble);
|
||||
|
||||
case GL_MAX_ELEMENTS_VERTICES:
|
||||
*d = (GLdouble)state->vertArray.maxElementsVertices;
|
||||
break;
|
||||
case GL_MAX_ELEMENTS_INDICES:
|
||||
*d = (GLdouble)state->vertArray.maxElementsIndices;
|
||||
break;
|
||||
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
*d = (GLdouble)__GL_CLIENT_ATTRIB_STACK_DEPTH;
|
||||
break;
|
||||
case GL_CLIENT_ACTIVE_TEXTURE_ARB:
|
||||
*d = (GLdouble)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
|
||||
case GL_CLIENT_ACTIVE_TEXTURE:
|
||||
*d = (GLdouble)(__glXGetActiveTextureUnit(state) + GL_TEXTURE0);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
@ -455,6 +473,8 @@ void __indirect_glGetFloatv(GLenum val, GLfloat *f)
|
|||
** Error occured; don't modify user's buffer.
|
||||
*/
|
||||
} else {
|
||||
GLintptr data;
|
||||
|
||||
/*
|
||||
** For all the queries listed here, we use the locally stored
|
||||
** values rather than the one returned by the server. Note that
|
||||
|
@ -462,6 +482,12 @@ void __indirect_glGetFloatv(GLenum val, GLfloat *f)
|
|||
** find out whether it was legal to make a query (it's illegal,
|
||||
** for example, to call a query between glBegin() and glEnd()).
|
||||
*/
|
||||
|
||||
if ( get_array_data( state, val, & data ) ) {
|
||||
*f = (GLfloat) data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case GL_PACK_ROW_LENGTH:
|
||||
*f = (GLfloat)state->storePack.rowLength;
|
||||
|
@ -511,52 +537,11 @@ void __indirect_glGetFloatv(GLenum val, GLfloat *f)
|
|||
case GL_UNPACK_LSB_FIRST:
|
||||
*f = (GLfloat)state->storeUnpack.lsbFirst;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ALL(VERTEX, vertex, f, GLfloat);
|
||||
|
||||
CASE_ARRAY_ENABLE(NORMAL, normal, f, GLfloat);
|
||||
CASE_ARRAY_TYPE(NORMAL, normal, f, GLfloat);
|
||||
CASE_ARRAY_STRIDE(NORMAL, normal, f, GLfloat);
|
||||
|
||||
CASE_ARRAY_ALL(COLOR, color, f, GLfloat);
|
||||
|
||||
CASE_ARRAY_ENABLE(INDEX, index, f, GLfloat);
|
||||
CASE_ARRAY_TYPE(INDEX, index, f, GLfloat);
|
||||
CASE_ARRAY_STRIDE(INDEX, index, f, GLfloat);
|
||||
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
*f = (GLfloat) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE:
|
||||
*f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].size;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE:
|
||||
*f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].type;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE:
|
||||
*f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, f, GLfloat);
|
||||
CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, f, GLfloat);
|
||||
|
||||
CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, f, GLfloat);
|
||||
|
||||
CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, f, GLfloat);
|
||||
CASE_ARRAY_TYPE(FOG_COORD, fogCoord, f, GLfloat);
|
||||
CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, f, GLfloat);
|
||||
|
||||
case GL_MAX_ELEMENTS_VERTICES:
|
||||
*f = (GLfloat)state->vertArray.maxElementsVertices;
|
||||
break;
|
||||
case GL_MAX_ELEMENTS_INDICES:
|
||||
*f = (GLfloat)state->vertArray.maxElementsIndices;
|
||||
break;
|
||||
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
*f = (GLfloat)__GL_CLIENT_ATTRIB_STACK_DEPTH;
|
||||
break;
|
||||
case GL_CLIENT_ACTIVE_TEXTURE_ARB:
|
||||
*f = (GLfloat)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
|
||||
case GL_CLIENT_ACTIVE_TEXTURE:
|
||||
*f = (GLfloat)(__glXGetActiveTextureUnit(state) + GL_TEXTURE0);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
@ -596,6 +581,8 @@ void __indirect_glGetIntegerv(GLenum val, GLint *i)
|
|||
** Error occured; don't modify user's buffer.
|
||||
*/
|
||||
} else {
|
||||
GLintptr data;
|
||||
|
||||
/*
|
||||
** For all the queries listed here, we use the locally stored
|
||||
** values rather than the one returned by the server. Note that
|
||||
|
@ -603,6 +590,12 @@ void __indirect_glGetIntegerv(GLenum val, GLint *i)
|
|||
** find out whether it was legal to make a query (it's illegal,
|
||||
** for example, to call a query between glBegin() and glEnd()).
|
||||
*/
|
||||
|
||||
if ( get_array_data( state, val, & data ) ) {
|
||||
*i = (GLint) data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case GL_PACK_ROW_LENGTH:
|
||||
*i = (GLint)state->storePack.rowLength;
|
||||
|
@ -652,52 +645,11 @@ void __indirect_glGetIntegerv(GLenum val, GLint *i)
|
|||
case GL_UNPACK_LSB_FIRST:
|
||||
*i = (GLint)state->storeUnpack.lsbFirst;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ALL(VERTEX, vertex, i, GLint);
|
||||
|
||||
CASE_ARRAY_ENABLE(NORMAL, normal, i, GLint);
|
||||
CASE_ARRAY_TYPE(NORMAL, normal, i, GLint);
|
||||
CASE_ARRAY_STRIDE(NORMAL, normal, i, GLint);
|
||||
|
||||
CASE_ARRAY_ALL(COLOR, color, i, GLint);
|
||||
|
||||
CASE_ARRAY_ENABLE(INDEX, index, i, GLint);
|
||||
CASE_ARRAY_TYPE(INDEX, index, i, GLint);
|
||||
CASE_ARRAY_STRIDE(INDEX, index, i, GLint);
|
||||
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
*i = (GLint) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE:
|
||||
*i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].size;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE:
|
||||
*i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].type;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE:
|
||||
*i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
|
||||
break;
|
||||
|
||||
CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, i, GLint);
|
||||
CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, i, GLint);
|
||||
|
||||
CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, i, GLint);
|
||||
|
||||
CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, i, GLint);
|
||||
CASE_ARRAY_TYPE(FOG_COORD, fogCoord, i, GLint);
|
||||
CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, i, GLint);
|
||||
|
||||
case GL_MAX_ELEMENTS_VERTICES:
|
||||
*i = (GLint)state->vertArray.maxElementsVertices;
|
||||
break;
|
||||
case GL_MAX_ELEMENTS_INDICES:
|
||||
*i = (GLint)state->vertArray.maxElementsIndices;
|
||||
break;
|
||||
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
*i = (GLint)__GL_CLIENT_ATTRIB_STACK_DEPTH;
|
||||
break;
|
||||
case GL_CLIENT_ACTIVE_TEXTURE_ARB:
|
||||
*i = (GLint)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
|
||||
case GL_CLIENT_ACTIVE_TEXTURE:
|
||||
*i = (GLint)(__glXGetActiveTextureUnit(state) + GL_TEXTURE0);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
@ -981,26 +933,28 @@ GLboolean __indirect_glIsEnabled(GLenum cap)
|
|||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
xGLXSingleReply reply;
|
||||
GLboolean retval = 0;
|
||||
GLintptr enable;
|
||||
|
||||
if (!dpy) return 0;
|
||||
|
||||
switch(cap) {
|
||||
case GL_VERTEX_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, vertex);
|
||||
case GL_NORMAL_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, normal);
|
||||
case GL_COLOR_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, color);
|
||||
case GL_INDEX_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, index);
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
return IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
|
||||
case GL_EDGE_FLAG_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, edgeFlag);
|
||||
case GL_SECONDARY_COLOR_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, secondaryColor);
|
||||
case GL_FOG_COORD_ARRAY:
|
||||
return IS_ARRAY_ENABLED(state, fogCoord);
|
||||
case GL_VERTEX_ARRAY:
|
||||
case GL_NORMAL_ARRAY:
|
||||
case GL_COLOR_ARRAY:
|
||||
case GL_INDEX_ARRAY:
|
||||
case GL_EDGE_FLAG_ARRAY:
|
||||
case GL_SECONDARY_COLOR_ARRAY:
|
||||
case GL_FOG_COORD_ARRAY:
|
||||
retval = __glXGetArrayEnable( state, cap, 0, & enable );
|
||||
assert( retval );
|
||||
return (GLboolean) enable;
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
retval = __glXGetArrayEnable( state, GL_TEXTURE_COORD_ARRAY,
|
||||
__glXGetActiveTextureUnit( state ), & enable );
|
||||
assert( retval );
|
||||
return (GLboolean) enable;
|
||||
break;
|
||||
}
|
||||
|
||||
__GLX_SINGLE_LOAD_VARIABLES();
|
||||
|
@ -1021,37 +975,32 @@ void __indirect_glGetPointerv(GLenum pname, void **params)
|
|||
if (!dpy) return;
|
||||
|
||||
switch(pname) {
|
||||
case GL_VERTEX_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ vertex_ARRAY ].ptr;
|
||||
return;
|
||||
case GL_NORMAL_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ normal_ARRAY ].ptr;
|
||||
return;
|
||||
case GL_COLOR_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ color_ARRAY ].ptr;
|
||||
return;
|
||||
case GL_INDEX_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ index_ARRAY ].ptr;
|
||||
return;
|
||||
case GL_TEXTURE_COORD_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.texCoord[state->vertArray.activeTexture].ptr;
|
||||
return;
|
||||
case GL_EDGE_FLAG_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ edgeFlag_ARRAY ].ptr;
|
||||
case GL_VERTEX_ARRAY_POINTER:
|
||||
case GL_NORMAL_ARRAY_POINTER:
|
||||
case GL_COLOR_ARRAY_POINTER:
|
||||
case GL_INDEX_ARRAY_POINTER:
|
||||
case GL_EDGE_FLAG_ARRAY_POINTER:
|
||||
__glXGetArrayPointer( state, pname - GL_VERTEX_ARRAY_POINTER
|
||||
+ GL_VERTEX_ARRAY,
|
||||
0, params );
|
||||
return;
|
||||
case GL_SECONDARY_COLOR_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ secondaryColor_ARRAY ].ptr;
|
||||
case GL_TEXTURE_COORD_ARRAY_POINTER:
|
||||
__glXGetArrayPointer( state, GL_TEXTURE_COORD_ARRAY,
|
||||
__glXGetActiveTextureUnit( state ), params );
|
||||
return;
|
||||
case GL_FOG_COORD_ARRAY_POINTER:
|
||||
*params = (void *)state->vertArray.arrays[ fogCoord_ARRAY ].ptr;
|
||||
case GL_SECONDARY_COLOR_ARRAY_POINTER:
|
||||
case GL_FOG_COORD_ARRAY_POINTER:
|
||||
__glXGetArrayPointer( state, pname - GL_FOG_COORD_ARRAY_POINTER
|
||||
+ GL_FOG_COORD_ARRAY,
|
||||
0, params );
|
||||
return;
|
||||
case GL_FEEDBACK_BUFFER_POINTER:
|
||||
case GL_FEEDBACK_BUFFER_POINTER:
|
||||
*params = (void *)gc->feedbackBuf;
|
||||
return;
|
||||
case GL_SELECTION_BUFFER_POINTER:
|
||||
case GL_SELECTION_BUFFER_POINTER:
|
||||
*params = (void *)gc->selectBuf;
|
||||
return;
|
||||
default:
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,134 +34,10 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "glxclient.h"
|
||||
#include "packrender.h"
|
||||
#include "indirect.h"
|
||||
#include <string.h>
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include "indirect_vertex_array.h"
|
||||
|
||||
/* macros for setting function pointers */
|
||||
#define __GL_VERTEX_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
if (size == 2) \
|
||||
vertexPointer->proc = (void (*)(const void *))__indirect_glVertex2##let##v; \
|
||||
else if (size == 3) \
|
||||
vertexPointer->proc = (void (*)(const void *))__indirect_glVertex3##let##v; \
|
||||
else if (size == 4) \
|
||||
vertexPointer->proc = (void (*)(const void *))__indirect_glVertex4##let##v; \
|
||||
break
|
||||
|
||||
#define __GL_NORMAL_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
normalPointer->proc = (void (*)(const void *))__indirect_glNormal3##let##v; \
|
||||
break
|
||||
|
||||
#define __GL_COLOR_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
if (size == 3) \
|
||||
colorPointer->proc = (void (*)(const void *))__indirect_glColor3##let##v; \
|
||||
else if (size == 4)\
|
||||
colorPointer->proc = (void (*)(const void *))__indirect_glColor4##let##v; \
|
||||
break
|
||||
|
||||
#define __GL_SEC_COLOR_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
seccolorPointer->proc = (void (*)(const void *))__indirect_glSecondaryColor3##let##vEXT; \
|
||||
|
||||
#define __GL_FOG_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
fogPointer->proc = (void (*)(const void *))__indirect_glFogCoord##let##vEXT; \
|
||||
|
||||
#define __GL_INDEX_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
indexPointer->proc = (void (*)(const void *))__indirect_glIndex##let##v; \
|
||||
break
|
||||
|
||||
#define __GL_TEXTURE_FUNC(NAME, let) \
|
||||
case GL_##NAME: \
|
||||
if (size == 1) { \
|
||||
texCoordPointer->proc = (void (*)(const void *))__indirect_glTexCoord1##let##v; \
|
||||
texCoordPointer->mtex_proc = (void (*)(GLenum, const void *))__indirect_glMultiTexCoord1##let##vARB; \
|
||||
} else if (size == 2) { \
|
||||
texCoordPointer->proc = (void (*)(const void *))__indirect_glTexCoord2##let##v; \
|
||||
texCoordPointer->mtex_proc = (void (*)(GLenum, const void *))__indirect_glMultiTexCoord2##let##vARB; \
|
||||
} else if (size == 3) { \
|
||||
texCoordPointer->proc = (void (*)(const void *))__indirect_glTexCoord3##let##v; \
|
||||
texCoordPointer->mtex_proc = (void (*)(GLenum, const void *))__indirect_glMultiTexCoord2##let##vARB; \
|
||||
} else if (size == 4) { \
|
||||
texCoordPointer->proc = (void (*)(const void *))__indirect_glTexCoord4##let##v; \
|
||||
texCoordPointer->mtex_proc = (void (*)(GLenum, const void *))__indirect_glMultiTexCoord4##let##vARB; \
|
||||
} break
|
||||
|
||||
/**
|
||||
* Table of sizes, in bytes, of a GL types. All of the type enums are be in
|
||||
* the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
|
||||
* \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
|
||||
* type enums masked with 0x0f.
|
||||
*
|
||||
* \notes
|
||||
* \c GL_HAVE_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
|
||||
* \c GL_3_BYTES, or \c GL_4_BYTES.
|
||||
*/
|
||||
static const GLuint __glXTypeSize_table[16] = {
|
||||
1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define __glXTypeSize(e) ((((e) & ~0x0f) != 0x1400) \
|
||||
? 0 : __glXTypeSize_table[ (e) & 0x0f ])
|
||||
|
||||
|
||||
/**
|
||||
* Initialize vertex array state for a GLX context.
|
||||
*
|
||||
* \param gc GLX context whose vertex array state is to be initialized.
|
||||
*
|
||||
* \todo
|
||||
* Someone is going to have to check the spec. This function takes greate
|
||||
* care to initialize the \c size and \c type fields to "correct" values
|
||||
* for each array. I'm not sure this is necessary. I think it should be
|
||||
* acceptable to just \c memset the whole \c arrays and \c texCoord arrays
|
||||
* to zero and be done with it. The spec may say something to the contrary,
|
||||
* however.
|
||||
*/
|
||||
void __glXInitVertexArrayState(__GLXcontext *gc)
|
||||
{
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertArrayState *va = &state->vertArray;
|
||||
GLint i;
|
||||
|
||||
va->enables = 0;
|
||||
va->texture_enables = 0;
|
||||
|
||||
for ( i = 0 ; i < __GLX_MAX_ARRAYS ; i++ ) {
|
||||
va->arrays[ i ].proc = NULL;
|
||||
va->arrays[ i ].skip = 0;
|
||||
va->arrays[ i ].ptr = 0;
|
||||
va->arrays[ i ].size = 1;
|
||||
va->arrays[ i ].type = GL_FLOAT;
|
||||
va->arrays[ i ].stride = 0;
|
||||
}
|
||||
|
||||
va->arrays[ edgeFlag_ARRAY ].type = GL_UNSIGNED_BYTE;;
|
||||
|
||||
va->arrays[ secondaryColor_ARRAY ].size = 3;
|
||||
va->arrays[ color_ARRAY ].size = 4;
|
||||
va->arrays[ normal_ARRAY ].size = 3;
|
||||
va->arrays[ vertex_ARRAY ].size = 4;
|
||||
|
||||
for ( i = 0 ; i < __GLX_MAX_TEXTURE_UNITS ; i++ ) {
|
||||
va->texCoord[ i ].proc = NULL;
|
||||
va->texCoord[ i ].skip = 0;
|
||||
va->texCoord[ i ].ptr = 0;
|
||||
va->texCoord[ i ].size = 4;
|
||||
va->texCoord[ i ].type = GL_FLOAT;
|
||||
va->texCoord[ i ].stride = 0;
|
||||
}
|
||||
|
||||
va->maxElementsVertices = INT_MAX;
|
||||
va->maxElementsIndices = INT_MAX;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -214,296 +90,6 @@ void __indirect_glVertexPointerEXT(GLint size, GLenum type, GLsizei stride,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *vertexPointer = &state->vertArray.arrays[ vertex_ARRAY ];
|
||||
|
||||
/* 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 __indirect_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *normalPointer = &state->vertArray.arrays[ normal_ARRAY ];
|
||||
|
||||
/* 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 __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *colorPointer = &state->vertArray.arrays[ color_ARRAY ];
|
||||
|
||||
/* 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 __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *indexPointer = &state->vertArray.arrays[ index_ARRAY ];
|
||||
|
||||
/* 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 __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *texCoordPointer =
|
||||
&state->vertArray.texCoord[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 __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *edgeFlagPointer = &state->vertArray.arrays[ edgeFlag_ARRAY ];
|
||||
|
||||
/* Check arguments */
|
||||
if (stride < 0) {
|
||||
__glXSetError(gc, GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose appropriate api proc */
|
||||
edgeFlagPointer->proc = (void (*)(const void *))__indirect_glEdgeFlagv;
|
||||
|
||||
edgeFlagPointer->stride = stride;
|
||||
edgeFlagPointer->ptr = pointer;
|
||||
|
||||
/* Set internal state */
|
||||
if (stride == 0) {
|
||||
edgeFlagPointer->skip = sizeof(GLboolean);
|
||||
} else {
|
||||
edgeFlagPointer->skip = stride;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void __indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid * pointer )
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *seccolorPointer = &state->vertArray.arrays[ secondaryColor_ARRAY ];
|
||||
|
||||
/* Check arguments */
|
||||
if ( (stride < 0) || (size != 3) ) {
|
||||
__glXSetError(gc, GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose appropriate api proc */
|
||||
switch(type) {
|
||||
__GL_SEC_COLOR_FUNC(BYTE, b);
|
||||
__GL_SEC_COLOR_FUNC(UNSIGNED_BYTE, ub);
|
||||
__GL_SEC_COLOR_FUNC(SHORT, s);
|
||||
__GL_SEC_COLOR_FUNC(UNSIGNED_SHORT, us);
|
||||
__GL_SEC_COLOR_FUNC(INT, i);
|
||||
__GL_SEC_COLOR_FUNC(UNSIGNED_INT, ui);
|
||||
__GL_SEC_COLOR_FUNC(FLOAT, f);
|
||||
__GL_SEC_COLOR_FUNC(DOUBLE, d);
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
seccolorPointer->size = size;
|
||||
seccolorPointer->type = type;
|
||||
seccolorPointer->stride = stride;
|
||||
seccolorPointer->ptr = pointer;
|
||||
|
||||
/* Set internal state */
|
||||
if (stride == 0) {
|
||||
seccolorPointer->skip = size * __glXTypeSize(type);
|
||||
} else {
|
||||
seccolorPointer->skip = stride;
|
||||
}
|
||||
}
|
||||
|
||||
void __indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertexArrayPointerState *fogPointer = &state->vertArray.arrays[ fogCoord_ARRAY ];
|
||||
|
||||
/* Check arguments */
|
||||
if (stride < 0) {
|
||||
__glXSetError(gc, GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose appropriate api proc */
|
||||
switch(type) {
|
||||
__GL_FOG_FUNC(FLOAT, f);
|
||||
__GL_FOG_FUNC(DOUBLE, d);
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
fogPointer->size = 1;
|
||||
fogPointer->type = type;
|
||||
fogPointer->stride = stride;
|
||||
fogPointer->ptr = pointer;
|
||||
|
||||
/* Set internal state */
|
||||
if (stride == 0) {
|
||||
fogPointer->skip = __glXTypeSize(type);
|
||||
} else {
|
||||
fogPointer->skip = stride;
|
||||
}
|
||||
}
|
||||
|
||||
void __indirect_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
|
@ -642,8 +228,8 @@ void __indirect_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid
|
|||
|
||||
trueStride = (stride == 0) ? size : stride;
|
||||
|
||||
state->vertArray.enables = 0;
|
||||
state->vertArray.texture_enables = 0;
|
||||
__glXArrayDisableAll( state );
|
||||
|
||||
if (tEnable) {
|
||||
__indirect_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
__indirect_glTexCoordPointer(tSize, tType, trueStride, (const char *)pointer);
|
||||
|
@ -659,543 +245,3 @@ void __indirect_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid
|
|||
__indirect_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
__indirect_glVertexPointer(vSize, vType, trueStride, (const char *)pointer+vOffset);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void __indirect_glArrayElement(GLint i)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertArrayState *va = &state->vertArray;
|
||||
GLint j;
|
||||
|
||||
|
||||
if (IS_TEXARRAY_ENABLED(state, 0)) {
|
||||
(*va->texCoord[0].proc)(va->texCoord[0].ptr+i*va->texCoord[0].skip);
|
||||
}
|
||||
|
||||
/* Multitexturing is handled specially because the protocol
|
||||
* requires an extra parameter.
|
||||
*/
|
||||
for (j=1; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
|
||||
if (IS_TEXARRAY_ENABLED(state, j)) {
|
||||
(*va->texCoord[j].mtex_proc)(GL_TEXTURE0 + j, va->texCoord[j].ptr+i*va->texCoord[j].skip);
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < __GLX_MAX_ARRAYS ; j++ ) {
|
||||
if (IS_ARRAY_ENABLED_BY_INDEX(state, j)) {
|
||||
(*va->arrays[ j ].proc)(va->arrays[ j ].ptr+i*va->arrays[ j ].skip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct array_info {
|
||||
__GLXdispatchDrawArraysComponentHeader ai;
|
||||
GLsizei bytes;
|
||||
const GLubyte *ptr;
|
||||
GLsizei skip;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a \c array_info structure for each array that is enabled in
|
||||
* \c state. Determine how many arrays are enabled, and store the result
|
||||
* in \c num_arrays. Determine how big each vertex is, and store the result
|
||||
* in \c total_vertex_size.
|
||||
*
|
||||
* \returns The size of the final request. This is the size, in bytes, of
|
||||
* the DrawArrays header, the ARRAY_INFO structures, and all the vertex data.
|
||||
* This value \b assumes a \c X_GLXRender command is used. The true size
|
||||
* will be 4 bytes larger if a \c X_GLXRenderLarge command is used.
|
||||
*/
|
||||
static GLuint
|
||||
prep_arrays(const __GLXattribute * const state, struct array_info * arrays,
|
||||
GLint count,
|
||||
GLsizei *num_arrays, GLsizei *total_vertex_size)
|
||||
{
|
||||
GLsizei na = 0;
|
||||
GLsizei vs = 0;
|
||||
|
||||
#define ASSIGN_ARRAY_INFO(state, enum_name, arr) \
|
||||
do { \
|
||||
arrays[ na ].ai.datatype = state->vertArray. arr .type ; \
|
||||
arrays[ na ].ai.numVals = state->vertArray. arr .size ; \
|
||||
arrays[ na ].ai.component = GL_ ## enum_name ## _ARRAY; \
|
||||
\
|
||||
arrays[ na ].bytes = state->vertArray. arr .size \
|
||||
* __glXTypeSize( state->vertArray. arr .type ); \
|
||||
arrays[ na ].ptr = state->vertArray. arr .ptr; \
|
||||
arrays[ na ].skip = state->vertArray. arr .skip; \
|
||||
\
|
||||
vs += __GLX_PAD(arrays[ na ].bytes); \
|
||||
na++; \
|
||||
} while( 0 )
|
||||
|
||||
#define ADD_ARRAY_IF_ENABLED(state, enum_name, arr) \
|
||||
do { if ( IS_ARRAY_ENABLED(state, arr) ) { \
|
||||
ASSIGN_ARRAY_INFO(state, enum_name, arrays[ arr ## _ARRAY ] ); \
|
||||
} } while( 0 )
|
||||
|
||||
ADD_ARRAY_IF_ENABLED(state, VERTEX, vertex);
|
||||
ADD_ARRAY_IF_ENABLED(state, NORMAL, normal);
|
||||
ADD_ARRAY_IF_ENABLED(state, COLOR, color);
|
||||
ADD_ARRAY_IF_ENABLED(state, SECONDARY_COLOR, secondaryColor);
|
||||
ADD_ARRAY_IF_ENABLED(state, FOG_COORD, fogCoord);
|
||||
ADD_ARRAY_IF_ENABLED(state, EDGE_FLAG, edgeFlag);
|
||||
ADD_ARRAY_IF_ENABLED(state, INDEX, index);
|
||||
|
||||
/* The standard DrawArrays protocol *only* supports a single array of
|
||||
* texture coordinates.
|
||||
*/
|
||||
if ( IS_TEXARRAY_ENABLED(state, 0) ) {
|
||||
ASSIGN_ARRAY_INFO(state, TEXTURE_COORD, texCoord[0]);
|
||||
}
|
||||
|
||||
*num_arrays = na;
|
||||
*total_vertex_size = vs;
|
||||
|
||||
return __GLX_PAD((__GLX_COMPONENT_HDR_SIZE * na)
|
||||
+ (vs * count)
|
||||
+ __GLX_DRAWARRAYS_CMD_HDR_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emits the vertex data for the DrawArrays GLX protocol.
|
||||
*/
|
||||
static GLsizei
|
||||
emit_vertex(GLubyte * data, const struct array_info * arrays,
|
||||
GLsizei num_arrays, GLint element, GLsizei offset)
|
||||
{
|
||||
GLint i;
|
||||
|
||||
for ( i = 0 ; i < num_arrays ; i++ ) {
|
||||
(void) memcpy( data + offset,
|
||||
arrays[i].ptr + (arrays[i].skip * element),
|
||||
arrays[i].bytes );
|
||||
offset += __GLX_PAD(arrays[i].bytes);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_header(GLubyte * pc, const struct array_info * arrays,
|
||||
GLsizei num_arrays, GLsizei count, GLenum mode)
|
||||
{
|
||||
__GLXdispatchDrawArraysComponentHeader *arrayInfo;
|
||||
GLsizei i;
|
||||
|
||||
__GLX_PUT_LONG(0, count);
|
||||
__GLX_PUT_LONG(4, num_arrays);
|
||||
__GLX_PUT_LONG(8, mode);
|
||||
|
||||
arrayInfo = (__GLXdispatchDrawArraysComponentHeader *)
|
||||
(pc + __GLX_DRAWARRAYS_HDR_SIZE);
|
||||
|
||||
|
||||
/* Write the ARRAY_INFO data.
|
||||
*/
|
||||
|
||||
for ( i = 0 ; i < num_arrays ; i++ ) {
|
||||
arrayInfo[i] = arrays[i].ai;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit GLX DrawArrays protocol using a GLXRender packet.
|
||||
*/
|
||||
static void
|
||||
emit_Render_DrawArrays(__GLXcontext * gc, const struct array_info * arrays,
|
||||
GLsizei first, GLsizei count, GLsizei num_arrays, GLenum mode,
|
||||
GLsizei cmdlen, GLsizei total_vertex_size)
|
||||
{
|
||||
GLubyte * pc = gc->pc;
|
||||
GLsizei offset;
|
||||
GLsizei i;
|
||||
|
||||
__GLX_BEGIN_VARIABLE(X_GLrop_DrawArrays, cmdlen);
|
||||
emit_header(pc + 4, arrays, num_arrays, count, mode);
|
||||
|
||||
|
||||
/* Write the actual array data.
|
||||
*/
|
||||
|
||||
offset = __GLX_DRAWARRAYS_CMD_HDR_SIZE
|
||||
+ (num_arrays * __GLX_COMPONENT_HDR_SIZE);
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
offset = emit_vertex(pc, arrays, num_arrays, i + first, offset);
|
||||
}
|
||||
|
||||
__GLX_END(cmdlen);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit GLX DrawArrays protocol using a GLXRenderLarge packet.
|
||||
*/
|
||||
static void
|
||||
emit_RenderLarge_DrawArrays(__GLXcontext * gc, const struct array_info * arrays,
|
||||
GLsizei first, GLsizei count, GLsizei num_arrays, GLenum mode,
|
||||
GLsizei cmdlen, GLsizei total_vertex_size)
|
||||
{
|
||||
GLubyte * pc = gc->pc;
|
||||
GLsizei offset;
|
||||
GLsizei i;
|
||||
GLint maxSize;
|
||||
GLint totalRequests;
|
||||
GLint requestNumber;
|
||||
GLsizei elements_per_request;
|
||||
|
||||
|
||||
/* Calculate the maximum amount of data can be stuffed into a single
|
||||
* packet. sz_xGLXRenderReq is added because bufSize is the maximum
|
||||
* packet size minus sz_xGLXRenderReq.
|
||||
*
|
||||
* The important value here is elements_per_request. This is the number
|
||||
* of complete array elements that will fit in a single buffer. There
|
||||
* may be some wasted space at the end of the buffer, but splitting
|
||||
* elements across buffer boundries would be painful.
|
||||
*/
|
||||
|
||||
maxSize = (gc->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq;
|
||||
|
||||
elements_per_request = maxSize / total_vertex_size;
|
||||
|
||||
totalRequests = ((count + (elements_per_request - 1))
|
||||
/ elements_per_request) + 1;
|
||||
|
||||
|
||||
/* Fill in the header data and send it away.
|
||||
*/
|
||||
|
||||
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_DrawArrays, cmdlen+4);
|
||||
emit_header(pc + 8, arrays, num_arrays, count, mode);
|
||||
|
||||
gc->pc = pc + (__GLX_DRAWARRAYS_CMD_HDR_SIZE + 4)
|
||||
+ (__GLX_COMPONENT_HDR_SIZE * num_arrays);
|
||||
__glXSendLargeChunk(gc, 1, totalRequests, gc->buf, gc->pc - gc->buf);
|
||||
|
||||
|
||||
/* Write the actual array data.
|
||||
*/
|
||||
offset = 0;
|
||||
requestNumber = 2;
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
if ( i == elements_per_request ) {
|
||||
__glXSendLargeChunk(gc, requestNumber, totalRequests,
|
||||
gc->buf, offset);
|
||||
requestNumber++;
|
||||
offset = 0;
|
||||
|
||||
count -= i;
|
||||
first += i;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
offset = emit_vertex(gc->buf, arrays, num_arrays, i + first, offset);
|
||||
}
|
||||
|
||||
/* If the buffer isn't empty, emit the last, partial request.
|
||||
*/
|
||||
if ( offset != 0 ) {
|
||||
assert(requestNumber == totalRequests);
|
||||
__glXSendLargeChunk(gc, requestNumber, totalRequests, gc->buf, offset);
|
||||
}
|
||||
|
||||
gc->pc = gc->buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit DrawArrays protocol. This function acts as a switch betteen
|
||||
* \c emit_Render_DrawArrays and \c emit_RenderLarge_DrawArrays depending
|
||||
* on how much array data is to be sent.
|
||||
*/
|
||||
static void
|
||||
emit_DrawArraysEXT(const __GLXattribute * const state,
|
||||
GLint first, GLsizei count, GLenum mode)
|
||||
{
|
||||
struct array_info arrays[32];
|
||||
GLsizei num_arrays;
|
||||
GLsizei total_vertex_size;
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
GLuint cmdlen;
|
||||
|
||||
|
||||
/* Determine how big the final request will be. This depends on a number
|
||||
* of factors. It depends on how many array elemets there are (which is
|
||||
* the passed-in 'count'), how many arrays are enabled, how many elements
|
||||
* are in each array entry, and what the types are for each array.
|
||||
*/
|
||||
|
||||
cmdlen = prep_arrays(state, arrays, count, & num_arrays,
|
||||
& total_vertex_size);
|
||||
|
||||
|
||||
/* If the data payload and the protocol header is too large for a Render
|
||||
* command, use a RenderLarge command.
|
||||
*/
|
||||
if (cmdlen > gc->maxSmallRenderCommandSize) {
|
||||
emit_RenderLarge_DrawArrays(gc, arrays, first, count, num_arrays,
|
||||
mode, cmdlen, total_vertex_size);
|
||||
}
|
||||
else {
|
||||
emit_Render_DrawArrays(gc, arrays, first, count, num_arrays,
|
||||
mode, cmdlen, total_vertex_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit a DrawArrays call using the old "protocol." This isn't really
|
||||
* DrawArrays protocol at all. It just simulates DrawArrays by using
|
||||
* immediate-mode vertex calls. Very, very slow for large arrays, but works
|
||||
* with every GLX server.
|
||||
*/
|
||||
static void
|
||||
emit_DrawArrays_old(const __GLXattribute * const state,
|
||||
GLint first, GLsizei count, GLenum mode)
|
||||
{
|
||||
const __GLXvertArrayState *va = &state->vertArray;
|
||||
const GLubyte *vaPtr[__GLX_MAX_ARRAYS];
|
||||
const GLubyte *tcaPtr[__GLX_MAX_TEXTURE_UNITS];
|
||||
GLint i, j;
|
||||
|
||||
/*
|
||||
** Set up pointers for quick array traversal.
|
||||
*/
|
||||
|
||||
(void) memset( vaPtr, 0, sizeof(vaPtr) );
|
||||
(void) memset( tcaPtr, 0, sizeof(tcaPtr) );
|
||||
|
||||
for ( j = 0 ; j < __GLX_MAX_ARRAYS ; j++ ) {
|
||||
if (IS_ARRAY_ENABLED_BY_INDEX(state, j)) {
|
||||
vaPtr[ j ] = va->arrays[ j ].ptr + first * va->arrays[ j ].skip;
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < __GLX_MAX_TEXTURE_UNITS ; j++ ) {
|
||||
if (IS_TEXARRAY_ENABLED(state, j))
|
||||
tcaPtr[ j ] = va->texCoord[ j ].ptr + first * va->texCoord[ j ].skip;
|
||||
}
|
||||
|
||||
__indirect_glBegin(mode);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (IS_TEXARRAY_ENABLED(state, 0)) {
|
||||
(*va->texCoord[0].proc)(tcaPtr[0]);
|
||||
tcaPtr[0] += va->texCoord[0].skip;
|
||||
}
|
||||
|
||||
/* Multitexturing is handled specially because the protocol
|
||||
* requires an extra parameter.
|
||||
*/
|
||||
for (j=1; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
|
||||
if (IS_TEXARRAY_ENABLED(state, j)) {
|
||||
(*va->texCoord[j].mtex_proc)(GL_TEXTURE0 + j, tcaPtr[j]);
|
||||
tcaPtr[j] += va->texCoord[j].skip;
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < __GLX_MAX_ARRAYS ; j++ ) {
|
||||
if (IS_ARRAY_ENABLED_BY_INDEX(state, j)) {
|
||||
(*va->arrays[ j ].proc)(vaPtr[ j ]);
|
||||
vaPtr[ j ] += va->arrays[ j ].skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
__indirect_glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate that the \c mode and \c count parameters to \c glDrawArrays or
|
||||
* \c glDrawElements are valid. If the arguments are not valid, then an
|
||||
* error code is set in the GLX context.
|
||||
*
|
||||
* \returns \c GL_TRUE if the arguments are valide, \c GL_FALSE if they are
|
||||
* not.
|
||||
*/
|
||||
static GLboolean
|
||||
glx_validate_array_args(__GLXcontext *gc, GLenum mode, GLsizei count)
|
||||
{
|
||||
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 GL_FALSE;
|
||||
}
|
||||
|
||||
if (count < 0) {
|
||||
__glXSetError(gc, GL_INVALID_VALUE);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
const __GLXattribute * state =
|
||||
(const __GLXattribute *)(gc->client_state_private);
|
||||
|
||||
|
||||
if ( ! glx_validate_array_args(gc, mode, count) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The "true" DrawArrays protocol does not support generic attributes,
|
||||
* multiple vertex arrays, or multiple texture coordinate arrays.
|
||||
*/
|
||||
if ( state->NoDrawArraysProtocol
|
||||
|| (state->vertArray.texture_enables > 1) ) {
|
||||
emit_DrawArrays_old(state, first, count, mode);
|
||||
}
|
||||
else {
|
||||
emit_DrawArraysEXT(state, first, count, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \todo Modify this to use the "true" DrawArrays protocol if possible. This
|
||||
* would probably require refactoring out parts of \c emit_DrawArraysEXT into
|
||||
* more general functions that could be used in either place.
|
||||
*/
|
||||
void __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
__GLXvertArrayState *va = &state->vertArray;
|
||||
const GLubyte *iPtr1 = NULL;
|
||||
const GLushort *iPtr2 = NULL;
|
||||
const GLuint *iPtr3 = NULL;
|
||||
GLint i, j, offset = 0;
|
||||
|
||||
if ( ! glx_validate_array_args(gc, mode, count) ) {
|
||||
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;
|
||||
}
|
||||
|
||||
__indirect_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 (IS_TEXARRAY_ENABLED(state, 0)) {
|
||||
(*va->texCoord[0].proc)(va->texCoord[0].ptr+
|
||||
(offset*va->texCoord[0].skip));
|
||||
}
|
||||
|
||||
/* Multitexturing is handled specially because the protocol
|
||||
* requires an extra parameter.
|
||||
*/
|
||||
for (j=1; j<__GLX_MAX_TEXTURE_UNITS; ++j) {
|
||||
if (IS_TEXARRAY_ENABLED(state, j)) {
|
||||
(*va->texCoord[j].mtex_proc)(GL_TEXTURE0 + j,
|
||||
va->texCoord[j].ptr+
|
||||
(offset*va->texCoord[j].skip));
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < __GLX_MAX_ARRAYS ; j++ ) {
|
||||
if (IS_ARRAY_ENABLED_BY_INDEX(state, j)) {
|
||||
(*va->arrays[ j ].proc)(va->arrays[ j ].ptr
|
||||
+(offset*va->arrays[ j ].skip));
|
||||
}
|
||||
}
|
||||
}
|
||||
__indirect_glEnd();
|
||||
}
|
||||
|
||||
void __indirect_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;
|
||||
}
|
||||
|
||||
__indirect_glDrawElements(mode,count,type,indices);
|
||||
}
|
||||
|
||||
void __indirect_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count,
|
||||
GLsizei primcount)
|
||||
{
|
||||
GLsizei i;
|
||||
|
||||
for(i=0; i<primcount; i++) {
|
||||
if ( count[i] > 0 ) {
|
||||
__indirect_glDrawArrays( mode, first[i], count[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count,
|
||||
GLenum type, const GLvoid ** indices,
|
||||
GLsizei primcount)
|
||||
{
|
||||
GLsizei i;
|
||||
|
||||
for(i=0; i<primcount; i++) {
|
||||
if ( count[i] > 0 ) {
|
||||
__indirect_glDrawElements( mode, count[i], type, indices[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __indirect_glClientActiveTextureARB(GLenum texture)
|
||||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
GLint unit = (GLint) texture - GL_TEXTURE0;
|
||||
|
||||
if (unit < 0 || __GLX_MAX_TEXTURE_UNITS <= unit) {
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
state->vertArray.activeTexture = unit;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue