mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-20 03:30:36 +02:00
This is a major re-work of the __indirect_glInterleavedArrays routine. The
big, ugly, error prone switch-statement is replaced with a compact table. I also added numerous comments, including a comment explaining how the format parameter is validated. Explicitly pass GL_FLOAT as the type in the cases where that is the only possible value (e.g., everywhere except the call to glColorPointer). Validate that stride is >= 0. Tested with all modes (including the two error modes) of progs/tests/interleave.c. Bug: #5001, #5058 Reviewed by: Brian Paul
This commit is contained in:
parent
96f216565e
commit
5910dfacf1
1 changed files with 90 additions and 134 deletions
|
|
@ -94,154 +94,110 @@ void __indirect_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid
|
|||
{
|
||||
__GLXcontext *gc = __glXGetCurrentContext();
|
||||
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
|
||||
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:
|
||||
#define NONE {0, 0, 0}
|
||||
#define F(x) {GL_FLOAT, x, x * sizeof(GLfloat)}
|
||||
#define UB4 {GL_UNSIGNED_BYTE, 4, 4 * sizeof(GLubyte)}
|
||||
|
||||
/* Each row in this array describes the elements of a particular
|
||||
* interleaved array mode. Each column describes, in the order in which
|
||||
* they appear in the interleaved arrays, one of the four possible types
|
||||
* of vertex data that can appear in an interleaved array.
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* The enum describing the GL type, as would be passed to the
|
||||
* appropriate gl*Pointer function.
|
||||
*/
|
||||
GLushort type;
|
||||
|
||||
/**
|
||||
* Number of elements in the subarray, as would be passed (as the
|
||||
* \c size parameter) to the appropriate gl*Pointer function.
|
||||
*/
|
||||
GLubyte count;
|
||||
|
||||
/**
|
||||
* True size of a single element in the subarray, as would be passed
|
||||
* (as the \c stride parameter) to the appropriate gl*Pointer
|
||||
* function.
|
||||
*/
|
||||
GLubyte size;
|
||||
}
|
||||
static const modes[14][4] = {
|
||||
/* texture color normal vertex */
|
||||
{NONE, NONE, NONE, F(2)}, /* GL_V2F */
|
||||
{NONE, NONE, NONE, F(3)}, /* GL_V3F */
|
||||
{NONE, UB4, NONE, F(2)}, /* GL_C4UB_V2F */
|
||||
{NONE, UB4, NONE, F(3)}, /* GL_C4UB_V3F */
|
||||
{NONE, F(3), NONE, F(3)}, /* GL_C3F_V3F */
|
||||
{NONE, NONE, F(3), F(3)}, /* GL_N3F_V3F */
|
||||
{NONE, F(4), F(3), F(3)}, /* GL_C4F_N3F_V3F */
|
||||
{F(2), NONE, NONE, F(3)}, /* GL_T2F_V3F */
|
||||
{F(4), NONE, NONE, F(4)}, /* GL_T4F_V4F */
|
||||
{F(2), UB4, NONE, F(3)}, /* GL_T2F_C4UB_V3F */
|
||||
{F(2), F(3), NONE, F(3)}, /* GL_T2F_C3F_V3F */
|
||||
{F(2), NONE, F(3), F(3)}, /* GL_T2F_N3F_V3F */
|
||||
{F(2), F(4), F(3), F(3)}, /* GL_T2F_C4F_N3F_V3F */
|
||||
{F(4), F(4), F(3), F(4)}, /* GL_T4F_C4F_N3F_V4F */
|
||||
};
|
||||
#undef NONE
|
||||
#undef F
|
||||
#undef UB4
|
||||
|
||||
GLint trueStride, size;
|
||||
int offsets[4];
|
||||
unsigned i;
|
||||
const int idx = format - GL_V2F;
|
||||
|
||||
|
||||
/* All valid formats are on the range [GL_V2F, GL_V2F+0x0D]. Since idx
|
||||
* is just the format biased by -GL_V2F, all valid idx values are on the
|
||||
* range [0, 0x0D].
|
||||
*/
|
||||
if ( (idx < 0) || (idx > 0x0D) ) {
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( stride < 0 ) {
|
||||
__glXSetError(gc, GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* If the 'count' for a subarray is non-zero, then the offset of its
|
||||
* first element is at the currently accumulated 'size'.
|
||||
*/
|
||||
size = 0;
|
||||
for ( i = 0 ; i < 4 ; i++ ) {
|
||||
offsets[i] = (modes[idx][i].count != 0) ? size : -1;
|
||||
size += modes[idx][i].size;
|
||||
}
|
||||
|
||||
trueStride = (stride == 0) ? size : stride;
|
||||
|
||||
__glXArrayDisableAll( state );
|
||||
|
||||
if (tEnable) {
|
||||
if ( offsets[0] >= 0 ) {
|
||||
__indirect_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
__indirect_glTexCoordPointer(tSize, tType, trueStride, (const char *)pointer);
|
||||
__indirect_glTexCoordPointer( modes[idx][0].count, GL_FLOAT,
|
||||
trueStride,
|
||||
(const char *) pointer );
|
||||
}
|
||||
if (cEnable) {
|
||||
if ( offsets[1] >= 0 ) {
|
||||
__indirect_glEnableClientState(GL_COLOR_ARRAY);
|
||||
__indirect_glColorPointer(cSize, cType, trueStride, (const char *)pointer+cOffset);
|
||||
__indirect_glColorPointer( modes[idx][1].count, modes[idx][1].type,
|
||||
trueStride,
|
||||
(const char *) pointer + offsets[1] );
|
||||
}
|
||||
if (nEnable) {
|
||||
if ( offsets[2] >= 0 ) {
|
||||
__indirect_glEnableClientState(GL_NORMAL_ARRAY);
|
||||
__indirect_glNormalPointer(nType, trueStride, (const char *)pointer+nOffset);
|
||||
__indirect_glNormalPointer( GL_FLOAT, trueStride,
|
||||
(const char *)pointer + offsets[2] );
|
||||
}
|
||||
__indirect_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
__indirect_glVertexPointer(vSize, vType, trueStride, (const char *)pointer+vOffset);
|
||||
__indirect_glVertexPointer( modes[idx][3].count, GL_FLOAT,
|
||||
trueStride,
|
||||
(const char *)pointer + offsets[3] );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue