void Technique::Load( const char *filename ) { char buffer[512]; PHYSFS_File *f = PHYSFS_openRead( fs::MakeCanonicalForm( buffer, filename ) ); if ( f ) { char line[512]; while ( PHYSFS_gets( line, sizeof(line), f ) ) { char str[256]; if ( sscanf( line, "pass %s", str ) == 1 ) { TechniquePass pass; if ( ParsePass( pass, f, str ) ) { passes.push_back( pass ); } } } PHYSFS_close(f); } else { TechniquePass pass; pass.pass = RP_Opaque; pass.shader = shaderManager()->Load( "_default" ); pass.blendSrc = hw::BLEND_ONE; pass.blendDst = hw::BLEND_ZERO; passes.push_back( pass ); } }
static bool ParsePass( TechniquePass &pass, PHYSFS_File *f, const char *passName ) { pass.pass = interpretPassName( passName ); char line[512]; while ( PHYSFS_gets( line, sizeof(line), f ) ) { char *tok = stripws( line ); if ( tok == NULL ) { continue; } char str[256]; if ( sscanf( tok, "blendSrc %s", str ) == 1 ) { pass.blendSrc = interpretBlend( str ); } else if ( sscanf( tok, "blendDst %s", str ) == 1 ) { pass.blendDst = interpretBlend( str ); } else if ( sscanf( tok, "shader %s", str ) == 1 ) { pass.shader = shaderManager()->Load( str ); } else { tok = strtok( tok, " \t\n\r" ); if ( tok && _stricmp( tok, "endpass" ) == 0 ) { return true; } } } return false; }
void CitySceneGenerator::generate(Scene* scene) { auto renderer = scene->renderer(); auto material = std::make_shared<PhongMaterial>(renderer); material->setShader(renderer->shaderManager()->getGlslProgram("phong")); PhongMaterialData materialData = { glm::vec4(0.0f, 0.1f, 0.0f, 1.0f), glm::vec4(0.8f, 0.3f, 0.1f, 1.0f), glm::vec4(0.3f, 0.3f, 0.3f, 1.0f), 5.0f }; material->properties()->setData(materialData); material->properties()->flushData(); auto mesh = std::make_shared<Mesh>(); mesh->setPrimitiveType(PrimitiveType::TriangleList); size_t buildingVerticesCount = sizeof(buildingVertices) / sizeof(*buildingVertices); std::vector<char> vertices(reinterpret_cast<const char*>(buildingVertices), reinterpret_cast<const char*>(buildingVertices) + sizeof(buildingVertices)); std::vector<VertexElement> layout = { VertexElement(3, VertexElementType::Float), VertexElement(3, VertexElementType::Float) }; mesh->loadVertices(vertices, buildingVerticesCount, layout); size_t buildingIndicesCount = sizeof(buildingIndices) / sizeof(*buildingIndices); std::vector<uint32_t> indices(reinterpret_cast<const unsigned*>(buildingIndices), reinterpret_cast<const unsigned*>(buildingIndices) + buildingIndicesCount); mesh->loadIndices(indices); size_t numBuildings = 1000; float citySize = 500.0f; float minBuildingSize = 10.0f; float maxBuildingSize = 60.0f; float minHeightToWidthRatio = 8.0f; float maxHeightToWidthRatio = 16.0f; std::uniform_real_distribution<float> angleDist(0.0f, 360.0f); std::uniform_real_distribution<float> positionDist(-citySize, citySize); std::uniform_real_distribution<float> canonicalDist; std::vector<std::shared_ptr<BaseSceneObject>> buildings; for (size_t i = 0; i < numBuildings; i++) { auto building = std::make_shared<Building>(mesh, material); // set random position glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(positionDist(m_rng), positionDist(m_rng), 0.0f) ); // rotate around z with random angle model = glm::rotate(model, angleDist(m_rng), glm::vec3(0.0f, 0.0f, 1.0f)); glm::vec3 scale; // multiplying uniform distribution will generate beta distribution scale.x = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * (maxBuildingSize - minBuildingSize) + minBuildingSize; scale.y = scale.x; scale.z = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * scale.x * (maxHeightToWidthRatio - minHeightToWidthRatio) + minHeightToWidthRatio; model = glm::scale(model, scale); building->setModelMatrix(model); building->calculateBBox(); buildings.push_back(building); } scene->setStaticGeometry(std::move(buildings)); }