tBane Temat założony przez niniejszego użytkownika |
» 2025-07-01 10:06:59 Tak, z assetstory od Unity bo tam jest wiele modeli. Tylko większość jest w formacie FBX. Udało mi się załadować wierzchołki, uv i normalne. Ale jak wczytać animację to nie mam pojęcia. Wiem, że można pobierać współrzędne wierzchołków z polygonów po transformacji kości. Ale czy to optymalne rozwiązanie ? Wszystko renderuje przez GLFW więc innej opcji nie widzę .. load FBXvoid loadFBX() { meshes.clear(); FbxManager * manager = FbxManager::Create(); FbxIOSettings * ios = FbxIOSettings::Create( manager, IOSROOT ); manager->SetIOSettings( ios ); FbxImporter * importer = FbxImporter::Create( manager, "" ); if( !importer->Initialize( "mdl\\knight.FBX", - 1, manager->GetIOSettings() ) ) { std::cerr << "Błąd: nie udało się wczytać modelu." << std::endl; return; } FbxScene * scene = FbxScene::Create( manager, "myScene" ); importer->Import( scene ); importer->Destroy(); FbxNode * root = scene->GetRootNode(); if( !root ) return; FbxSystemUnit sys = scene->GetGlobalSettings().GetSystemUnit(); std::cout << "Scene unit scale: " << sys.GetScaleFactor() << std::endl; double scaleFactor = sys.GetScaleFactor(); std::function < void( FbxNode * ) > traverse =[ & ]( FbxNode * node ) { FbxMesh * mesh = node->GetMesh(); if( mesh ) { Mesh m; const int polygonCount = mesh->GetPolygonCount(); FbxVector4 * controlPoints = mesh->GetControlPoints(); FbxGeometryElementUV * uvElement = mesh->GetElementUV(); FbxGeometryElementNormal * normalElement = mesh->GetElementNormal(); for( int polyIndex = 0; polyIndex < polygonCount; ++polyIndex ) { for( int vert = 0; vert < 3; ++vert ) { int ctrlIndex = mesh->GetPolygonVertex( polyIndex, vert ); FbxVector4 v = controlPoints[ ctrlIndex ]; FbxVector2 uv( 0, 0 ); bool unmapped = false; if( uvElement ) mesh->GetPolygonVertexUV( polyIndex, vert, uvElement->GetName(), uv, unmapped ); FbxVector4 n( 0, 1, 0 ); if( normalElement ) { int idx = polyIndex * 3 + vert; if( normalElement->GetReferenceMode() == FbxGeometryElement::eDirect ) n = normalElement->GetDirectArray().GetAt( idx ); else if( normalElement->GetReferenceMode() == FbxGeometryElement::eIndexToDirect ) { int nidx = normalElement->GetIndexArray().GetAt( idx ); n = normalElement->GetDirectArray().GetAt( nidx ); } } vertice vv; const float globalFix = 0.1f; double sceneScale = scene->GetGlobalSettings().GetSystemUnit().GetScaleFactor(); float scaleFactor = 1.0f / static_cast < float >( sceneScale ); vv.x = float( v[ 0 ] ) * scaleFactor * globalFix; vv.y = float( v[ 2 ] ) * scaleFactor * globalFix; vv.z = - float( v[ 1 ] ) * scaleFactor * globalFix; vv.u = float( uv[ 0 ] ); vv.v = float( uv[ 1 ] ); vv.nx = float( n[ 0 ] ); vv.ny = float( n[ 2 ] ); vv.nz = - float( n[ 1 ] ); m.vertices.push_back( vv ); } } m.material = getMaterial( L"DemoKnightMaterial" ); meshes.push_back( m ); } for( int i = 0; i < node->GetChildCount(); ++i ) traverse( node->GetChild( i ) ); }; traverse( root ); std::vector < vertice > buffer_vertices; mesh_draw_ranges.clear(); int offset = 0; for( const auto & mesh: meshes ) { mesh_draw_ranges.emplace_back( offset, mesh.vertices.size() ); buffer_vertices.insert( buffer_vertices.end(), mesh.vertices.begin(), mesh.vertices.end() ); offset += mesh.vertices.size(); } glGenVertexArrays( 1, & VAO ); glGenBuffers( 1, & VBO ); glBindVertexArray( VAO ); glBindBuffer( GL_ARRAY_BUFFER, VBO ); glBufferData( GL_ARRAY_BUFFER, buffer_vertices.size() * sizeof( vertice ), buffer_vertices.data(), GL_STATIC_DRAW ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof( vertice ),( void * ) offsetof( vertice, x ) ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, sizeof( vertice ),( void * ) offsetof( vertice, u ) ); glEnableVertexAttribArray( 1 ); glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, sizeof( vertice ),( void * ) offsetof( vertice, nx ) ); glEnableVertexAttribArray( 2 ); glBindVertexArray( 0 ); }
funckja renderująca w GLFWvoid draw() { Program * program = getProgram( L"advanced program" ); glBindVertexArray( VAO ); for( int i = 0; i < meshes.size(); ++i ) { glUseProgram( program->shader_program ); glActiveTexture( GL_TEXTURE0 ); ( meshes[ i ].material != nullptr ) ? glBindTexture( GL_TEXTURE_2D, meshes[ i ].material->texture->id ) : glBindTexture( GL_TEXTURE_2D, 0 ); glUniform1i( glGetUniformLocation( program->shader_program, "texture1" ), 0 ); glUniform3f( glGetUniformLocation( program->shader_program, "fogColor" ), 0.25f, 0.25f, 0.25f ); glUniform1f( glGetUniformLocation( program->shader_program, "fogStart" ), 1.0f ); glUniform1f( glGetUniformLocation( program->shader_program, "fogEnd" ), 200.0f ); glm::mat4 view = cam->GetViewMatrix(); glm::mat4 projection = glm::perspective( glm::radians( 45.0f ), 800.0f / 600.0f, 0.1f, 400.0f ); glm::mat4 model = glm::mat4( 1.0f ); model = glm::translate( model, transform.position ); model = glm::rotate( model, glm::radians( transform.rotation.x ), glm::vec3( 1.0f, 0.0f, 0.0f ) ); model = glm::rotate( model, glm::radians( transform.rotation.y ), glm::vec3( 0.0f, 1.0f, 0.0f ) ); model = glm::rotate( model, glm::radians( transform.rotation.z ), glm::vec3( 0.0f, 0.0f, 1.0f ) ); model = glm::scale( model, transform.scale ); glUniformMatrix4fv( glGetUniformLocation( program->shader_program, "projection" ), 1, GL_FALSE, & projection[ 0 ][ 0 ] ); glUniformMatrix4fv( glGetUniformLocation( program->shader_program, "view" ), 1, GL_FALSE, & view[ 0 ][ 0 ] ); glUniformMatrix4fv( glGetUniformLocation( program->shader_program, "model" ), 1, GL_FALSE, & model[ 0 ][ 0 ] ); glm::vec3 lightPos = glm::vec3( - 10, 10, 0 ); glm::vec3 lightColor = glm::vec3( 1.0f, 1.0f, 1.0f ); static float lightPower = 0.1f; static float lightRange = 10.0f; glUniform3f( glGetUniformLocation( program->shader_program, "LightPosition" ), lightPos.x, lightPos.y, lightPos.z ); glUniform3fv( glGetUniformLocation( program->shader_program, "LightColor" ), 1, & lightColor[ 0 ] ); glUniform1f( glGetUniformLocation( program->shader_program, "LightPower" ), lightPower ); glUniform1f( glGetUniformLocation( program->shader_program, "LightRange" ), lightRange ); glUniform3fv( glGetUniformLocation( program->shader_program, "Ka" ), 1, & meshes[ i ].material->Ka[ 0 ] ); glUniform3fv( glGetUniformLocation( program->shader_program, "Ks" ), 1, & meshes[ i ].material->Ks[ 0 ] ); auto[ offset, count ] = mesh_draw_ranges[ i ]; glDrawArrays( GL_TRIANGLES, offset, count ); offset += meshes[ i ].vertices.size(); } glBindVertexArray( 0 ); }
|