void Vao_SetVertexPointers(vao_t *vao) { int attribIndex; // set vertex pointers for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) { uint32_t attribBit = 1 << attribIndex; vaoAttrib_t *vAtb = &vao->attribs[attribIndex]; if (vAtb->enabled) { qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset)); if (glRefConfig.vertexArrayObject || !(glState.vertexAttribsEnabled & attribBit)) qglEnableVertexAttribArray(attribIndex); if (!glRefConfig.vertexArrayObject || vao == tess.vao) glState.vertexAttribsEnabled |= attribBit; } else { // don't disable vertex attribs when using vertex array objects // Vao_SetVertexPointers is only called during init when using VAOs, and vertex attribs start disabled anyway if (!glRefConfig.vertexArrayObject && (glState.vertexAttribsEnabled & attribBit)) qglDisableVertexAttribArray(attribIndex); if (!glRefConfig.vertexArrayObject || vao == tess.vao) glState.vertexAttribsEnabled &= ~attribBit; } } }
void R_AttributePointer (const char* name, GLuint size, const GLvoid* array) { r_progvar_t* v; if (!(v = R_ProgramVariable(GL_ATTRIBUTE, name))) return; qglVertexAttribPointer(v->location, size, GL_FLOAT, GL_FALSE, 0, array); }
/* * @brief */ void R_AttributePointer(const char *name, GLuint size, GLvoid *array) { r_attribute_t attribute; R_ProgramVariable(&attribute, R_ATTRIBUTE, name); qglVertexAttribPointer(attribute.location, size, GL_FLOAT, GL_FALSE, 0, array); R_GetError(name); }
/* ============== RB_UpdateTessVao Adapted from Tess_UpdateVBOs from xreal Update the default VAO to replace the client side vertex arrays ============== */ void RB_UpdateTessVao(unsigned int attribBits) { GLimp_LogComment("--- RB_UpdateTessVao ---\n"); backEnd.pc.c_dynamicVaoDraws++; // update the default VAO if(tess.numVertexes > 0 && tess.numVertexes <= SHADER_MAX_VERTEXES && tess.numIndexes > 0 && tess.numIndexes <= SHADER_MAX_INDEXES) { int attribIndex; int attribUpload; R_BindVao(tess.vao); // orphan old vertex buffer so we don't stall on it qglBufferData(GL_ARRAY_BUFFER, tess.vao->vertexesSize, NULL, GL_DYNAMIC_DRAW); // if nothing to set, set everything if(!(attribBits & ATTR_BITS)) attribBits = ATTR_BITS; attribUpload = attribBits; if((attribUpload & ATTR_TEXCOORD) || (attribUpload & ATTR_LIGHTCOORD)) { // these are interleaved, so we update both if either need it // this translates to updating ATTR_TEXCOORD twice as large as it needs attribUpload &= ~ATTR_LIGHTCOORD; attribUpload |= ATTR_TEXCOORD; } for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) { uint32_t attribBit = 1 << attribIndex; vaoAttrib_t *vAtb = &tess.vao->attribs[attribIndex]; if (attribUpload & attribBit) { // note: tess has a VBO where stride == size qglBufferSubData(GL_ARRAY_BUFFER, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]); } if (attribBits & attribBit) { if (!glRefConfig.vertexArrayObject) qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset)); if (!(glState.vertexAttribsEnabled & attribBit)) { qglEnableVertexAttribArray(attribIndex); glState.vertexAttribsEnabled |= attribBit; } } else { if ((glState.vertexAttribsEnabled & attribBit)) { qglDisableVertexAttribArray(attribIndex); glState.vertexAttribsEnabled &= ~attribBit; } } } // orphan old index buffer so we don't stall on it qglBufferData(GL_ELEMENT_ARRAY_BUFFER, tess.vao->indexesSize, NULL, GL_DYNAMIC_DRAW); qglBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes); } }
void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface) { //mdvModel_t *mdvModel; //mdvSurface_t *mdvSurface; refEntity_t *refEnt; GLimp_LogComment("--- RB_SurfaceVaoMdvMesh ---\n"); if (ShaderRequiresCPUDeforms(tess.shader)) { RB_SurfaceMesh(surface->mdvSurface); return; } if(!surface->vao) return; //RB_CheckVao(surface->vao); RB_EndSurface(); RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex); R_BindVao(surface->vao); tess.useInternalVao = qfalse; tess.numIndexes = surface->numIndexes; tess.numVertexes = surface->numVerts; //mdvModel = surface->mdvModel; //mdvSurface = surface->mdvSurface; refEnt = &backEnd.currentEntity->e; glState.vertexAttribsInterpolation = (refEnt->oldframe == refEnt->frame) ? 0.0f : refEnt->backlerp; if (surface->mdvModel->numFrames > 1) { int frameOffset, attribIndex; vaoAttrib_t *vAtb; glState.vertexAnimation = qtrue; if (glRefConfig.vertexArrayObject) { qglBindBuffer(GL_ARRAY_BUFFER, surface->vao->vertexesVBO); } frameOffset = refEnt->frame * surface->vao->frameSize; attribIndex = ATTR_INDEX_POSITION; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); attribIndex = ATTR_INDEX_NORMAL; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); attribIndex = ATTR_INDEX_TANGENT; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); frameOffset = refEnt->oldframe * surface->vao->frameSize; attribIndex = ATTR_INDEX_POSITION2; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); attribIndex = ATTR_INDEX_NORMAL2; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); attribIndex = ATTR_INDEX_TANGENT2; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset)); if (!glRefConfig.vertexArrayObject) { attribIndex = ATTR_INDEX_TEXCOORD; vAtb = &surface->vao->attribs[attribIndex]; qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset)); } } RB_EndSurface(); // So we don't lerp surfaces that shouldn't be lerped glState.vertexAnimation = qfalse; }