OpenGL2: VBO cleanup.

This commit is contained in:
SmileTheory 2014-10-13 21:57:06 -07:00
parent c04d05fd8f
commit 873a02bd3c
8 changed files with 300 additions and 666 deletions

View File

@ -2050,17 +2050,8 @@ static void R_CreateWorldVBOs(void)
} }
} }
#ifdef USE_VERT_TANGENT_SPACE vbo = R_CreateVBO2(va("staticBspModel%i_VBO", k), numVerts, verts);
vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, ibo = R_CreateIBO2(va("staticBspModel%i_IBO", k), numIndexes, indexes);
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);
// point bsp surfaces to VBO // point bsp surfaces to VBO
for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)

View File

@ -537,10 +537,10 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position"); qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position");
if(attribs & ATTR_TEXCOORD) if(attribs & ATTR_TEXCOORD)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD0, "attr_TexCoord0"); qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0");
if(attribs & ATTR_LIGHTCOORD) if(attribs & ATTR_LIGHTCOORD)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD1, "attr_TexCoord1"); qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1");
// if(attribs & ATTR_TEXCOORD2) // if(attribs & ATTR_TEXCOORD2)
// qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "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) // if(attribs & ATTR_TEXCOORD3)
// qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3"); // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
#ifdef USE_VERT_TANGENT_SPACE
if(attribs & ATTR_TANGENT) if(attribs & ATTR_TANGENT)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
#endif
if(attribs & ATTR_NORMAL) if(attribs & ATTR_NORMAL)
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "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) if(attribs & ATTR_NORMAL2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
#ifdef USE_VERT_TANGENT_SPACE
if(attribs & ATTR_TANGENT2) if(attribs & ATTR_TANGENT2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
#endif
GLSL_LinkProgram(program->program); GLSL_LinkProgram(program->program);
@ -1412,20 +1408,9 @@ void GLSL_ShutdownGPUShaders(void)
ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n"); ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n");
qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); for (i = 0; i < ATTR_INDEX_COUNT; i++)
qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); qglDisableVertexAttribArrayARB(i);
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);
GLSL_BindNullProgram(); GLSL_BindNullProgram();
for ( i = 0; i < GENERICDEF_COUNT; i++) for ( i = 0; i < GENERICDEF_COUNT; i++)
@ -1502,155 +1487,26 @@ void GLSL_BindNullProgram(void)
void GLSL_VertexAttribsState(uint32_t stateBits) 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"); if (stateBits & attribBit)
qglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION); {
} qglEnableVertexAttribArrayARB(attribIndex);
else }
{ else
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_POSITION )\n"); {
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); 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); GLSL_VertexAttribPointers(stateBits);
@ -1660,9 +1516,10 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
void GLSL_VertexAttribPointers(uint32_t attribBits) void GLSL_VertexAttribPointers(uint32_t attribBits)
{ {
qboolean animated;
int newFrame, oldFrame; int newFrame, oldFrame;
VBO_t *vbo = glState.currentVBO; VBO_t *vbo = glState.currentVBO;
int attribIndex;
uint32_t extraOffsets[ATTR_INDEX_COUNT];
if(!vbo) if(!vbo)
{ {
@ -1676,95 +1533,36 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", vbo->name)); 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 // position/normal/tangent are always set in case of animation
oldFrame = glState.vertexAttribsOldFrame; oldFrame = glState.vertexAttribsOldFrame;
newFrame = glState.vertexAttribsNewFrame; newFrame = glState.vertexAttribsNewFrame;
animated = glState.vertexAnimation; if (glState.vertexAnimation)
if((attribBits & ATTR_POSITION) && (!(glState.vertexAttribPointersSet & ATTR_POSITION) || animated))
{ {
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION )\n"); glState.vertexAttribPointersSet &= ~(ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TANGENT | ATTR_TANGENT2);
extraOffsets[ATTR_INDEX_POSITION] = newFrame * vbo->size_xyz;
qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + newFrame * vbo->size_xyz)); extraOffsets[ATTR_INDEX_POSITION2] = oldFrame * vbo->size_xyz;
glState.vertexAttribPointersSet |= ATTR_POSITION; 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)); if (!(attribBits & attribBit) || (glState.vertexAttribPointersSet & attribBit))
glState.vertexAttribPointersSet |= ATTR_TEXCOORD; 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
} }

View File

