/* * RB_EnableVertexAttribs */ static void RB_EnableVertexAttribs( void ) { vattribmask_t vattribs = rb.currentVAttribs; mesh_vbo_t *vbo = rb.currentVBO; vattribmask_t hfa = vbo->halfFloatAttribs; assert( vattribs & VATTRIB_POSITION_BIT ); if( ( vattribs == rb.gl.lastVAttribs ) && ( hfa == rb.gl.lastHalfFloatVAttribs ) ) { return; } rb.gl.lastVAttribs = vattribs; rb.gl.lastHalfFloatVAttribs = hfa; // xyz position RB_EnableVertexAttrib( VATTRIB_POSITION, true ); qglVertexAttribPointerARB( VATTRIB_POSITION, 4, FLOAT_VATTRIB_GL_TYPE( VATTRIB_POSITION_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )0 ); // normal if( vattribs & VATTRIB_NORMAL_BIT ) { RB_EnableVertexAttrib( VATTRIB_NORMAL, true ); qglVertexAttribPointerARB( VATTRIB_NORMAL, 4, FLOAT_VATTRIB_GL_TYPE( VATTRIB_NORMAL_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->normalsOffset ); } else { RB_EnableVertexAttrib( VATTRIB_NORMAL, false ); } // s-vector if( vattribs & VATTRIB_SVECTOR_BIT ) { RB_EnableVertexAttrib( VATTRIB_SVECTOR, true ); qglVertexAttribPointerARB( VATTRIB_SVECTOR, 4, FLOAT_VATTRIB_GL_TYPE( VATTRIB_SVECTOR_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->sVectorsOffset ); } else { RB_EnableVertexAttrib( VATTRIB_SVECTOR, false ); } // color if( vattribs & VATTRIB_COLOR0_BIT ) { RB_EnableVertexAttrib( VATTRIB_COLOR0, true ); qglVertexAttribPointerARB( VATTRIB_COLOR0, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->vertexSize, (const GLvoid * )vbo->colorsOffset[0] ); } else { RB_EnableVertexAttrib( VATTRIB_COLOR0, false ); } // texture coordinates if( vattribs & VATTRIB_TEXCOORDS_BIT ) { RB_EnableVertexAttrib( VATTRIB_TEXCOORDS, true ); qglVertexAttribPointerARB( VATTRIB_TEXCOORDS, 2, FLOAT_VATTRIB_GL_TYPE( VATTRIB_TEXCOORDS_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->stOffset ); } else { RB_EnableVertexAttrib( VATTRIB_TEXCOORDS, false ); } if( (vattribs & VATTRIB_AUTOSPRITE_BIT) == VATTRIB_AUTOSPRITE_BIT ) { // submit sprite point RB_EnableVertexAttrib( VATTRIB_SPRITEPOINT, true ); qglVertexAttribPointerARB( VATTRIB_SPRITEPOINT, 4, FLOAT_VATTRIB_GL_TYPE( VATTRIB_AUTOSPRITE_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->spritePointsOffset ); } else { RB_EnableVertexAttrib( VATTRIB_SPRITEPOINT, false ); } // bones (skeletal models) if( (vattribs & VATTRIB_BONES_BITS) == VATTRIB_BONES_BITS ) { // submit indices RB_EnableVertexAttrib( VATTRIB_BONESINDICES, true ); qglVertexAttribPointerARB( VATTRIB_BONESINDICES, 4, GL_UNSIGNED_BYTE, GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->bonesIndicesOffset ); // submit weights RB_EnableVertexAttrib( VATTRIB_BONESWEIGHTS, true ); qglVertexAttribPointerARB( VATTRIB_BONESWEIGHTS, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->vertexSize, ( const GLvoid * )vbo->bonesWeightsOffset ); } else { int i; vattrib_t lmattr; vattribbit_t lmattrbit; // lightmap texture coordinates - aliasing bones, so not disabling bones lmattr = VATTRIB_LMCOORDS01; lmattrbit = VATTRIB_LMCOORDS0_BIT; for( i = 0; i < ( MAX_LIGHTMAPS + 1 ) / 2; i++ ) { if( vattribs & lmattrbit ) { RB_EnableVertexAttrib( lmattr, true ); qglVertexAttribPointerARB( lmattr, vbo->lmstSize[i], FLOAT_VATTRIB_GL_TYPE( VATTRIB_LMCOORDS0_BIT, hfa ), GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->lmstOffset[i] ); } else { RB_EnableVertexAttrib( lmattr, false ); } lmattr++; lmattrbit <<= 2; } // lightmap array texture layers lmattr = VATTRIB_LMLAYERS0123; for( i = 0; i < ( MAX_LIGHTMAPS + 3 ) / 4; i++ ) { if( vattribs & ( VATTRIB_LMLAYERS0123_BIT << i ) ) { RB_EnableVertexAttrib( lmattr, true ); qglVertexAttribPointerARB( lmattr, 4, GL_UNSIGNED_BYTE, GL_FALSE, vbo->vertexSize, ( const GLvoid * )vbo->lmlayersOffset[i] ); } else { RB_EnableVertexAttrib( lmattr, false ); } lmattr++; } } if( (vattribs & VATTRIB_INSTANCES_BITS) == VATTRIB_INSTANCES_BITS ) { RB_EnableVertexAttrib( VATTRIB_INSTANCE_QUAT, true ); qglVertexAttribPointerARB( VATTRIB_INSTANCE_QUAT, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( vec_t ), ( const GLvoid * )vbo->instancesOffset ); qglVertexAttribDivisorARB( VATTRIB_INSTANCE_QUAT, 1 ); RB_EnableVertexAttrib( VATTRIB_INSTANCE_XYZS, true ); qglVertexAttribPointerARB( VATTRIB_INSTANCE_XYZS, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( vec_t ), ( const GLvoid * )( vbo->instancesOffset + sizeof( vec_t ) * 4 ) ); qglVertexAttribDivisorARB( VATTRIB_INSTANCE_XYZS, 1 ); } else { RB_EnableVertexAttrib( VATTRIB_INSTANCE_QUAT, false ); RB_EnableVertexAttrib( VATTRIB_INSTANCE_XYZS, false ); } }
/* * RB_EnableVertexAttribs */ static void RB_EnableVertexAttribs( void ) { int i; vattribmask_t vattribs = rb.currentVAttribs; mesh_vbo_t *vbo = rb.currentVBO; // xyz position GL_EnableVertexAttrib( VATTRIB_POSITION, qtrue ); qglVertexAttribPointerARB( VATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )0 ); // normal if( vattribs & VATTRIB_NORMAL_BIT ) { GL_EnableVertexAttrib( VATTRIB_NORMAL, qtrue ); qglVertexAttribPointerARB( VATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->normalsOffset ); } else { GL_EnableVertexAttrib( VATTRIB_NORMAL, qfalse ); } // s-vector if( vattribs & VATTRIB_SVECTOR_BIT ) { GL_EnableVertexAttrib( VATTRIB_SVECTOR, qtrue ); qglVertexAttribPointerARB( VATTRIB_SVECTOR, 4, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->sVectorsOffset ); } else { GL_EnableVertexAttrib( VATTRIB_SVECTOR, qfalse ); } // color if( vattribs & VATTRIB_COLOR_BIT ) { GL_EnableVertexAttrib( VATTRIB_COLOR, qtrue ); qglVertexAttribPointerARB( VATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, ( const GLvoid * )vbo->colorsOffset[0] ); } else { GL_EnableVertexAttrib( VATTRIB_COLOR, qfalse ); } // texture coordinates if( vattribs & VATTRIB_TEXCOORDS_BIT ) { GL_EnableVertexAttrib( VATTRIB_TEXCOORDS, qtrue ); qglVertexAttribPointerARB( VATTRIB_TEXCOORDS, 2, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->stOffset ); } else { GL_EnableVertexAttrib( VATTRIB_TEXCOORDS, qfalse ); } if( (vattribs & VATTRIB_AUTOSPRITE2_BIT) == VATTRIB_AUTOSPRITE2_BIT ) { // submit sprite centre and the longest edge GL_EnableVertexAttrib( VATTRIB_SPRITEPOINT, qtrue ); qglVertexAttribPointerARB( VATTRIB_SPRITEPOINT, 4, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->spritePointsOffset ); GL_EnableVertexAttrib( VATTRIB_SPRITERAXIS, qtrue ); qglVertexAttribPointerARB( VATTRIB_SPRITERAXIS, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->spriteRightAxesOffset ); GL_EnableVertexAttrib( VATTRIB_SPRITEUAXIS, qtrue ); qglVertexAttribPointerARB( VATTRIB_SPRITEUAXIS, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->spriteUpAxesOffset ); } else if( (vattribs & VATTRIB_AUTOSPRITE_BIT) == VATTRIB_AUTOSPRITE_BIT ) { // submit sprite point GL_EnableVertexAttrib( VATTRIB_SPRITERAXIS, qfalse ); GL_EnableVertexAttrib( VATTRIB_SPRITEUAXIS, qfalse ); GL_EnableVertexAttrib( VATTRIB_SPRITEPOINT, qtrue ); qglVertexAttribPointerARB( VATTRIB_SPRITEPOINT, 4, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->spritePointsOffset ); } else { GL_EnableVertexAttrib( VATTRIB_SPRITEPOINT, qfalse ); GL_EnableVertexAttrib( VATTRIB_SPRITERAXIS, qfalse ); GL_EnableVertexAttrib( VATTRIB_SPRITEUAXIS, qfalse ); } // bones (skeletal models) if( (vattribs & VATTRIB_BONES_BIT) == VATTRIB_BONES_BIT ) { // submit indices GL_EnableVertexAttrib( VATTRIB_BONESINDICES, qtrue ); qglVertexAttribPointerARB( VATTRIB_BONESINDICES, 4, GL_UNSIGNED_BYTE, GL_FALSE, SKM_MAX_WEIGHTS, ( const GLvoid * )vbo->bonesIndicesOffset ); // submit weights GL_EnableVertexAttrib( VATTRIB_BONESWEIGHTS, qtrue ); qglVertexAttribPointerARB( VATTRIB_BONESWEIGHTS, 4, GL_UNSIGNED_BYTE, GL_TRUE, SKM_MAX_WEIGHTS, ( const GLvoid * )vbo->bonesWeightsOffset ); } else { GL_EnableVertexAttrib( VATTRIB_BONESINDICES, qfalse ); GL_EnableVertexAttrib( VATTRIB_BONESWEIGHTS, qfalse ); // lightmap texture coordinates if( vattribs & VATTRIB_LMCOORDS_BIT ) { GL_EnableVertexAttrib( VATTRIB_LMCOORDS, qtrue ); qglVertexAttribPointerARB( VATTRIB_LMCOORDS, 2, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->lmstOffset[0] ); } else { GL_EnableVertexAttrib( VATTRIB_LMCOORDS, qfalse ); } for( i = 0; i < MAX_LIGHTMAPS-1; i++ ) { if( vattribs & (VATTRIB_LMCOORDS1_BIT<<i) ) { GL_EnableVertexAttrib( VATTRIB_LMCOORDS1+i, qtrue ); qglVertexAttribPointerARB( VATTRIB_LMCOORDS1+i, 2, GL_FLOAT, GL_FALSE, 0, ( const GLvoid * )vbo->lmstOffset[i+1] ); } else { GL_EnableVertexAttrib( VATTRIB_LMCOORDS1+i, qfalse ); } } } if( (vattribs & VATTRIB_INSTANCES_BIT) == VATTRIB_INSTANCES_BIT ) { GL_EnableVertexAttrib( VATTRIB_INSTANCE_QUAT, qtrue ); qglVertexAttribPointerARB( VATTRIB_INSTANCE_QUAT, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( vec_t ), ( const GLvoid * )vbo->instancesOffset ); qglVertexAttribDivisorARB( VATTRIB_INSTANCE_QUAT, 1 ); GL_EnableVertexAttrib( VATTRIB_INSTANCE_XYZS, qtrue ); qglVertexAttribPointerARB( VATTRIB_INSTANCE_XYZS, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( vec_t ), ( const GLvoid * )( vbo->instancesOffset + sizeof( vec_t ) * 4 ) ); qglVertexAttribDivisorARB( VATTRIB_INSTANCE_XYZS, 1 ); } else { GL_EnableVertexAttrib( VATTRIB_INSTANCE_QUAT, qfalse ); GL_EnableVertexAttrib( VATTRIB_INSTANCE_XYZS, qfalse ); } }