diff --git a/qglengine/core/glmesh.cpp b/qglengine/core/glmesh.cpp index 952df02..1bba0ef 100644 --- a/qglengine/core/glmesh.cpp +++ b/qglengine/core/glmesh.cpp @@ -57,17 +57,22 @@ Mesh * Mesh::clone() { void Mesh::init(QOpenGLExtraFunctions * f) { - buffer_geom.init(f); - buffer_ind .init(f); - vao.bindBuffers(f, buffer_geom, buffer_ind); - changed = true; + if (!isInit()) { + buffer_geom.init(f); + buffer_ind .init(f); + changed = true; + } } void Mesh::destroy(QOpenGLExtraFunctions * f) { buffer_geom.destroy(f); buffer_ind .destroy(f); - vao.destroy(f); + QList vaol = vao_map.values(); + foreach (VertexObject* vao, vaol) + vao->destroy(f); + qDeleteAll(vao_map); + vao_map.clear(); } @@ -119,6 +124,15 @@ void Mesh::calculateTangents() { } +VertexObject * Mesh::vaoByType(int type) { + VertexObject *& vao(vao_map[type]); + if (!vao) { + vao = new VertexObject(); + } + return vao; +} + + bool Mesh::rebuffer(QOpenGLExtraFunctions * f) { changed = false; if (vertices_.isEmpty()) return true; @@ -159,15 +173,18 @@ bool Mesh::rebuffer(QOpenGLExtraFunctions * f) { } -void Mesh::draw(QOpenGLExtraFunctions * f, int count) { +void Mesh::draw(QOpenGLExtraFunctions * f, int count, int type) { if (isEmpty()) return; if (!isInit()) init(f); if (changed) rebuffer(f); //qDebug() << "draw" << geom_type << vert_count << count; + + VertexObject * vao = vaoByType(type); + vao->bindBuffers(f, buffer_geom, buffer_ind); if (geom_type == GL_TRIANGLES) - vao.draw(f, geom_type, triangles_.size() * 3, count); + vao->draw(f, geom_type, triangles_.size() * 3, count); else - vao.draw(f, geom_type, lines_.size() * 2, count); + vao->draw(f, geom_type, lines_.size() * 2, count); } @@ -184,19 +201,21 @@ void Mesh::clear() { } -void Mesh::loadObject(QOpenGLExtraFunctions * f, const Object & object) { - vao.loadObject(f, object); +void Mesh::loadObject(QOpenGLExtraFunctions * f, const Object & object, int type) { + VertexObject * vao = vaoByType(type); + vao->loadObject(f, object); } -void Mesh::loadObjects(QOpenGLExtraFunctions * f, const QVector & objects) { - vao.loadObjects(f, objects); +void Mesh::loadObjects(QOpenGLExtraFunctions * f, const QVector & objects, int type) { + VertexObject * vao = vaoByType(type); + vao->loadObjects(f, objects); } -void Mesh::loadSelections(QOpenGLExtraFunctions * f, const QVector & sels) { - //qDebug() << "loadSelections" << sels; - vao.loadSelections(f, sels); +void Mesh::loadSelections(QOpenGLExtraFunctions * f, const QVector & sels, int type) { + VertexObject * vao = vaoByType(type); + vao->loadSelections(f, sels); } diff --git a/qglengine/core/glmesh.h b/qglengine/core/glmesh.h index a8a0509..89c49ce 100644 --- a/qglengine/core/glmesh.h +++ b/qglengine/core/glmesh.h @@ -41,16 +41,16 @@ public: void init (QOpenGLExtraFunctions * f); void destroy (QOpenGLExtraFunctions * f); bool rebuffer(QOpenGLExtraFunctions * f); - void draw (QOpenGLExtraFunctions * f, int count); + void draw (QOpenGLExtraFunctions * f, int count, int type = 0); void clear(); - void loadObject (QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object); - void loadObjects (QOpenGLExtraFunctions * f, const QVector & objects); - void loadSelections(QOpenGLExtraFunctions * f, const QVector & sels); + void loadObject (QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object, int type = 0); + void loadObjects (QOpenGLExtraFunctions * f, const QVector & objects, int type = 0); + void loadSelections(QOpenGLExtraFunctions * f, const QVector & sels, int type = 0); int verticesCount() const {return vertices_.size();} int trianglesCount() const {return triangles_.size();} int linesCount() const {return lines_.size();} - bool isInit() const {return vao.isInit();} + bool isInit() const {return buffer_geom.isInit();} bool isEmpty() const {return vertices_.isEmpty();} uint hash() const; @@ -78,6 +78,7 @@ public: private: void calculateNormals(); void calculateTangents(); + VertexObject * vaoByType(int type); QVector vertices_, normals_, tangents_, bitangents_; QVector texcoords_; @@ -87,7 +88,7 @@ private: QVector data_; GLenum geom_type; Buffer buffer_geom, buffer_ind; - VertexObject vao; + QMap vao_map; mutable uint hash_; mutable bool hash_changed; int vert_count; diff --git a/qglengine/core/glvertexobject.cpp b/qglengine/core/glvertexobject.cpp index 34008a8..b400900 100644 --- a/qglengine/core/glvertexobject.cpp +++ b/qglengine/core/glvertexobject.cpp @@ -27,6 +27,7 @@ VertexObject::VertexObject(): buffer_obj (GL_ARRAY_BUFFER, GL_STREAM_DRAW), buffer_sel (GL_ARRAY_BUFFER, GL_STREAM_DRAW) { vao_ = 0; + buffers_binded = false; } @@ -64,7 +65,10 @@ void VertexObject::release(QOpenGLExtraFunctions * f) { } -void VertexObject::bindBuffers(QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem) { +void VertexObject::bindBuffers(QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem, bool force) { + if (!force && buffers_binded) return; + buffers_binded = true; + init(f); bind(f); diff --git a/qglengine/core/glvertexobject.h b/qglengine/core/glvertexobject.h index 4bc9d1a..af3f1ab 100644 --- a/qglengine/core/glvertexobject.h +++ b/qglengine/core/glvertexobject.h @@ -36,7 +36,7 @@ public: void bind (QOpenGLExtraFunctions * f); void release (QOpenGLExtraFunctions * f); - void bindBuffers (QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem); + void bindBuffers (QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem, bool force = false); void loadObject (QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object); void loadObjects (QOpenGLExtraFunctions * f, const QVector & objects); void loadSelections(QOpenGLExtraFunctions * f, const QVector & sels); @@ -51,6 +51,7 @@ private: GLuint vao_; Buffer buffer_obj, buffer_sel; + bool buffers_binded; };