From e9c88361817154ab58c78f269504d8a45caae671 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Thu, 14 Mar 2019 13:15:56 +0000 Subject: [PATCH] Huge cleanup of glDrawElements handling --- GL/draw.c | 594 +++++++++--------------------------------------------- 1 file changed, 95 insertions(+), 499 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index 464bc40..1cc8d82 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -279,6 +279,37 @@ static void _readVertexData3ubARGB(const GLubyte* input, GLuint count, GLubyte s } } +static void _fillWithNegZ(GLuint count, GLfloat* output) { + const GLfloat* end = (GLfloat*) ((GLubyte*) output) + (sizeof(ClipVertex) * count); + while(output < end) { + output[0] = output[1] = 0.0f; + output[2] = -1.0f; + + output += sizeof(ClipVertex); + } +} + +static void _fillWhiteARGB(GLuint count, GLubyte* output) { + const GLubyte* end = output + (sizeof(ClipVertex) * count); + + while(output < end) { + output[R8IDX] = 255; + output[G8IDX] = 255; + output[B8IDX] = 255; + output[A8IDX] = 255; + + output += sizeof(ClipVertex); + } +} + +static void _fillZero2f(GLuint count, GLfloat* output) { + const GLfloat* end = output + (sizeof(ClipVertex) * count); + while(output < end) { + output[0] = output[1] = 0.0f; + output += sizeof(ClipVertex); + } +} + static void _readVertexData3usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) { assert(0 && "Not Implemented"); } @@ -319,112 +350,6 @@ AttribPointer* _glGetSTAttribPointer() { return &ST_POINTER; } -static inline void _parseVec3FromShort3(GLfloat* out, const GLubyte* in) { - GLshort* ptr = (GLshort*) in; - - out[0] = (GLfloat) ptr[0]; - out[1] = (GLfloat) ptr[1]; - out[2] = (GLfloat) ptr[2]; -} - -static inline void _parseVec3FromInt3(GLfloat* out, const GLubyte* in) { - GLint* ptr = (GLint*) in; - - out[0] = (GLfloat) ptr[0]; - out[1] = (GLfloat) ptr[1]; - out[2] = (GLfloat) ptr[2]; -} - -static inline void _parseVec3FromFloat3(GLfloat* out, const GLubyte* in) { - GLfloat* ptr = (GLfloat*) in; - - out[0] = ptr[0]; - out[1] = ptr[1]; - out[2] = ptr[2]; -} - -static inline void _parseVec2FromFloat2(GLfloat* out, const GLubyte* in) { - GLfloat* ptr = (GLfloat*) in; - - out[0] = ptr[0]; - out[1] = ptr[1]; -} - -static inline void _parseVec3FromFloat2(GLfloat* out, const GLubyte* in) { - GLfloat* ptr = (GLfloat*) in; - - out[0] = ptr[0]; - out[1] = ptr[1]; - out[2] = 0.0f; -} - -static inline void _parseVec4FromFloat3(GLfloat* out, const GLubyte* in) { - GLfloat* ptr = (GLfloat*) in; - - out[0] = ptr[0]; - out[1] = ptr[1]; - out[2] = ptr[2]; - out[3] = 1.0; -} - -static inline void _parseVec4FromFloat4(GLfloat* out, const GLubyte* in) { - GLfloat* ptr = (GLfloat*) in; - - out[0] = ptr[0]; - out[1] = ptr[1]; - out[2] = ptr[2]; - out[3] = ptr[3]; -} - -static inline void _parseColourFromUByte4(GLubyte* out, const GLubyte* in) { - out[R8IDX] = in[0]; - out[G8IDX] = in[1]; - out[B8IDX] = in[2]; - out[A8IDX] = in[3]; -} - -static inline void _parseColourFromFloat4(GLubyte* out, const GLubyte* in) { - GLfloat* fin = (GLfloat*) in; - - out[R8IDX] = (GLubyte) (fin[0] * 255.0f); - out[G8IDX] = (GLubyte) (fin[1] * 255.0f); - out[B8IDX] = (GLubyte) (fin[2] * 255.0f); - out[A8IDX] = (GLubyte) (fin[3] * 255.0f); -} - -static inline void _parseColourFromFloat3(GLubyte* out, const GLubyte* in) { - out[A8IDX] = 255; - out[R8IDX] = (GLubyte) ((GLfloat) in[0]) * 255.0f; - out[G8IDX] = (GLubyte) ((GLfloat) in[1]) * 255.0f; - out[B8IDX] = (GLubyte) ((GLfloat) in[2]) * 255.0f; -} - -static inline void _constVec2Zero(GLfloat* out, const GLubyte* in) { - out[0] = 0.0f; - out[1] = 0.0f; -} - -static inline void _constVec3NegZ(GLfloat* out, const GLubyte* in) { - out[0] = 0.0f; - out[1] = 0.0f; - out[2] = -1.0f; -} - -static inline void _constVec4One(GLfloat* out, const GLubyte* in) { - out[0] = 1.0f; - out[1] = 1.0f; - out[2] = 1.0f; - out[3] = 1.0f; -} - -static inline void _constColourOne(GLubyte* out, const GLubyte* in) { - out[0] = 255; - out[1] = 255; - out[2] = 255; - out[3] = 255; -} - - typedef GLuint (*IndexParseFunc)(const GLubyte* in); static inline GLuint _parseUByteIndex(const GLubyte* in) { @@ -508,339 +433,6 @@ do { \ *b = temp; \ } while(0) -static inline FloatParseFunc _calcVertexParseFunc() { - switch(VERTEX_POINTER.type) { - case GL_SHORT: { - if(VERTEX_POINTER.size == 3) { - return &_parseVec3FromShort3; - } - } break; - case GL_INT: { - if(VERTEX_POINTER.size == 3) { - return &_parseVec3FromInt3; - } - } break; - case GL_FLOAT: { - if(VERTEX_POINTER.size == 3) { - return &_parseVec3FromFloat3; - } else if(VERTEX_POINTER.size == 2) { - return &_parseVec3FromFloat2; - } - } break; - default: - break; - } - - return NULL; -} - -static inline ByteParseFunc _calcDiffuseParseFunc() { - if((ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) != DIFFUSE_ENABLED_FLAG) { - return &_constColourOne; - } - - switch(DIFFUSE_POINTER.type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: { - if(DIFFUSE_POINTER.size == 4) { - return &_parseColourFromUByte4; - } - } break; - case GL_FLOAT: { - if(DIFFUSE_POINTER.size == 3) { - return &_parseColourFromFloat3; - } else if(DIFFUSE_POINTER.size == 4) { - return &_parseColourFromFloat4; - } - } break; - default: - break; - } - - return &_constColourOne; -} - -static inline FloatParseFunc _calcUVParseFunc() { - if((ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) != UV_ENABLED_FLAG) { - return &_constVec2Zero; - } - - switch(UV_POINTER.type) { - case GL_FLOAT: { - if(UV_POINTER.size == 2) { - return &_parseVec2FromFloat2; - } - } break; - default: - break; - } - - return &_constVec2Zero; -} - -static inline FloatParseFunc _calcSTParseFunc() { - if((ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) != ST_ENABLED_FLAG) { - return &_constVec2Zero; - } - - switch(ST_POINTER.type) { - case GL_FLOAT: { - if(ST_POINTER.size == 2) { - return &_parseVec2FromFloat2; - } - } break; - default: - break; - } - - return &_constVec2Zero; -} - -static inline FloatParseFunc _calcNormalParseFunc() { - if((ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) != NORMAL_ENABLED_FLAG) { - return &_constVec3NegZ; - } - - switch(NORMAL_POINTER.type) { - case GL_SHORT: { - if(NORMAL_POINTER.size == 3) { - return &_parseVec3FromShort3; - } - } break; - case GL_INT: { - if(NORMAL_POINTER.size == 3) { - return &_parseVec3FromInt3; - } - } break; - case GL_FLOAT: { - if(NORMAL_POINTER.size == 3) { - return &_parseVec3FromFloat3; - } else if(NORMAL_POINTER.size == 2) { - return &_parseVec3FromFloat2; - } - } break; - default: - break; - } - - return &_constVec3NegZ; -} - - -static inline void _buildTriangle(ClipVertex* first, ClipVertex* previous, ClipVertex* vertex, ClipVertex* next, const GLsizei i) { - if(((i + 1) % 3) == 0) { - vertex->flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline GLsizei fast_mod(const GLsizei input, const GLsizei ceil) { - return input >= ceil ? input % ceil : input; -} - -static inline void _buildQuad(ClipVertex* first, ClipVertex* previous, ClipVertex* vertex, ClipVertex* next, const GLsizei i) { - if((i + 1) % 4 == 0) { - previous->flags = PVR_CMD_VERTEX_EOL; - swapVertex(previous, vertex); - } -} - -static void _buildTriangleFan(ClipVertex* first, ClipVertex* previous, ClipVertex* vertex, ClipVertex* next, const GLsizei i) { - if(i == 2) { - swapVertex(previous, vertex); - vertex->flags = PVR_CMD_VERTEX_EOL; - } else if(i > 2) { - ClipVertex* next = vertex + 1; - - *next = *first; - - swapVertex(next, vertex); - - vertex = next + 1; - *vertex = *previous; - - vertex->flags = PVR_CMD_VERTEX_EOL; - } -} - -static void _buildStrip(ClipVertex* first, ClipVertex* previous, ClipVertex* vertex, ClipVertex* next, const GLsizei i) { - if(!next) { - /* If the mode was triangle strip, then the last vertex is the last vertex */ - vertex->flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline PolyBuildFunc _calcBuildFunc(const GLenum type) { - switch(type) { - case GL_TRIANGLES: - return &_buildTriangle; - break; - case GL_QUADS: - return &_buildQuad; - break; - case GL_TRIANGLE_FAN: - case GL_POLYGON: - return &_buildTriangleFan; - break; - default: - break; - } - - return &_buildStrip; -} - -static inline void nullFloatParseFunc(GLfloat* out, const GLubyte* in) {} - -static inline void genElementsCommon( - ClipVertex* output, - const GLubyte* iptr, GLuint istride, GLenum type, - GLuint count, - const GLubyte* vptr, GLuint vstride, - const GLubyte* cptr, GLuint cstride, - const GLubyte* uvptr, GLuint uvstride, - const GLubyte* stptr, GLuint ststride, - const GLubyte* nptr, GLuint nstride, - GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting -) { - const FloatParseFunc vertexFunc = _calcVertexParseFunc(); - const ByteParseFunc diffuseFunc = _calcDiffuseParseFunc(); - const FloatParseFunc uvFunc = (doTexture) ? _calcUVParseFunc() : &nullFloatParseFunc; - const FloatParseFunc stFunc = (doMultitexture) ? _calcSTParseFunc() : &nullFloatParseFunc; - const FloatParseFunc normalFunc = (doLighting) ? _calcNormalParseFunc() : &nullFloatParseFunc; - - const IndexParseFunc indexFunc = _calcParseIndexFunc(type); - - assert(vertexFunc); - assert(diffuseFunc); - assert(uvFunc); - assert(stFunc); - assert(normalFunc); - assert(indexFunc); - - GLsizei i = 0; - const GLubyte* idx = iptr; - ClipVertex* vertex = output; - - for(; i < count; ++i, idx += istride, ++vertex) { - GLuint j = indexFunc(idx); - vertex->flags = PVR_CMD_VERTEX; - vertexFunc(vertex->xyz, vptr + (j * vstride)); - diffuseFunc(vertex->bgra, cptr + (j * cstride)); - uvFunc(vertex->uv, uvptr + (j * uvstride)); - stFunc(vertex->st, stptr + (j * ststride)); - normalFunc(vertex->nxyz, nptr + (j * nstride)); - } -} - -static inline void genElementsTriangles( - ClipVertex* output, - GLuint count, - const GLubyte* iptr, GLuint istride, GLenum type, - const GLubyte* vptr, GLuint vstride, - const GLubyte* cptr, GLuint cstride, - const GLubyte* uvptr, GLuint uvstride, - const GLubyte* stptr, GLuint ststride, - const GLubyte* nptr, GLuint nstride, - GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) { - - genElementsCommon( - output, - iptr, istride, type, count, - vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride, - doTexture, doMultitexture, doLighting - ); - - GLsizei i = 2; - for(; i < count; i += 3) { - output[i].flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline void genElementsQuads( - ClipVertex* output, - GLuint count, - const GLubyte* iptr, GLuint istride, GLenum type, - const GLubyte* vptr, GLuint vstride, - const GLubyte* cptr, GLuint cstride, - const GLubyte* uvptr, GLuint uvstride, - const GLubyte* stptr, GLuint ststride, - const GLubyte* nptr, GLuint nstride, - GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) { - - genElementsCommon( - output, - iptr, istride, type, count, - vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride, - doTexture, doMultitexture, doLighting - ); - - GLsizei i = 3; - for(; i < count; i += 4) { - swapVertex(&output[i], &output[i - 1]); - output[i].flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline void genElementsTriangleFan( - ClipVertex* output, - GLuint count, - const GLubyte* iptr, GLuint istride, GLenum type, - const GLubyte* vptr, GLuint vstride, - const GLubyte* cptr, GLuint cstride, - const GLubyte* uvptr, GLuint uvstride, - const GLubyte* stptr, GLuint ststride, - const GLubyte* nptr, GLuint nstride, - GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) { - - genElementsCommon( - output, - iptr, istride, type, count, - vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride, - doTexture, doMultitexture, doLighting - ); - - swapVertex(&output[1], &output[2]); - output[2].flags = PVR_CMD_VERTEX_EOL; - - GLsizei i = 3; - ClipVertex* first = &output[0]; - - for(; i < count - 1; ++i) { - ClipVertex* next = &output[i + 1]; - ClipVertex* previous = &output[i - 1]; - ClipVertex* vertex = &output[i]; - - *next = *first; - - swapVertex(next, vertex); - - vertex = next + 1; - *vertex = *previous; - - vertex->flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline void genElementsTriangleStrip( - ClipVertex* output, - GLuint count, - const GLubyte* iptr, GLuint istride, GLenum type, - const GLubyte* vptr, GLuint vstride, - const GLubyte* cptr, GLuint cstride, - const GLubyte* uvptr, GLuint uvstride, - const GLubyte* stptr, GLuint ststride, - const GLubyte* nptr, GLuint nstride, - GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) { - - genElementsCommon( - output, - iptr, istride, type, count, - vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride, - doTexture, doMultitexture, doLighting - ); - - output[count - 1].flags = PVR_CMD_VERTEX_EOL; -} - static inline void genArraysTriangles(ClipVertex* output, GLuint count) { const ClipVertex* end = output + count; ClipVertex* it = output + 2; @@ -946,6 +538,11 @@ static inline void _readPositionData(const GLuint first, const GLuint count, Cli } static inline void _readUVData(const GLuint first, const GLuint count, ClipVertex* output) { + if((ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) != UV_ENABLED_FLAG) { + _fillZero2f(count, output->uv); + return; + } + const GLubyte uvstride = (UV_POINTER.stride) ? UV_POINTER.stride : UV_POINTER.size * byte_size(UV_POINTER.type); const void* uvptr = ((GLubyte*) UV_POINTER.ptr + (first * uvstride)); @@ -975,6 +572,11 @@ static inline void _readUVData(const GLuint first, const GLuint count, ClipVerte } static inline void _readSTData(const GLuint first, const GLuint count, ClipVertex* output) { + if((ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) != ST_ENABLED_FLAG) { + _fillZero2f(count, output->st); + return; + } + const GLubyte ststride = (ST_POINTER.stride) ? ST_POINTER.stride : ST_POINTER.size * byte_size(ST_POINTER.type); const void* stptr = ((GLubyte*) ST_POINTER.ptr + (first * ststride)); @@ -1004,6 +606,11 @@ static inline void _readSTData(const GLuint first, const GLuint count, ClipVerte } static inline void _readNormalData(const GLuint first, const GLuint count, ClipVertex* output) { + if((ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) != NORMAL_ENABLED_FLAG) { + _fillWithNegZ(count, output->nxyz); + return; + } + const GLuint nstride = (NORMAL_POINTER.stride) ? NORMAL_POINTER.stride : NORMAL_POINTER.size * byte_size(NORMAL_POINTER.type); const void* nptr = ((GLubyte*) NORMAL_POINTER.ptr + (first * nstride)); @@ -1033,6 +640,12 @@ static inline void _readNormalData(const GLuint first, const GLuint count, ClipV } static inline void _readDiffuseData(const GLuint first, const GLuint count, ClipVertex* output) { + if((ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) != DIFFUSE_ENABLED_FLAG) { + /* Just fill the whole thing white if the attribute is disabled */ + _fillWhiteARGB(count, output[0].bgra); + return; + } + const GLubyte cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : DIFFUSE_POINTER.size * byte_size(DIFFUSE_POINTER.type); const void* cptr = ((GLubyte*) DIFFUSE_POINTER.ptr + (first * cstride)); @@ -1085,18 +698,9 @@ static void generate(ClipVertex* output, const GLenum mode, const GLsizei first, const GLubyte* indices, const GLenum type, const GLboolean doTexture, const GLboolean doMultitexture, const GLboolean doLighting) { /* Read from the client buffers and generate an array of ClipVertices */ - const GLuint vstride = (VERTEX_POINTER.stride) ? VERTEX_POINTER.stride : VERTEX_POINTER.size * byte_size(VERTEX_POINTER.type); - const GLuint cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : DIFFUSE_POINTER.size * byte_size(DIFFUSE_POINTER.type); - const GLuint uvstride = (UV_POINTER.stride) ? UV_POINTER.stride : UV_POINTER.size * byte_size(UV_POINTER.type); - const GLuint ststride = (ST_POINTER.stride) ? ST_POINTER.stride : ST_POINTER.size * byte_size(ST_POINTER.type); - const GLuint nstride = (NORMAL_POINTER.stride) ? NORMAL_POINTER.stride : NORMAL_POINTER.size * byte_size(NORMAL_POINTER.type); - - const GLubyte* vptr = VERTEX_POINTER.ptr + (first * vstride); - const GLubyte* cptr = DIFFUSE_POINTER.ptr + (first * cstride); - const GLubyte* uvptr = UV_POINTER.ptr + (first * uvstride); - const GLubyte* stptr = ST_POINTER.ptr + (first * ststride); - const GLubyte* nptr = NORMAL_POINTER.ptr + (first * nstride); const GLsizei istride = byte_size(type); + ClipVertex* it; + const ClipVertex* end; if(!indices) { _readPositionData(first, count, output); @@ -1105,8 +709,8 @@ static void generate(ClipVertex* output, const GLenum mode, const GLsizei first, if(doLighting) _readNormalData(first, count, output); if(doTexture && doMultitexture) _readSTData(first, count, output); - ClipVertex* it = output; - const ClipVertex* end = output + count; + it = output; + end = output + count; while(it < end) { (it++)->flags = PVR_CMD_VERTEX; } @@ -1129,54 +733,46 @@ static void generate(ClipVertex* output, const GLenum mode, const GLsizei first, default: assert(0 && "Not Implemented"); } - } else if(mode == GL_TRIANGLES) { - genElementsTriangles( - output, - count, - indices, istride, type, - vptr, vstride, - cptr, cstride, - uvptr, uvstride, - stptr, ststride, - nptr, nstride, - doTexture, doMultitexture, doLighting - ); - } else if(mode == GL_QUADS) { - genElementsQuads( - output, - count, - indices, istride, type, - vptr, vstride, - cptr, cstride, - uvptr, uvstride, - stptr, ststride, - nptr, nstride, - doTexture, doMultitexture, doLighting - ); - } else if(mode == GL_TRIANGLE_FAN || mode == GL_POLYGON) { - genElementsTriangleFan( - output, - count, - indices, istride, type, - vptr, vstride, - cptr, cstride, - uvptr, uvstride, - stptr, ststride, - nptr, nstride, - doTexture, doMultitexture, doLighting - ); } else { - genElementsTriangleStrip( - output, - count, - indices, istride, type, - vptr, vstride, - cptr, cstride, - uvptr, uvstride, - stptr, ststride, - nptr, nstride, - doTexture, doMultitexture, doLighting - ); + const IndexParseFunc indexFunc = _calcParseIndexFunc(type); + it = output; + end = output + count; + GLuint j; + const GLubyte* idx = indices; + while(it < end) { + j = indexFunc(idx); + _readPositionData(j, 1, it); + _readDiffuseData(j, 1, it); + if(doTexture) _readUVData(j, 1, it); + if(doLighting) _readNormalData(j, 1, it); + if(doTexture && doMultitexture) _readSTData(j, 1, it); + ++it; + idx += istride; + } + + it = output; + while(it < end) { + (it++)->flags = PVR_CMD_VERTEX; + } + + // Drawing arrays + switch(mode) { + case GL_TRIANGLES: + genArraysTriangles(output, count); + break; + case GL_QUADS: + genArraysQuads(output, count); + break; + case GL_POLYGON: + case GL_TRIANGLE_FAN: + genArraysTriangleFan(output, count); + break; + case GL_TRIANGLE_STRIP: + genArraysTriangleStrip(output, count); + break; + default: + assert(0 && "Not Implemented"); + } } }