@@ -759,6 +759,58 @@ void Mesh::loadOBJ(const std::string* objSource) {
759759 updateGPU ();
760760}
761761
762+ void Mesh::updateGPU () {
763+
764+ vao.bind ();
765+ delete vbo;
766+ delete ebo;
767+ vbo = new VBO (vertices);
768+ ebo = new EBO (indices);
769+
770+ vbo->linkVertexAttrib (0 , 3 , GL_FLOAT, sizeof (Vertex), (void *)0 );
771+ vbo->linkVertexAttrib (1 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(3 * sizeof (float )));
772+ vbo->linkVertexAttrib (2 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(6 * sizeof (float )));
773+ vbo->linkVertexAttrib (3 , 2 , GL_FLOAT, sizeof (Vertex), (void *)(9 * sizeof (float )));
774+
775+ Message (0 , " MESH" , " OBJ loaded successfully" , " STRING" , 1 );
776+ }
777+
778+ void Mesh::updateGPUAsync () {
779+ if (!ready) return ;
780+
781+ std::lock_guard<std::mutex> lock (parseMutex);
782+ if (!parseData.has_value ()) return ;
783+
784+ auto & [verts, inds] = *parseData;
785+
786+ vao.bind ();
787+ delete vbo;
788+ delete ebo;
789+ vbo = new VBO (vertices);
790+ ebo = new EBO (indices);
791+
792+ vbo->linkVertexAttrib (0 , 3 , GL_FLOAT, sizeof (Vertex), (void *)0 );
793+ vbo->linkVertexAttrib (1 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(3 * sizeof (float )));
794+ vbo->linkVertexAttrib (2 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(6 * sizeof (float )));
795+ vbo->linkVertexAttrib (3 , 2 , GL_FLOAT, sizeof (Vertex), (void *)(9 * sizeof (float )));
796+
797+ Message (0 , " MESH" , " OBJ loaded successfully" , " STRING" , 1 );
798+
799+ parseData.reset ();
800+ ready = false ;
801+
802+ }
803+
804+ int GetOrAddVertex (std::vector<Vertex>& vertices, const Vertex& v) {
805+ for (size_t i = 0 ; i < vertices.size (); i++) {
806+ if (memcmp (&vertices[i], &v, sizeof (Vertex)) == 0 ) {
807+ return static_cast <int >(i);
808+ }
809+ }
810+ vertices.push_back (v);
811+ return static_cast <int >(vertices.size () - 1 );
812+ }
813+
762814void Mesh::parseOBJString (const std::string* objSource, std::vector<Vertex>& outVerts, std::vector<GLuint>& outIndices) {
763815
764816 std::vector<glm::vec3> positions;
@@ -851,33 +903,6 @@ void Mesh::parseOBJString(const std::string* objSource, std::vector<Vertex>& out
851903 }
852904}
853905
854- void Mesh::updateGPU () {
855-
856- vao.bind ();
857- delete vbo;
858- delete ebo;
859- vbo = new VBO (vertices);
860- ebo = new EBO (indices);
861-
862- vbo->linkVertexAttrib (0 , 3 , GL_FLOAT, sizeof (Vertex), (void *)0 );
863- vbo->linkVertexAttrib (1 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(3 * sizeof (float )));
864- vbo->linkVertexAttrib (2 , 3 , GL_FLOAT, sizeof (Vertex), (void *)(6 * sizeof (float )));
865- vbo->linkVertexAttrib (3 , 2 , GL_FLOAT, sizeof (Vertex), (void *)(9 * sizeof (float )));
866-
867- Message (0 , " MESH" , " OBJ loaded successfully" , " STRING" , 1 );
868-
869- }
870-
871- int Mesh::GetOrAddVertex (std::vector<Vertex>& vertices, const Vertex& v) {
872- for (size_t i = 0 ; i < vertices.size (); i++) {
873- if (memcmp (&vertices[i], &v, sizeof (Vertex)) == 0 ) {
874- return static_cast <int >(i);
875- }
876- }
877- vertices.push_back (v);
878- return static_cast <int >(vertices.size () - 1 );
879- }
880-
881906void Mesh::draw (Shader& shader, const glm::mat4& modelMatrix) {
882907 shader.activate ();
883908 vao.bind ();
@@ -946,6 +971,58 @@ void Mesh::makePreview(Framebuffer& fb, Shader& shader, glm::vec2 rotation, bool
946971 fb.unbind ();
947972}
948973
974+ void Mesh::loadOBJAsync (const std::string& objPath) {
975+ if (parsing) return ;
976+
977+ parsing = true ;
978+ ready = false ;
979+
980+ std::thread ([this , objPath]() {
981+ std::vector<Vertex> verts;
982+ std::vector<GLuint> inds;
983+
984+ std::ifstream file (objPath);
985+ if (!file.is_open ()) {
986+ Message (2 , " MESH" , " Failed to open OBJ file " + objPath, objPath.c_str (), 1 );
987+ return ;
988+ }
989+
990+ std::string source ((std::istreambuf_iterator<char >(file)), std::istreambuf_iterator<char >());
991+
992+ parseOBJString (&source, verts, inds);
993+
994+ {
995+ std::lock_guard<std::mutex> lock (parseMutex);
996+ parseData = std::make_pair (std::move (verts), std::move (inds));
997+ }
998+
999+ parsing = false ;
1000+ ready = true ;
1001+ }).detach ();
1002+ }
1003+
1004+ void Mesh::loadOBJAsync (const std::string* objSource) {
1005+ if (parsing) return ;
1006+
1007+ parsing = true ;
1008+ ready = false ;
1009+
1010+ std::thread ([this , objSource]() {
1011+ std::vector<Vertex> verts;
1012+ std::vector<GLuint> inds;
1013+
1014+ parseOBJString (objSource, verts, inds);
1015+
1016+ {
1017+ std::lock_guard<std::mutex> lock (parseMutex);
1018+ parseData = std::make_pair (std::move (verts), std::move (inds));
1019+ }
1020+
1021+ parsing = false ;
1022+ ready = true ;
1023+ }).detach ();
1024+ }
1025+
9491026Mesh::~Mesh () {
9501027 delete vbo;
9511028 delete ebo;
0 commit comments