From 873a02bd3ce92ff765cb4847428d896c4433616e Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 13 Oct 2014 21:57:06 -0700 Subject: [PATCH] OpenGL2: VBO cleanup. --- code/renderergl2/tr_bsp.c | 13 +- code/renderergl2/tr_glsl.c | 288 +++---------------- code/renderergl2/tr_local.h | 77 +++-- code/renderergl2/tr_model.c | 59 +++- code/renderergl2/tr_shade.c | 2 +- code/renderergl2/tr_sky.c | 2 +- code/renderergl2/tr_surface.c | 4 +- code/renderergl2/tr_vbo.c | 521 +++++++++++----------------------- 8 files changed, 300 insertions(+), 666 deletions(-) diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index fa045122..e14fb939 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -2050,17 +2050,8 @@ static void R_CreateWorldVBOs(void) } } -#ifdef USE_VERT_TANGENT_SPACE - vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | - ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); -#else - vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | - ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); -#endif - - ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", k), numIndexes, indexes, VBO_USAGE_STATIC); + vbo = R_CreateVBO2(va("staticBspModel%i_VBO", k), numVerts, verts); + ibo = R_CreateIBO2(va("staticBspModel%i_IBO", k), numIndexes, indexes); // point bsp surfaces to VBO for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index bdf6e1b0..6e8934ed 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -537,10 +537,10 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position"); if(attribs & ATTR_TEXCOORD) - qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD0, "attr_TexCoord0"); + qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0"); if(attribs & ATTR_LIGHTCOORD) - qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD1, "attr_TexCoord1"); + qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1"); // if(attribs & ATTR_TEXCOORD2) // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2"); @@ -548,10 +548,8 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int // if(attribs & ATTR_TEXCOORD3) // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3"); -#ifdef USE_VERT_TANGENT_SPACE if(attribs & ATTR_TANGENT) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); -#endif if(attribs & ATTR_NORMAL) qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal"); @@ -571,10 +569,8 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int if(attribs & ATTR_NORMAL2) qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); -#ifdef USE_VERT_TANGENT_SPACE if(attribs & ATTR_TANGENT2) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2"); -#endif GLSL_LinkProgram(program->program); @@ -1412,20 +1408,9 @@ void GLSL_ShutdownGPUShaders(void) ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); - qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); - qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); - qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); -#ifdef USE_VERT_TANGENT_SPACE - qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); -#endif - qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); -#ifdef USE_VERT_TANGENT_SPACE - qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); -#endif - qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); - qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); + for (i = 0; i < ATTR_INDEX_COUNT; i++) + qglDisableVertexAttribArrayARB(i); + GLSL_BindNullProgram(); for ( i = 0; i < GENERICDEF_COUNT; i++) @@ -1502,155 +1487,26 @@ void GLSL_BindNullProgram(void) void GLSL_VertexAttribsState(uint32_t stateBits) { - uint32_t diff; + uint32_t diff = stateBits ^ glState.vertexAttribsState; - diff = stateBits ^ glState.vertexAttribsState; - - if(diff) + if (diff) { - if(diff & ATTR_POSITION) + int attribIndex; + for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) { - if(stateBits & ATTR_POSITION) + uint32_t attribBit = 1 << attribIndex; + if(diff & attribBit) { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_POSITION )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_POSITION )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); + if (stateBits & attribBit) + { + qglEnableVertexAttribArrayARB(attribIndex); + } + else + { + qglDisableVertexAttribArrayARB(attribIndex); + } } } - - if(diff & ATTR_TEXCOORD) - { - if(stateBits & ATTR_TEXCOORD) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TEXCOORD )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TEXCOORD )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); - } - } - - if(diff & ATTR_LIGHTCOORD) - { - if(stateBits & ATTR_LIGHTCOORD) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_LIGHTCOORD )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_LIGHTCOORD )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); - } - } - - if(diff & ATTR_NORMAL) - { - if(stateBits & ATTR_NORMAL) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_NORMAL )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_NORMAL); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_NORMAL )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); - } - } - -#ifdef USE_VERT_TANGENT_SPACE - if(diff & ATTR_TANGENT) - { - if(stateBits & ATTR_TANGENT) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); - } - } -#endif - - if(diff & ATTR_COLOR) - { - if(stateBits & ATTR_COLOR) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_COLOR )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_COLOR); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_COLOR )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); - } - } - - if(diff & ATTR_LIGHTDIRECTION) - { - if(stateBits & ATTR_LIGHTDIRECTION) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_LIGHTDIRECTION )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_LIGHTDIRECTION )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); - } - } - - if(diff & ATTR_POSITION2) - { - if(stateBits & ATTR_POSITION2) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_POSITION2 )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION2); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_POSITION2 )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); - } - } - - if(diff & ATTR_NORMAL2) - { - if(stateBits & ATTR_NORMAL2) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_NORMAL2 )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_NORMAL2 )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); - } - } - -#ifdef USE_VERT_TANGENT_SPACE - if(diff & ATTR_TANGENT2) - { - if(stateBits & ATTR_TANGENT2) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); - } - } -#endif } GLSL_VertexAttribPointers(stateBits); @@ -1660,10 +1516,11 @@ void GLSL_VertexAttribsState(uint32_t stateBits) void GLSL_VertexAttribPointers(uint32_t attribBits) { - qboolean animated; int newFrame, oldFrame; VBO_t *vbo = glState.currentVBO; - + int attribIndex; + uint32_t extraOffsets[ATTR_INDEX_COUNT]; + if(!vbo) { ri.Error(ERR_FATAL, "GL_VertexAttribPointers: no VBO bound"); @@ -1676,95 +1533,36 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", vbo->name)); } + for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) + extraOffsets[attribIndex] = 0; + // position/normal/tangent are always set in case of animation oldFrame = glState.vertexAttribsOldFrame; newFrame = glState.vertexAttribsNewFrame; - animated = glState.vertexAnimation; - - if((attribBits & ATTR_POSITION) && (!(glState.vertexAttribPointersSet & ATTR_POSITION) || animated)) + if (glState.vertexAnimation) { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + newFrame * vbo->size_xyz)); - glState.vertexAttribPointersSet |= ATTR_POSITION; + glState.vertexAttribPointersSet &= ~(ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TANGENT | ATTR_TANGENT2); + extraOffsets[ATTR_INDEX_POSITION] = newFrame * vbo->size_xyz; + extraOffsets[ATTR_INDEX_POSITION2] = oldFrame * vbo->size_xyz; + extraOffsets[ATTR_INDEX_NORMAL] = newFrame * vbo->size_normal; + extraOffsets[ATTR_INDEX_NORMAL2] = oldFrame * vbo->size_normal; + extraOffsets[ATTR_INDEX_TANGENT] = newFrame * vbo->size_normal; + extraOffsets[ATTR_INDEX_TANGENT2] = oldFrame * vbo->size_normal; } - if((attribBits & ATTR_TEXCOORD) && !(glState.vertexAttribPointersSet & ATTR_TEXCOORD)) + for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TEXCOORD )\n"); + uint32_t attribBit = 1 << attribIndex; + vaoAttrib_t *vAtb; - qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD0, 2, GL_FLOAT, 0, vbo->stride_st, BUFFER_OFFSET(vbo->ofs_st)); - glState.vertexAttribPointersSet |= ATTR_TEXCOORD; + if (!(attribBits & attribBit) || (glState.vertexAttribPointersSet & attribBit)) + continue; + + vAtb = &vbo->attribs[attribIndex]; + + qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + extraOffsets[attribIndex])); + glState.vertexAttribPointersSet |= attribBit; } - - if((attribBits & ATTR_LIGHTCOORD) && !(glState.vertexAttribPointersSet & ATTR_LIGHTCOORD)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTCOORD )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD1, 2, GL_FLOAT, 0, vbo->stride_lightmap, BUFFER_OFFSET(vbo->ofs_lightmap)); - glState.vertexAttribPointersSet |= ATTR_LIGHTCOORD; - } - - if((attribBits & ATTR_NORMAL) && (!(glState.vertexAttribPointersSet & ATTR_NORMAL) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + newFrame * vbo->size_normal)); - glState.vertexAttribPointersSet |= ATTR_NORMAL; - } - -#ifdef USE_VERT_TANGENT_SPACE - if((attribBits & ATTR_TANGENT) && (!(glState.vertexAttribPointersSet & ATTR_TANGENT) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + newFrame * vbo->size_normal)); // FIXME - glState.vertexAttribPointersSet |= ATTR_TANGENT; - } -#endif - - if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_COLOR )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_COLOR, 4, GL_FLOAT, 0, vbo->stride_vertexcolor, BUFFER_OFFSET(vbo->ofs_vertexcolor)); - glState.vertexAttribPointersSet |= ATTR_COLOR; - } - - if((attribBits & ATTR_LIGHTDIRECTION) && !(glState.vertexAttribPointersSet & ATTR_LIGHTDIRECTION)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTDIRECTION )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_lightdir, BUFFER_OFFSET(vbo->ofs_lightdir)); - glState.vertexAttribPointersSet |= ATTR_LIGHTDIRECTION; - } - - if((attribBits & ATTR_POSITION2) && (!(glState.vertexAttribPointersSet & ATTR_POSITION2) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION2 )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_POSITION2, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + oldFrame * vbo->size_xyz)); - glState.vertexAttribPointersSet |= ATTR_POSITION2; - } - - if((attribBits & ATTR_NORMAL2) && (!(glState.vertexAttribPointersSet & ATTR_NORMAL2) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL2 )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + oldFrame * vbo->size_normal)); - glState.vertexAttribPointersSet |= ATTR_NORMAL2; - } - -#ifdef USE_VERT_TANGENT_SPACE - if((attribBits & ATTR_TANGENT2) && (!(glState.vertexAttribPointersSet & ATTR_TANGENT2) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + oldFrame * vbo->size_normal)); // FIXME - glState.vertexAttribPointersSet |= ATTR_TANGENT2; - } -#endif - } diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 164b104c..a9d1043c 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -96,40 +96,36 @@ typedef struct { float transformMatrix[16]; } orientationr_t; +// Ensure this is >= the ATTR_INDEX_COUNT enum below +#define VAO_MAX_ATTRIBS 16 + typedef enum { VBO_USAGE_STATIC, VBO_USAGE_DYNAMIC } vboUsage_t; +typedef struct vaoAttrib_s +{ + uint32_t enabled; + uint32_t count; + uint32_t type; + uint32_t normalized; + uint32_t stride; + uint32_t offset; +} +vaoAttrib_t; + typedef struct VBO_s { char name[MAX_QPATH]; uint32_t vertexesVBO; int vertexesSize; // amount of memory data allocated for all vertices in bytes - uint32_t ofs_xyz; - uint32_t ofs_normal; - uint32_t ofs_st; - uint32_t ofs_lightmap; - uint32_t ofs_vertexcolor; - uint32_t ofs_lightdir; -#ifdef USE_VERT_TANGENT_SPACE - uint32_t ofs_tangent; -#endif - uint32_t stride_xyz; - uint32_t stride_normal; - uint32_t stride_st; - uint32_t stride_lightmap; - uint32_t stride_vertexcolor; - uint32_t stride_lightdir; -#ifdef USE_VERT_TANGENT_SPACE - uint32_t stride_tangent; -#endif + vaoAttrib_t attribs[VAO_MAX_ATTRIBS]; + uint32_t size_xyz; uint32_t size_normal; - - int attribs; } VBO_t; typedef struct IBO_s @@ -514,8 +510,8 @@ static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader) enum { ATTR_INDEX_POSITION = 0, - ATTR_INDEX_TEXCOORD0 = 1, - ATTR_INDEX_TEXCOORD1 = 2, + ATTR_INDEX_TEXCOORD = 1, + ATTR_INDEX_LIGHTCOORD = 2, ATTR_INDEX_TANGENT = 3, ATTR_INDEX_NORMAL = 4, ATTR_INDEX_COLOR = 5, @@ -527,26 +523,28 @@ enum // GPU vertex animations ATTR_INDEX_POSITION2 = 10, ATTR_INDEX_TANGENT2 = 11, - ATTR_INDEX_NORMAL2 = 12 + ATTR_INDEX_NORMAL2 = 12, + + ATTR_INDEX_COUNT = 13 }; enum { - ATTR_POSITION = 0x0001, - ATTR_TEXCOORD = 0x0002, - ATTR_LIGHTCOORD = 0x0004, - ATTR_TANGENT = 0x0008, - ATTR_NORMAL = 0x0010, - ATTR_COLOR = 0x0020, - ATTR_PAINTCOLOR = 0x0040, - ATTR_LIGHTDIRECTION = 0x0080, - ATTR_BONE_INDEXES = 0x0100, - ATTR_BONE_WEIGHTS = 0x0200, + ATTR_POSITION = 1 << ATTR_INDEX_POSITION, + ATTR_TEXCOORD = 1 << ATTR_INDEX_TEXCOORD, + ATTR_LIGHTCOORD = 1 << ATTR_INDEX_LIGHTCOORD, + ATTR_TANGENT = 1 << ATTR_INDEX_TANGENT, + ATTR_NORMAL = 1 << ATTR_INDEX_NORMAL, + ATTR_COLOR = 1 << ATTR_INDEX_COLOR, + ATTR_PAINTCOLOR = 1 << ATTR_INDEX_PAINTCOLOR, + ATTR_LIGHTDIRECTION = 1 << ATTR_INDEX_LIGHTDIRECTION, + ATTR_BONE_INDEXES = 1 << ATTR_INDEX_BONE_INDEXES, + ATTR_BONE_WEIGHTS = 1 << ATTR_INDEX_BONE_WEIGHTS, // for .md3 interpolation - ATTR_POSITION2 = 0x0400, - ATTR_TANGENT2 = 0x0800, - ATTR_NORMAL2 = 0x1000, + ATTR_POSITION2 = 1 << ATTR_INDEX_POSITION2, + ATTR_TANGENT2 = 1 << ATTR_INDEX_TANGENT2, + ATTR_NORMAL2 = 1 << ATTR_INDEX_NORMAL2, ATTR_DEFAULT = ATTR_POSITION, ATTR_BITS = ATTR_POSITION | @@ -2033,6 +2031,7 @@ typedef struct shaderCommands_s uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16); //int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16); + void *attribPointers[ATTR_INDEX_COUNT]; VBO_t *vbo; IBO_t *ibo; qboolean useInternalVBO; @@ -2201,10 +2200,10 @@ void R_VboUnpackTangent(vec4_t v, uint32_t b); void R_VboUnpackNormal(vec3_t v, uint32_t b); VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, vboUsage_t usage); -VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vertexes, uint32_t stateBits, vboUsage_t usage); +VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vertexes); IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, vboUsage_t usage); -IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage); +IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes); void R_BindVBO(VBO_t * vbo); void R_BindNullVBO(void); @@ -2216,7 +2215,7 @@ void R_InitVBOs(void); void R_ShutdownVBOs(void); void R_VBOList_f(void); -void RB_UpdateVBOs(unsigned int attribBits); +void RB_UpdateTessVbo(unsigned int attribBits); /* diff --git a/code/renderergl2/tr_model.c b/code/renderergl2/tr_model.c index 2dbecee7..a9405809 100644 --- a/code/renderergl2/tr_model.c +++ b/code/renderergl2/tr_model.c @@ -740,26 +740,65 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vboSurf->vbo = R_CreateVBO(va("staticMD3Mesh_VBO '%s'", surf->name), data, dataSize, VBO_USAGE_STATIC); - vboSurf->vbo->ofs_xyz = ofs_xyz; - vboSurf->vbo->ofs_normal = ofs_normal; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].enabled = 1; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].enabled = 1; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].enabled = 1; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].enabled = 1; #ifdef USE_VERT_TANGENT_SPACE - vboSurf->vbo->ofs_tangent = ofs_tangent; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].enabled = 1; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].enabled = 1; #endif - vboSurf->vbo->ofs_st = ofs_st; + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1; + + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].count = 3; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].count = 3; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].count = 4; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].count = 4; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].count = 4; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].count = 4; + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].count = 2; + + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].type = GL_FLOAT; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].type = glRefConfig.packedNormalDataType; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].type = glRefConfig.packedNormalDataType; + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT; + + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].normalized = GL_FALSE; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].normalized = GL_TRUE; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].normalized = GL_TRUE; + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE; + + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].offset = ofs_xyz; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].stride = sizeof(*verts); + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].offset = ofs_xyz; + vboSurf->vbo->attribs[ATTR_INDEX_POSITION2 ].stride = sizeof(*verts); + + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].offset = ofs_normal; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL ].stride = sizeof(*normals); + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].offset = ofs_normal; + vboSurf->vbo->attribs[ATTR_INDEX_NORMAL2 ].stride = sizeof(*normals); - vboSurf->vbo->stride_xyz = sizeof(*verts); - vboSurf->vbo->stride_normal = sizeof(*normals); #ifdef USE_VERT_TANGENT_SPACE - vboSurf->vbo->stride_tangent = sizeof(*tangents); + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].offset = ofs_tangent; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT ].stride = sizeof(*tangents); + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].offset = ofs_tangent; + vboSurf->vbo->attribs[ATTR_INDEX_TANGENT2 ].stride = sizeof(*tangents); #endif - vboSurf->vbo->stride_st = sizeof(*st); + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].offset = ofs_st; + vboSurf->vbo->attribs[ATTR_INDEX_TEXCOORD ].stride = sizeof(*st); - vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts; + vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts; vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts; ri.Free(data); - vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numIndexes, surf->indexes, VBO_USAGE_STATIC); + vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numIndexes, surf->indexes); } } diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 5285e28e..79a1778d 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -1498,7 +1498,7 @@ void RB_StageIteratorGeneric( void ) if (tess.useInternalVBO) { - RB_UpdateVBOs(vertexAttribs); + RB_UpdateTessVbo(vertexAttribs); } else { diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index 3b739df0..1d9a97c5 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -421,7 +421,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max tess.maxIndex = tess.numVertexes; // FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function - RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD); + RB_UpdateTessVbo(ATTR_POSITION | ATTR_TEXCOORD); /* { shaderProgram_t *sp = &tr.textureColorShader; diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 825582bd..38c4814f 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -203,7 +203,7 @@ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4]) tess.minIndex = 0; tess.maxIndex = 3; - RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD); + RB_UpdateTessVbo(ATTR_POSITION | ATTR_TEXCOORD); GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); @@ -601,7 +601,7 @@ static void RB_SurfaceBeam( void ) tess.maxIndex = tess.numVertexes; // FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function - RB_UpdateVBOs(ATTR_POSITION); + RB_UpdateTessVbo(ATTR_POSITION); GLSL_VertexAttribsState(ATTR_POSITION); GLSL_BindProgram(sp); diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index dc0f33be..cb140921 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -155,7 +155,7 @@ VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, R_CreateVBO2 ============ */ -VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * verts, unsigned int stateBits, vboUsage_t usage) +VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * verts) { VBO_t *vbo; int i; @@ -164,22 +164,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert int dataSize; int dataOfs; - int glUsage; - - switch (usage) - { - case VBO_USAGE_STATIC: - glUsage = GL_STATIC_DRAW_ARB; - break; - - case VBO_USAGE_DYNAMIC: - glUsage = GL_DYNAMIC_DRAW_ARB; - break; - - default: - Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage); - return NULL; - } + int glUsage = GL_STATIC_DRAW_ARB; if(!numVertexes) return NULL; @@ -202,279 +187,102 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert Q_strncpyz(vbo->name, name, sizeof(vbo->name)); - if (usage == VBO_USAGE_STATIC) + // since these vertex attributes are never altered, interleave them + vbo->attribs[ATTR_INDEX_POSITION ].enabled = 1; + vbo->attribs[ATTR_INDEX_NORMAL ].enabled = 1; +#ifdef USE_VERT_TANGENT_SPACE + vbo->attribs[ATTR_INDEX_TANGENT ].enabled = 1; +#endif + vbo->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1; + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1; + vbo->attribs[ATTR_INDEX_COLOR ].enabled = 1; + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].enabled = 1; + + vbo->attribs[ATTR_INDEX_POSITION ].count = 3; + vbo->attribs[ATTR_INDEX_NORMAL ].count = 4; + vbo->attribs[ATTR_INDEX_TANGENT ].count = 4; + vbo->attribs[ATTR_INDEX_TEXCOORD ].count = 2; + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].count = 2; + vbo->attribs[ATTR_INDEX_COLOR ].count = 4; + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4; + + vbo->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; + vbo->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; + vbo->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + vbo->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT; + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT; + vbo->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT; + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; + + vbo->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; + vbo->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; + vbo->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE; + vbo->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE; + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE; + vbo->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE; + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE; + + vbo->attribs[ATTR_INDEX_POSITION ].offset = 0; dataSize = sizeof(verts[0].xyz); + vbo->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(uint32_t); +#ifdef USE_VERT_TANGENT_SPACE + vbo->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t); +#endif + vbo->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += sizeof(verts[0].st); + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += sizeof(verts[0].lightmap); + vbo->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += sizeof(verts[0].vertexColors); + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t); + + vbo->attribs[ATTR_INDEX_POSITION ].stride = dataSize; + vbo->attribs[ATTR_INDEX_NORMAL ].stride = dataSize; + vbo->attribs[ATTR_INDEX_TANGENT ].stride = dataSize; + vbo->attribs[ATTR_INDEX_TEXCOORD ].stride = dataSize; + vbo->attribs[ATTR_INDEX_LIGHTCOORD ].stride = dataSize; + vbo->attribs[ATTR_INDEX_COLOR ].stride = dataSize; + vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = dataSize; + + // create VBO + dataSize *= numVertexes; + data = ri.Hunk_AllocateTempMemory(dataSize); + dataOfs = 0; + + for (i = 0; i < numVertexes; i++) { - // since these vertex attributes are never altered, interleave them - vbo->ofs_xyz = 0; - dataSize = sizeof(verts[0].xyz); - - if(stateBits & ATTR_NORMAL) - { - vbo->ofs_normal = dataSize; - dataSize += sizeof(uint32_t); - } - -#ifdef USE_VERT_TANGENT_SPACE - if(stateBits & ATTR_TANGENT) - { - vbo->ofs_tangent = dataSize; - dataSize += sizeof(uint32_t); - } -#endif - - if(stateBits & ATTR_TEXCOORD) - { - vbo->ofs_st = dataSize; - dataSize += sizeof(verts[0].st); - } - - if(stateBits & ATTR_LIGHTCOORD) - { - vbo->ofs_lightmap = dataSize; - dataSize += sizeof(verts[0].lightmap); - } - - if(stateBits & ATTR_COLOR) - { - vbo->ofs_vertexcolor = dataSize; - dataSize += sizeof(verts[0].vertexColors); - } - - if(stateBits & ATTR_LIGHTDIRECTION) - { - vbo->ofs_lightdir = dataSize; - dataSize += sizeof(uint32_t); - } - - vbo->stride_xyz = dataSize; - vbo->stride_normal = dataSize; -#ifdef USE_VERT_TANGENT_SPACE - vbo->stride_tangent = dataSize; -#endif - vbo->stride_st = dataSize; - vbo->stride_lightmap = dataSize; - vbo->stride_vertexcolor = dataSize; - vbo->stride_lightdir = dataSize; - - // create VBO - dataSize *= numVertexes; - data = ri.Hunk_AllocateTempMemory(dataSize); - dataOfs = 0; - - //ri.Printf(PRINT_ALL, "CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor, - //vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor); - - for (i = 0; i < numVertexes; i++) - { - // xyz - memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz)); - dataOfs += sizeof(verts[i].xyz); - - // normal - if(stateBits & ATTR_NORMAL) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackNormal(verts[i].normal); - - dataOfs += sizeof(uint32_t); - } - -#ifdef USE_VERT_TANGENT_SPACE - // tangent - if(stateBits & ATTR_TANGENT) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackTangent(verts[i].tangent); - - dataOfs += sizeof(uint32_t); - } -#endif - - // vertex texcoords - if(stateBits & ATTR_TEXCOORD) - { - memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st)); - dataOfs += sizeof(verts[i].st); - } - - // feed vertex lightmap texcoords - if(stateBits & ATTR_LIGHTCOORD) - { - memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap)); - dataOfs += sizeof(verts[i].lightmap); - } - - // feed vertex colors - if(stateBits & ATTR_COLOR) - { - memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors)); - dataOfs += sizeof(verts[i].vertexColors); - } - - // feed vertex light directions - if(stateBits & ATTR_LIGHTDIRECTION) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackNormal(verts[i].lightdir); - - dataOfs += sizeof(uint32_t); - } - } - } - else - { - // since these vertex attributes may be changed, put them in flat arrays - dataSize = sizeof(verts[0].xyz); - - if(stateBits & ATTR_NORMAL) - { - dataSize += sizeof(uint32_t); - } - -#ifdef USE_VERT_TANGENT_SPACE - if(stateBits & ATTR_TANGENT) - { - dataSize += sizeof(uint32_t); - } -#endif - - if(stateBits & ATTR_TEXCOORD) - { - dataSize += sizeof(verts[0].st); - } - - if(stateBits & ATTR_LIGHTCOORD) - { - dataSize += sizeof(verts[0].lightmap); - } - - if(stateBits & ATTR_COLOR) - { - dataSize += sizeof(verts[0].vertexColors); - } - - if(stateBits & ATTR_LIGHTDIRECTION) - { - dataSize += sizeof(uint32_t); - } - - // create VBO - dataSize *= numVertexes; - data = ri.Hunk_AllocateTempMemory(dataSize); - dataOfs = 0; - - vbo->ofs_xyz = 0; - vbo->ofs_normal = 0; -#ifdef USE_VERT_TANGENT_SPACE - vbo->ofs_tangent = 0; -#endif - vbo->ofs_st = 0; - vbo->ofs_lightmap = 0; - vbo->ofs_vertexcolor = 0; - vbo->ofs_lightdir = 0; - - vbo->stride_xyz = sizeof(verts[0].xyz); - vbo->stride_normal = sizeof(uint32_t); -#ifdef USE_VERT_TANGENT_SPACE - vbo->stride_tangent = sizeof(uint32_t); -#endif - vbo->stride_vertexcolor = sizeof(verts[0].vertexColors); - vbo->stride_st = sizeof(verts[0].st); - vbo->stride_lightmap = sizeof(verts[0].lightmap); - vbo->stride_lightdir = sizeof(uint32_t); - - //ri.Printf(PRINT_ALL, "2CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor, - //vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor); + uint32_t *p; // xyz - for (i = 0; i < numVertexes; i++) - { - memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz)); - dataOfs += sizeof(verts[i].xyz); - } + memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz)); + dataOfs += sizeof(verts[i].xyz); // normal - if(stateBits & ATTR_NORMAL) - { - vbo->ofs_normal = dataOfs; - for (i = 0; i < numVertexes; i++) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackNormal(verts[i].normal); - - dataOfs += sizeof(uint32_t); - } - } + p = (uint32_t *)(data + dataOfs); + *p = R_VboPackNormal(verts[i].normal); + dataOfs += sizeof(uint32_t); #ifdef USE_VERT_TANGENT_SPACE // tangent - if(stateBits & ATTR_TANGENT) - { - vbo->ofs_tangent = dataOfs; - for (i = 0; i < numVertexes; i++) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackTangent(verts[i].tangent); - - dataOfs += sizeof(uint32_t); - } - } + p = (uint32_t *)(data + dataOfs); + *p = R_VboPackTangent(verts[i].tangent); + dataOfs += sizeof(uint32_t); #endif // vertex texcoords - if(stateBits & ATTR_TEXCOORD) - { - vbo->ofs_st = dataOfs; - for (i = 0; i < numVertexes; i++) - { - memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st)); - dataOfs += sizeof(verts[i].st); - } - } + memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st)); + dataOfs += sizeof(verts[i].st); // feed vertex lightmap texcoords - if(stateBits & ATTR_LIGHTCOORD) - { - vbo->ofs_lightmap = dataOfs; - for (i = 0; i < numVertexes; i++) - { - memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap)); - dataOfs += sizeof(verts[i].lightmap); - } - } + memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap)); + dataOfs += sizeof(verts[i].lightmap); // feed vertex colors - if(stateBits & ATTR_COLOR) - { - vbo->ofs_vertexcolor = dataOfs; - for (i = 0; i < numVertexes; i++) - { - memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors)); - dataOfs += sizeof(verts[i].vertexColors); - } - } + memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors)); + dataOfs += sizeof(verts[i].vertexColors); - // feed vertex lightdirs - if(stateBits & ATTR_LIGHTDIRECTION) - { - vbo->ofs_lightdir = dataOfs; - for (i = 0; i < numVertexes; i++) - { - uint32_t *p = (uint32_t *)(data + dataOfs); - - *p = R_VboPackNormal(verts[i].lightdir); - - dataOfs += sizeof(uint32_t); - } - } + // feed vertex light directions + p = (uint32_t *)(data + dataOfs); + *p = R_VboPackNormal(verts[i].lightdir); + dataOfs += sizeof(uint32_t); } - vbo->vertexesSize = dataSize; qglGenBuffersARB(1, &vbo->vertexesVBO); @@ -556,7 +364,7 @@ IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, v R_CreateIBO2 ============ */ -IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage) +IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes) { IBO_t *ibo; int i; @@ -564,22 +372,7 @@ IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inInd glIndex_t *indexes; int indexesSize; - int glUsage; - - switch (usage) - { - case VBO_USAGE_STATIC: - glUsage = GL_STATIC_DRAW_ARB; - break; - - case VBO_USAGE_DYNAMIC: - glUsage = GL_DYNAMIC_DRAW_ARB; - break; - - default: - Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage); - return NULL; - } + int glUsage = GL_STATIC_DRAW_ARB; if(!numIndexes) return NULL; @@ -756,31 +549,74 @@ void R_InitVBOs(void) offset = 0; - tess.vbo->ofs_xyz = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES; - tess.vbo->ofs_normal = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES; + tess.vbo->attribs[ATTR_INDEX_POSITION ].enabled = 1; + tess.vbo->attribs[ATTR_INDEX_NORMAL ].enabled = 1; #ifdef USE_VERT_TANGENT_SPACE - tess.vbo->ofs_tangent = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES; + tess.vbo->attribs[ATTR_INDEX_TANGENT ].enabled = 1; +#endif + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1; + tess.vbo->attribs[ATTR_INDEX_COLOR ].enabled = 1; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].enabled = 1; + + tess.vbo->attribs[ATTR_INDEX_POSITION ].count = 3; + tess.vbo->attribs[ATTR_INDEX_NORMAL ].count = 4; + tess.vbo->attribs[ATTR_INDEX_TANGENT ].count = 4; + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].count = 2; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].count = 2; + tess.vbo->attribs[ATTR_INDEX_COLOR ].count = 4; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4; + + tess.vbo->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; + tess.vbo->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; + tess.vbo->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT; + tess.vbo->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; + + tess.vbo->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; + tess.vbo->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; + tess.vbo->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE; + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE; + tess.vbo->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE; + + tess.vbo->attribs[ATTR_INDEX_POSITION ].offset = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES; + tess.vbo->attribs[ATTR_INDEX_NORMAL ].offset = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES; +#ifdef USE_VERT_TANGENT_SPACE + tess.vbo->attribs[ATTR_INDEX_TANGENT ].offset = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES; #endif // these next two are actually interleaved - tess.vbo->ofs_st = offset; - tess.vbo->ofs_lightmap = offset + sizeof(tess.texCoords[0][0]); - offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES; + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].offset = offset; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].offset = offset + sizeof(tess.texCoords[0][0]); + offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES; - tess.vbo->ofs_vertexcolor = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES; - tess.vbo->ofs_lightdir = offset; + tess.vbo->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = offset; - tess.vbo->stride_xyz = sizeof(tess.xyz[0]); - tess.vbo->stride_normal = sizeof(tess.normal[0]); + tess.vbo->attribs[ATTR_INDEX_POSITION ].stride = sizeof(tess.xyz[0]); + tess.vbo->attribs[ATTR_INDEX_NORMAL ].stride = sizeof(tess.normal[0]); #ifdef USE_VERT_TANGENT_SPACE - tess.vbo->stride_tangent = sizeof(tess.tangent[0]); + tess.vbo->attribs[ATTR_INDEX_TANGENT ].stride = sizeof(tess.tangent[0]); #endif - tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]); - tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2; - tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2; - tess.vbo->stride_lightdir = sizeof(tess.lightdir[0]); + tess.vbo->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.vertexColors[0]); + tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2; + tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2; + tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = sizeof(tess.lightdir[0]); dataSize = sizeof(tess.indexes[0]) * SHADER_MAX_INDEXES; + tess.attribPointers[ATTR_INDEX_POSITION] = tess.xyz; + tess.attribPointers[ATTR_INDEX_TEXCOORD] = tess.texCoords; + tess.attribPointers[ATTR_INDEX_NORMAL] = tess.normal; +#ifdef USE_VERT_TANGENT_SPACE + tess.attribPointers[ATTR_INDEX_TANGENT] = tess.tangent; +#endif + tess.attribPointers[ATTR_INDEX_COLOR] = tess.vertexColors; + tess.attribPointers[ATTR_INDEX_LIGHTDIRECTION] = tess.lightdir; + tess.ibo = R_CreateIBO("tessVertexArray_IBO", NULL, dataSize, VBO_USAGE_DYNAMIC); R_BindNullVBO(); @@ -882,80 +718,51 @@ void R_VBOList_f(void) /* ============== -RB_UpdateVBOs +RB_UpdateTessVbo Adapted from Tess_UpdateVBOs from xreal Update the default VBO to replace the client side vertex arrays ============== */ -void RB_UpdateVBOs(unsigned int attribBits) +void RB_UpdateTessVbo(unsigned int attribBits) { - GLimp_LogComment("--- RB_UpdateVBOs ---\n"); + GLimp_LogComment("--- RB_UpdateTessVbo ---\n"); backEnd.pc.c_dynamicVboDraws++; // update the default VBO if(tess.numVertexes > 0 && tess.numVertexes <= SHADER_MAX_VERTEXES) { + int attribIndex; + R_BindVBO(tess.vbo); // orphan old buffer so we don't stall on it qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB); - if(attribBits & ATTR_BITS) + // if nothing to set, set everything + if(!(attribBits & ATTR_BITS)) + attribBits = ATTR_BITS; + + if(attribBits & ATTR_TEXCOORD || attribBits & ATTR_LIGHTCOORD) { - if(attribBits & ATTR_POSITION) - { - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0])); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0]), tess.xyz); - } - - if(attribBits & ATTR_TEXCOORD || attribBits & ATTR_LIGHTCOORD) - { - // these are interleaved, so we update both if either need it - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_st, tess.numVertexes * sizeof(tess.texCoords[0][0]) * 2); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_st, tess.numVertexes * sizeof(tess.texCoords[0][0]) * 2, tess.texCoords); - } - - if(attribBits & ATTR_NORMAL) - { - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0])); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal); - } - -#ifdef USE_VERT_TANGENT_SPACE - if(attribBits & ATTR_TANGENT) - { - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0])); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent); - } -#endif - - if(attribBits & ATTR_COLOR) - { - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0])); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors); - } - - if(attribBits & ATTR_LIGHTDIRECTION) - { - //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0])); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir); - } - } - else - { - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0]), tess.xyz); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_st, tess.numVertexes * sizeof(tess.texCoords[0][0]) * 2, tess.texCoords); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal); -#ifdef USE_VERT_TANGENT_SPACE - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent); -#endif - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors); - qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir); + // these are interleaved, so we update both if either need it + // this translates to updating ATTR_TEXCOORD twice as large as it needs + attribBits &= ~ATTR_LIGHTCOORD; + attribBits |= ATTR_TEXCOORD; } + for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) + { + if (attribBits & (1 << attribIndex)) + { + vaoAttrib_t *vAtb = &tess.vbo->attribs[attribIndex]; + + // note: tess is a VBO where stride == size + qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]); + } + } } // update the default IBO