void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp, RenderInfo* ri) { size_t old_vtx_cnt = last_vertex[tp]; size_t old_idx_cnt = last_index[tp]; regenerateBuffer(tp, old_vtx_cnt + mb->getVertexCount(), old_idx_cnt + mb->getIndexCount()); #if !defined(USE_GLES2) if (CVS->supportsAsyncInstanceUpload()) { void *tmp = (char*)VBOPtr[tp] + old_vtx_cnt * getVertexPitch(tp); memcpy(tmp, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp)); } else #endif { glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); glBufferSubData(GL_ARRAY_BUFFER, old_vtx_cnt * getVertexPitch(tp), mb->getVertexCount() * getVertexPitch(tp), mb->getVertices()); } #if !defined(USE_GLES2) if (CVS->supportsAsyncInstanceUpload()) { void *tmp = (char*)IBOPtr[tp] + old_idx_cnt * sizeof(u16); memcpy(tmp, mb->getIndices(), mb->getIndexCount() * sizeof(u16)); } else #endif { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices()); } std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri); mappedBaseVertex[tp][key] = old_vtx_cnt; mappedBaseIndex[tp][key] = old_idx_cnt * sizeof(u16); }
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp) { size_t old_vtx_cnt = last_vertex[tp]; size_t old_idx_cnt = last_index[tp]; regenerateBuffer(tp, old_vtx_cnt + mb->getVertexCount(), old_idx_cnt + mb->getIndexCount()); if (CVS->supportsAsyncInstanceUpload()) { void *tmp = (char*)VBOPtr[tp] + old_vtx_cnt * getVertexPitch(tp); memcpy(tmp, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp)); } else { glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); glBufferSubData(GL_ARRAY_BUFFER, old_vtx_cnt * getVertexPitch(tp), mb->getVertexCount() * getVertexPitch(tp), mb->getVertices()); } if (CVS->supportsAsyncInstanceUpload()) { void *tmp = (char*)IBOPtr[tp] + old_idx_cnt * sizeof(u16); memcpy(tmp, mb->getIndices(), mb->getIndexCount() * sizeof(u16)); } else { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices()); } mappedBaseVertex[tp][mb] = old_vtx_cnt; mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16); }
void VAOManager::regenerateBuffer(enum VTXTYPE tp, size_t newlastvertex, size_t newlastindex) { glBindVertexArray(0); if (newlastindex >= RealVBOSize[tp]) { while (newlastindex >= RealVBOSize[tp]) RealVBOSize[tp] = 2 * RealVBOSize[tp] + 1; GLuint newVBO; glGenBuffers(1, &newVBO); glBindBuffer(GL_ARRAY_BUFFER, newVBO); if (irr_driver->hasBufferStorageExtension()) { glBufferStorage(GL_ARRAY_BUFFER, RealVBOSize[tp] * getVertexPitch(tp), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, RealVBOSize[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); } else glBufferData(GL_ARRAY_BUFFER, RealVBOSize[tp] * getVertexPitch(tp), 0, GL_DYNAMIC_DRAW); if (vbo[tp]) { GLuint oldVBO = vbo[tp]; glBindBuffer(GL_COPY_WRITE_BUFFER, newVBO); glBindBuffer(GL_COPY_READ_BUFFER, oldVBO); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, last_vertex[tp] * getVertexPitch(tp)); glDeleteBuffers(1, &oldVBO); } vbo[tp] = newVBO; } last_vertex[tp] = newlastvertex; if (newlastindex >= RealIBOSize[tp]) { while (newlastindex >= RealIBOSize[tp]) RealIBOSize[tp] = 2 * RealIBOSize[tp] + 1; GLuint newIBO; glGenBuffers(1, &newIBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newIBO); if (irr_driver->hasBufferStorageExtension()) { glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, RealIBOSize[tp] * sizeof(u16), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); IBOPtr[tp] = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, RealIBOSize[tp] * sizeof(u16), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); } else glBufferData(GL_ELEMENT_ARRAY_BUFFER, RealIBOSize[tp] * sizeof(u16), 0, GL_STATIC_DRAW); if (ibo[tp]) { GLuint oldIBO = ibo[tp]; glBindBuffer(GL_COPY_WRITE_BUFFER, newIBO); glBindBuffer(GL_COPY_READ_BUFFER, oldIBO); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, last_index[tp] * sizeof(u16)); glDeleteBuffers(1, &oldIBO); } ibo[tp] = newIBO; } last_index[tp] = newlastindex; }
void VAOManager::regenerateBuffer(enum VTXTYPE tp, size_t newlastvertex, size_t newlastindex) { glBindVertexArray(0); resizeBufferIfNecessary(last_vertex[tp], newlastvertex, RealVBOSize[tp], getVertexPitch(tp), GL_ARRAY_BUFFER, vbo[tp], VBOPtr[tp]); resizeBufferIfNecessary(last_index[tp], newlastindex, RealIBOSize[tp], sizeof(u16), GL_ELEMENT_ARRAY_BUFFER, ibo[tp], IBOPtr[tp]); }
void VAOManager::regenerateVAO(enum VTXTYPE tp) { if (vao[tp]) glDeleteVertexArrays(1, &vao[tp]); glGenVertexArrays(1, &vao[tp]); glBindVertexArray(vao[tp]); glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); switch (tp) { case VTXTYPE_COUNT: break; // avoid compiler warning case VTXTYPE_STANDARD: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); break; case VTXTYPE_TCOORD: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); // SecondTexcoord glEnableVertexAttribArray(4); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); break; case VTXTYPE_TANGENT: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); // Tangent glEnableVertexAttribArray(5); glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); // Bitangent glEnableVertexAttribArray(6); glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48); break; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); glBindVertexArray(0); }