void VertexLayout::enable(ShaderProgram& _program, size_t _byteOffset, void* _ptr) { GLuint glProgram = _program.getGlProgram(); // Enable all attributes for this layout for (auto& attrib : m_attribs) { GLint location = _program.getAttribLocation(attrib.name); if (location != -1) { auto& loc = s_enabledAttribs[location]; // Track currently enabled attribs by the program to which they are bound if (loc != glProgram) { glEnableVertexAttribArray(location); loc = glProgram; } void* data = _ptr ? _ptr : ((unsigned char*) attrib.offset) + _byteOffset; glVertexAttribPointer(location, attrib.size, attrib.type, attrib.normalized, m_stride, data); } } // Disable previously bound and now-unneeded attributes for (auto& locationProgramPair : s_enabledAttribs) { const GLint& location = locationProgramPair.first; GLuint& boundProgram = locationProgramPair.second; if (boundProgram != glProgram && boundProgram != 0) { glDisableVertexAttribArray(location); boundProgram = 0; } } }
void VertexLayout::enable(RenderState& rs, ShaderProgram& _program, size_t _byteOffset, void* _ptr) { GLuint glProgram = _program.getGlProgram(); // Enable all attributes for this layout for (auto& attrib : m_attribs) { GLint location = _program.getAttribLocation(attrib.name); if (location != -1) { auto& loc = rs.attributeBindings[location]; // Track currently enabled attribs by the program to which they are bound if (loc != glProgram) { GL::enableVertexAttribArray(location); loc = glProgram; } void* data = (unsigned char*)_ptr + attrib.offset + _byteOffset; GL::vertexAttribPointer(location, attrib.size, attrib.type, attrib.normalized, m_stride, data); } } // Disable previously bound and now-unneeded attributes for (size_t i = 0; i < RenderState::MAX_ATTRIBUTES; ++i) { GLuint& boundProgram = rs.attributeBindings[i]; if (boundProgram != glProgram && boundProgram != 0) { GL::disableVertexAttribArray(i); boundProgram = 0; } } }