// generate vertex array object void Mesh::generateVAO(int programId) { GLuint tmpID; if (!vao_dirty_) { return; } obtainDeleter(); if (vertices_.size() == 0 && normals_.size() == 0 && tex_coords_.size() == 0) { std::string error = "no vertex data yet, shouldn't call here. "; throw error; } if (0 != normals_.size() && vertices_.size() != normals_.size()) { LOGW("mesh: number of vertices and normals do not match! vertices %d, normals %d", vertices_.size(), normals_.size()); } GLuint vaoID_; GLuint triangle_vboID_; GLuint static_vboID_; auto it = program_ids_.find(programId); if (it != program_ids_.end()) { GLVaoVboId ids = it->second; vaoID_ = ids.vaoID; triangle_vboID_ = ids.triangle_vboID; static_vboID_ = ids.static_vboID; } else { glGenVertexArrays(1, &vaoID_); glGenBuffers(1, &triangle_vboID_); glGenBuffers(1, &static_vboID_); } glBindVertexArray(vaoID_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * indices_.size(), &indices_[0], GL_STATIC_DRAW); numTriangles_ = indices_.size() / 3; attrMapping.clear(); int totalStride; int attrLength; createAttributeMapping(programId, totalStride, attrLength); std::vector<GLfloat> buffer; createBuffer(buffer, attrLength); glBindBuffer(GL_ARRAY_BUFFER, static_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * buffer.size(), &buffer[0], GL_STATIC_DRAW); int localCnt = 0; for ( std::vector<GLAttributeMapping>::iterator it = attrMapping.begin(); it != attrMapping.end(); ++it) { GLAttributeMapping currData = *it; glVertexAttribPointer(currData.index, currData.size, currData.type, 0, totalStride * sizeof(GLfloat), (GLvoid*) (currData.offset * sizeof(GLfloat))); glEnableVertexAttribArray(currData.index); } // done generation glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (it == program_ids_.end()) { GLVaoVboId id; id.vaoID = vaoID_; id.static_vboID = static_vboID_; id.triangle_vboID = triangle_vboID_; program_ids_[programId] = id; } vao_dirty_ = false; }
// generate vertex array object void Mesh::generateVAO() { #if _GVRF_USE_GLES3_ GLuint tmpID; if (!vao_dirty_) { return; } obtainDeleter(); deleteVaos(); if (vertices_.size() == 0 && normals_.size() == 0 && tex_coords_.size() == 0) { std::string error = "no vertex data yet, shouldn't call here. "; throw error; return; } glGenVertexArrays(1, &vaoID_); glBindVertexArray(vaoID_); glGenBuffers(1, &triangle_vboID_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * indices_.size(), &indices_[0], GL_STATIC_DRAW); numTriangles_ = indices_.size() / 3; if (vertices_.size()) { glGenBuffers(1, &vert_vboID_); glBindBuffer(GL_ARRAY_BUFFER, vert_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices_.size(), &vertices_[0], GL_STATIC_DRAW); GLuint vertexLoc = GLProgram::POSITION_ATTRIBUTE_LOCATION; glEnableVertexAttribArray(vertexLoc); glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0); } if (normals_.size()) { glGenBuffers(1, &norm_vboID_); glBindBuffer(GL_ARRAY_BUFFER, norm_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals_.size(), &normals_[0], GL_STATIC_DRAW); GLuint normalLoc = GLProgram::NORMAL_ATTRIBUTE_LOCATION; glEnableVertexAttribArray(normalLoc); glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0); } if (tex_coords_.size()) { glGenBuffers(1, &tex_vboID_); glBindBuffer(GL_ARRAY_BUFFER, tex_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * tex_coords_.size(), &tex_coords_[0], GL_STATIC_DRAW); GLuint texCoordLoc = GLProgram::TEXCOORD_ATTRIBUT_LOCATION; glEnableVertexAttribArray(texCoordLoc); glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_float_keys_.begin(); it != attribute_float_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * getFloatVector(it->second).size(), getFloatVector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 1, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec2_keys_.begin(); it != attribute_vec2_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * getVec2Vector(it->second).size(), getVec2Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec3_keys_.begin(); it != attribute_vec3_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * getVec3Vector(it->second).size(), getVec3Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 3, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec4_keys_.begin(); it != attribute_vec4_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * getVec4Vector(it->second).size(), getVec4Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 4, GL_FLOAT, 0, 0, 0); } // done generation glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); vao_dirty_ = false; #endif }