@ -96,40 +96,36 @@ typedef struct {
float transformMatrix[16]; float transformMatrix[16];
} orientationr_t; } orientationr_t;
// Ensure this is >= the ATTR_INDEX_COUNT enum below
#define VAO_MAX_ATTRIBS 16
typedef enum typedef enum
{ {
VBO_USAGE_STATIC, VBO_USAGE_STATIC,
VBO_USAGE_DYNAMIC VBO_USAGE_DYNAMIC
} vboUsage_t; } 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 typedef struct VBO_s
{ {
char name[MAX_QPATH]; char name[MAX_QPATH];
uint32_t vertexesVBO; uint32_t vertexesVBO;
int vertexesSize; // amount of memory data allocated for all vertices in bytes int vertexesSize; // amount of memory data allocated for all vertices in bytes
uint32_t ofs_xyz; vaoAttrib_t attribs[VAO_MAX_ATTRIBS];
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
uint32_t size_xyz; uint32_t size_xyz;
uint32_t size_normal; uint32_t size_normal;
int attribs;
} VBO_t; } VBO_t;
typedef struct IBO_s typedef struct IBO_s
@ -514,8 +510,8 @@ static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
enum enum
{ {
ATTR_INDEX_POSITION = 0, ATTR_INDEX_POSITION = 0,
ATTR_INDEX_TEXCOORD0 = 1, ATTR_INDEX_TEXCOORD = 1,
ATTR_INDEX_TEXCOORD1 = 2, ATTR_INDEX_LIGHTCOORD = 2,
ATTR_INDEX_TANGENT = 3, ATTR_INDEX_TANGENT = 3,
ATTR_INDEX_NORMAL = 4, ATTR_INDEX_NORMAL = 4,
ATTR_INDEX_COLOR = 5, ATTR_INDEX_COLOR = 5,
@ -527,26 +523,28 @@ enum
// GPU vertex animations // GPU vertex animations
ATTR_INDEX_POSITION2 = 10, ATTR_INDEX_POSITION2 = 10,
ATTR_INDEX_TANGENT2 = 11, ATTR_INDEX_TANGENT2 = 11,
ATTR_INDEX_NORMAL2 = 12 ATTR_INDEX_NORMAL2 = 12,
ATTR_INDEX_COUNT = 13
}; };
enum enum
{ {
ATTR_POSITION = 0x0001, ATTR_POSITION = 1 << ATTR_INDEX_POSITION,
ATTR_TEXCOORD = 0x0002, ATTR_TEXCOORD = 1 << ATTR_INDEX_TEXCOORD,
ATTR_LIGHTCOORD = 0x0004, ATTR_LIGHTCOORD = 1 << ATTR_INDEX_LIGHTCOORD,
ATTR_TANGENT = 0x0008, ATTR_TANGENT = 1 << ATTR_INDEX_TANGENT,
ATTR_NORMAL = 0x0010, ATTR_NORMAL = 1 << ATTR_INDEX_NORMAL,
ATTR_COLOR = 0x0020, ATTR_COLOR = 1 << ATTR_INDEX_COLOR,
ATTR_PAINTCOLOR = 0x0040, ATTR_PAINTCOLOR = 1 << ATTR_INDEX_PAINTCOLOR,
ATTR_LIGHTDIRECTION = 0x0080, ATTR_LIGHTDIRECTION = 1 << ATTR_INDEX_LIGHTDIRECTION,
ATTR_BONE_INDEXES = 0x0100, ATTR_BONE_INDEXES = 1 << ATTR_INDEX_BONE_INDEXES,
ATTR_BONE_WEIGHTS = 0x0200, ATTR_BONE_WEIGHTS = 1 << ATTR_INDEX_BONE_WEIGHTS,
// for .md3 interpolation // for .md3 interpolation
ATTR_POSITION2 = 0x0400, ATTR_POSITION2 = 1 << ATTR_INDEX_POSITION2,
ATTR_TANGENT2 = 0x0800, ATTR_TANGENT2 = 1 << ATTR_INDEX_TANGENT2,
ATTR_NORMAL2 = 0x1000, ATTR_NORMAL2 = 1 << ATTR_INDEX_NORMAL2,
ATTR_DEFAULT = ATTR_POSITION, ATTR_DEFAULT = ATTR_POSITION,
ATTR_BITS = ATTR_POSITION | ATTR_BITS = ATTR_POSITION |
@ -2033,6 +2031,7 @@ typedef struct shaderCommands_s
uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16); uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
//int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16); //int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
void *attribPointers[ATTR_INDEX_COUNT];
VBO_t *vbo; VBO_t *vbo;
IBO_t *ibo; IBO_t *ibo;
qboolean useInternalVBO; qboolean useInternalVBO;
@ -2201,10 +2200,10 @@ void R_VboUnpackTangent(vec4_t v, uint32_t b);
void R_VboUnpackNormal(vec3_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_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_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_BindVBO(VBO_t * vbo);
void R_BindNullVBO(void); void R_BindNullVBO(void);
@ -2216,7 +2215,7 @@ void R_InitVBOs(void);
void R_ShutdownVBOs(void); void R_ShutdownVBOs(void);
void R_VBOList_f(void); void R_VBOList_f(void);
void RB_UpdateVBOs(unsigned int attribBits); void RB_UpdateTessVbo(unsigned int attribBits);
/* /*

View File

@ -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 = R_CreateVBO(va("staticMD3Mesh_VBO '%s'", surf->name), data, dataSize, VBO_USAGE_STATIC);
vboSurf->vbo->ofs_xyz = ofs_xyz; vboSurf->vbo->attribs[ATTR_INDEX_POSITION ].enabled = 1;
vboSurf->vbo->ofs_normal = ofs_normal; 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 #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 #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 #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 #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; vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts;
ri.Free(data); 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);
} }
} }

View File

@ -1498,7 +1498,7 @@ void RB_StageIteratorGeneric( void )
if (tess.useInternalVBO) if (tess.useInternalVBO)
{ {
RB_UpdateVBOs(vertexAttribs); RB_UpdateTessVbo(vertexAttribs);
} }
else else
{ {

View File

@ -421,7 +421,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
tess.maxIndex = tess.numVertexes; tess.maxIndex = tess.numVertexes;
// FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function // 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; shaderProgram_t *sp = &tr.textureColorShader;

View File

@ -203,7 +203,7 @@ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4])
tess.minIndex = 0; tess.minIndex = 0;
tess.maxIndex = 3; tess.maxIndex = 3;
RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD); RB_UpdateTessVbo(ATTR_POSITION | ATTR_TEXCOORD);
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
@ -601,7 +601,7 @@ static void RB_SurfaceBeam( void )
tess.maxIndex = tess.numVertexes; tess.maxIndex = tess.numVertexes;
// FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function // 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_VertexAttribsState(ATTR_POSITION);
GLSL_BindProgram(sp); GLSL_BindProgram(sp);

View File

@ -155,7 +155,7 @@ VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize,
R_CreateVBO2 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; VBO_t *vbo;
int i; int i;
@ -164,22 +164,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
int dataSize; int dataSize;
int dataOfs; int dataOfs;
int glUsage; int glUsage = GL_STATIC_DRAW_ARB;
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;
}
if(!numVertexes) if(!numVertexes)
return NULL; 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)); 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 uint32_t *p;
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);
// xyz // 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 // normal
if(stateBits & ATTR_NORMAL) p = (uint32_t *)(data + dataOfs);
{ *p = R_VboPackNormal(verts[i].normal);
vbo->ofs_normal = dataOfs; dataOfs += sizeof(uint32_t);
for (i = 0; i < numVertexes; i++)
{
uint32_t *p = (uint32_t *)(data + dataOfs);
*p = R_VboPackNormal(verts[i].normal);
dataOfs += sizeof(uint32_t);
}
}
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
// tangent // tangent
if(stateBits & ATTR_TANGENT) p = (uint32_t *)(data + dataOfs);
{ *p = R_VboPackTangent(verts[i].tangent);
vbo->ofs_tangent = dataOfs; dataOfs += sizeof(uint32_t);
for (i = 0; i < numVertexes; i++)
{
uint32_t *p = (uint32_t *)(data + dataOfs);
*p = R_VboPackTangent(verts[i].tangent);
dataOfs += sizeof(uint32_t);
}
}
#endif #endif
// vertex texcoords // vertex texcoords
if(stateBits & ATTR_TEXCOORD) memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
{ dataOfs += sizeof(verts[i].st);
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);
}
}
// feed vertex lightmap texcoords // feed vertex lightmap texcoords
if(stateBits & ATTR_LIGHTCOORD) memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap));
{ dataOfs += sizeof(verts[i].lightmap);
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);
}
}
// feed vertex colors // feed vertex colors
if(stateBits & ATTR_COLOR) memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors));
{ dataOfs += sizeof(verts[i].vertexColors);
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);
}
}
// feed vertex lightdirs // feed vertex light directions
if(stateBits & ATTR_LIGHTDIRECTION) p = (uint32_t *)(data + dataOfs);
{ *p = R_VboPackNormal(verts[i].lightdir);
vbo->ofs_lightdir = dataOfs; dataOfs += sizeof(uint32_t);
for (i = 0; i < numVertexes; i++)
{
uint32_t *p = (uint32_t *)(data + dataOfs);
*p = R_VboPackNormal(verts[i].lightdir);
dataOfs += sizeof(uint32_t);
}
}
} }
vbo->vertexesSize = dataSize; vbo->vertexesSize = dataSize;
qglGenBuffersARB(1, &vbo->vertexesVBO); qglGenBuffersARB(1, &vbo->vertexesVBO);
@ -556,7 +364,7 @@ IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, v
R_CreateIBO2 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; IBO_t *ibo;
int i; int i;
@ -564,22 +372,7 @@ IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inInd
glIndex_t *indexes; glIndex_t *indexes;
int indexesSize; int indexesSize;
int glUsage; int glUsage = GL_STATIC_DRAW_ARB;
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;
}
if(!numIndexes) if(!numIndexes)
return NULL; return NULL;
@ -756,31 +549,74 @@ void R_InitVBOs(void)
offset = 0; offset = 0;
tess.vbo->ofs_xyz = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES; tess.vbo->attribs[ATTR_INDEX_POSITION ].enabled = 1;
tess.vbo->ofs_normal = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES; tess.vbo->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
#ifdef USE_VERT_TANGENT_SPACE #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 #endif
// these next two are actually interleaved // these next two are actually interleaved
tess.vbo->ofs_st = offset; tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].offset = offset;
tess.vbo->ofs_lightmap = offset + sizeof(tess.texCoords[0][0]); tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].offset = offset + sizeof(tess.texCoords[0][0]);
offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES; 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->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES;
tess.vbo->ofs_lightdir = offset; tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = offset;
tess.vbo->stride_xyz = sizeof(tess.xyz[0]); tess.vbo->attribs[ATTR_INDEX_POSITION ].stride = sizeof(tess.xyz[0]);
tess.vbo->stride_normal = sizeof(tess.normal[0]); tess.vbo->attribs[ATTR_INDEX_NORMAL ].stride = sizeof(tess.normal[0]);
#ifdef USE_VERT_TANGENT_SPACE #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 #endif
tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]); tess.vbo->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.vertexColors[0]);
tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->attribs[ATTR_INDEX_TEXCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->attribs[ATTR_INDEX_LIGHTCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
tess.vbo->stride_lightdir = sizeof(tess.lightdir[0]); tess.vbo->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = sizeof(tess.lightdir[0]);
dataSize = sizeof(tess.indexes[0]) * SHADER_MAX_INDEXES; 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); tess.ibo = R_CreateIBO("tessVertexArray_IBO", NULL, dataSize, VBO_USAGE_DYNAMIC);
R_BindNullVBO(); R_BindNullVBO();
@ -882,80 +718,51 @@ void R_VBOList_f(void)
/* /*
============== ==============
RB_UpdateVBOs RB_UpdateTessVbo
Adapted from Tess_UpdateVBOs from xreal Adapted from Tess_UpdateVBOs from xreal
Update the default VBO to replace the client side vertex arrays 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++; backEnd.pc.c_dynamicVboDraws++;
// update the default VBO // update the default VBO
if(tess.numVertexes > 0 && tess.numVertexes <= SHADER_MAX_VERTEXES) if(tess.numVertexes > 0 && tess.numVertexes <= SHADER_MAX_VERTEXES)
{ {
int attribIndex;
R_BindVBO(tess.vbo); R_BindVBO(tess.vbo);
// orphan old buffer so we don't stall on it // orphan old buffer so we don't stall on it
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB); 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) // these are interleaved, so we update both if either need it
{ // this translates to updating ATTR_TEXCOORD twice as large as it needs
//ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0])); attribBits &= ~ATTR_LIGHTCOORD;
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0]), tess.xyz); attribBits |= ATTR_TEXCOORD;
}
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);
} }
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 // update the default IBO