Exemple #1
0
void SubMesh::DrawImmediate()
{
	if (!loaded)
		return;
	glBegin(GL_TRIANGLES);
	for (int i = 0; i < meshInfo.triCount; ++i)
	{
		Triangle t = GetTriangle(i);
		if (HasTextureCoords())
		{
			for (int j = 0; j < 3; ++j)
			{
				VertexPositionTexcoord* vpt = GetVertexData<VertexPositionTexcoord>(t.index[j]);
				glVertex3fv(vpt->position);
				glTexCoord2fv(vpt->texCoord);
			}
		}
		else
		{	
			for (int j = 0; j < 3; ++j)
			{
				VertexPositionNormalTexcoord* vpnt = GetVertexData<VertexPositionNormalTexcoord>(t.index[j]);
				glVertex3fv(vpnt->position);
				if (HasNormals())
					glNormal3fv(vpnt->normal);
				if (HasTextureCoords())
					glTexCoord2fv(vpnt->texCoord);
			}
		}
	}
	glEnd();
}
Exemple #2
0
void Mesh::loadMeshdata(const std::string& a_Filepath)
{
	Assimp::Importer importer;
	const auto scene = importer.ReadFile(a_Filepath, aiPostProcessSteps::aiProcess_CalcTangentSpace |
		aiPostProcessSteps::aiProcess_Triangulate |
		aiPostProcessSteps::aiProcess_JoinIdenticalVertices |
		aiPostProcessSteps::aiProcess_SortByPType);
	auto error = importer.GetErrorString();
	auto mesh = scene->mMeshes[0];

	m_Vertices.reserve(mesh->mNumVertices);
	for (auto i = 0u; i < mesh->mNumVertices; i++)
	{
		m_Vertices.emplace_back(toXMFloat3(mesh->mVertices[i]),
			mesh->HasVertexColors(i) ? toXMFloat4(mesh->mColors[0][i]) : XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f),
			mesh->HasTextureCoords(i) ? toXMFloat2(mesh->mTextureCoords[0][i]) : XMFLOAT2(0.0f, 0.0f));
	}
	m_Indices.reserve(mesh->mNumFaces * 3);
	for (auto i = 0u; i < mesh->mNumFaces; ++i)
	{
		aiFace currentFace = mesh->mFaces[i];
		for (auto j = 0u; j < currentFace.mNumIndices; ++j)
		{
			m_Indices.push_back(currentFace.mIndices[j]);
		}
	}
}
Exemple #3
0
void SubMesh::InitialiseVAO()
{

	glGenVertexArrays(1, &vaoID);

	glGenBuffers(1, &bufID);
	glGenBuffers(1, &indexBufID);
	
	glBindVertexArray(vaoID);
	glBindBuffer(GL_ARRAY_BUFFER, bufID);
	glBufferData(GL_ARRAY_BUFFER, meshInfo.vertexSize * meshInfo.vertexCount , meshData, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufID);
	switch (meshInfo.indexFormat)
	{
	case GL_UNSIGNED_INT:
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * meshInfo.triCount * 3, longIndexData, GL_STATIC_DRAW);
		break;
	case GL_UNSIGNED_SHORT:
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshInfo.triCount * 3 * sizeof(unsigned short), indexData, GL_STATIC_DRAW);
		break;
	case GL_UNSIGNED_BYTE:
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshInfo.triCount * 3 * sizeof(unsigned char), byteIndexData, GL_STATIC_DRAW);
		break;
	}
	glEnableVertexAttribArray(0);	
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, meshInfo.vertexSize, (void*)0);

	if (HasNormals())
	{
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, meshInfo.vertexSize, (void*)(3 * sizeof(float)));
		if (HasTextureCoords())
		{
			glEnableVertexAttribArray(2);
			glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, meshInfo.vertexSize, (char*)0 + 6 * sizeof(float));
		}
	}
	else if (HasTextureCoords())
	{
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, meshInfo.vertexSize, (char*)0 + 3 * sizeof(float));
	}	

	glBindVertexArray(0);
	loaded = true;
}
Exemple #4
0
// Assuming the metallic-roughness material model of models loaded with GLTF.
std::pair<ID, std::vector<std::pair<Texture::Type, std::string>>>
MeshManager::load_mesh(const std::string& directory, const std::string& file) {
    MeshInformation mesh_info;
    mesh_info.loaded_from_filepath = directory + file;

    Assimp::Importer importer;
    auto scene = importer.ReadFile(mesh_info.loaded_from_filepath.c_str(), aiProcess_Triangulate | aiProcess_JoinIdenticalVertices);

    if (scene == nullptr || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) {
        Log::error(std::string(importer.GetErrorString()));
        return {0, {}};
    }

    std::vector<std::pair<Texture::Type, std::string>> texture_info;
    if (scene->HasMaterials()) {
        Log::info("Number of materials: " + std::to_string(scene->mNumMaterials));
        for (size_t i = 0; i < scene->mNumMaterials; i++) {
            auto material = scene->mMaterials[i];

            aiString material_name;
            material->Get(AI_MATKEY_NAME, material_name);
            Log::info("Material name: " + std::string(material_name.C_Str()));
          
            aiString diffuse_filepath;
            if (material->GetTexture(aiTextureType_DIFFUSE, 0, &diffuse_filepath) == AI_SUCCESS) {
                Log::info("Diffuse texture name: " + std::string(directory.c_str()) + std::string(diffuse_filepath.data));
                std::string texture_filepath(diffuse_filepath.data);
                texture_filepath.insert(0, directory);
                texture_info.push_back({Texture::Type::Diffuse, texture_filepath});
            }
          
            aiString specular_filepath;
            if (material->GetTexture(aiTextureType_SPECULAR, 0, &specular_filepath) == AI_SUCCESS) {
              Log::info("Specular texture name: " + std::string(directory.c_str()) + std::string(specular_filepath.data));
            }

            aiString ambient_filepath;
            if (material->GetTexture(aiTextureType_AMBIENT, 0, &ambient_filepath) == AI_SUCCESS) {
              Log::info("Ambient occlusion texture name: " + std::string(directory.c_str()) + std::string(ambient_filepath.data));
            }
            
            aiString shininess_filepath;
            if (material->GetTexture(aiTextureType_SHININESS, 0, &shininess_filepath) == AI_SUCCESS) {
              Log::info("Shininess texture name: " + std::string(directory.c_str()) + std::string(shininess_filepath.data));
            }

            aiString emissive_filepath;
            if (material->GetTexture(aiTextureType_EMISSIVE, 0, &emissive_filepath) == AI_SUCCESS) {
              Log::info("Emissive texture name: " + std::string(directory.c_str()) + std::string(emissive_filepath.data));
              std::string texture_filepath(emissive_filepath.data);
              texture_filepath.insert(0, directory);
              texture_info.push_back({Texture::Type::Emissive, texture_filepath});
              // TODO: Fetch emissive factor as well 
            }

            aiString displacement_filepath;
            if (material->GetTexture(aiTextureType_DISPLACEMENT, 0, &displacement_filepath) == AI_SUCCESS) {
              Log::info("Displacement texture name: " + std::string(directory.c_str()) + std::string(displacement_filepath.data));
            }

            aiString height_filepath;
            if (material->GetTexture(aiTextureType_HEIGHT, 0, &height_filepath) == AI_SUCCESS) {
              Log::info("Bumpmap texture name: " + std::string(directory.c_str()) + std::string(height_filepath.data));
            }

            // Lightmap is usually the ambient occlusion map ...
            aiString lightmap_filepath;
            if (material->GetTexture(aiTextureType_LIGHTMAP, 0, &lightmap_filepath) == AI_SUCCESS) {
              Log::info("Lightmap texture name: " + std::string(directory.c_str()) + std::string(lightmap_filepath.data));
              std::string texture_filepath(lightmap_filepath.data);
              texture_filepath.insert(0, directory);
              texture_info.push_back({Texture::Type::AmbientOcclusion, texture_filepath});
            }
             
            aiString normals_filepath;
            if (material->GetTexture(aiTextureType_NORMALS, 0, &normals_filepath) == AI_SUCCESS) {
              Log::info("Normals texture name: " + std::string(directory.c_str()) + std::string(normals_filepath.data));
            }

            aiString reflection_filepath;
            if (material->GetTexture(aiTextureType_REFLECTION, 0, &reflection_filepath) == AI_SUCCESS) {
              Log::info("Reflection texture name: " + std::string(directory.c_str()) + std::string(reflection_filepath.data));
            }

            aiString opacity_filepath;
            if (material->GetTexture(aiTextureType_OPACITY, 0, &opacity_filepath) == AI_SUCCESS) {
              Log::info("Opacity texture name: " + std::string(directory.c_str()) + std::string(opacity_filepath.data));
            }
          
            // NOTE: Roughness metallic textures are not detected so here we are assuming this is the unknown texture of the material.
            aiString unknown_filepath;
            if (material->GetTexture(aiTextureType_UNKNOWN, 0, &unknown_filepath) == AI_SUCCESS) {
              Log::info("Unknown texture name: " + std::string(directory.c_str()) + std::string(unknown_filepath.data));
              std::string texture_filepath(normals_filepath.data);
              texture_filepath.insert(0, directory);
              texture_info.push_back({Texture::Type::MetallicRoughness, texture_filepath});
            }
        }
    }

    if (scene->HasMeshes()) {
        // FIXME: Assumes the mesh is a single mesh and not a hierarchy
        Log::info("Scene: # meshes " + std::to_string(scene->mNumMeshes));
        for (size_t i = 0; i < scene->mNumMeshes; i++) {
            auto mesh = scene->mMeshes[i];
            Log::info("Loading mesh with name: " + std::string(mesh->mName.data));

            for (size_t j = 0; j < mesh->mNumVertices; j++) {
                Vertex vertex;

                auto pos = mesh->mVertices[j];
                vertex.position = {pos.x, pos.y, pos.z};

                if (mesh->HasTextureCoords(0)) {
                    auto tex_coord = mesh->mTextureCoords[0][j];
                    vertex.tex_coord = {tex_coord.x, -tex_coord.y}; // glTF (& .obj) has a flipped texture coordinate system compared to OpenGL 
                }

                if (mesh->HasNormals()) {
                    auto normal = mesh->mNormals[j];
                    vertex.normal = {normal.x, normal.y, normal.z};
                }

                mesh_info.mesh.vertices.push_back(vertex);
            }

            for (size_t j = 0; j < mesh->mNumFaces; j++) {
                auto face = &mesh->mFaces[j];
                if (face->mNumIndices != 3) {
                    Log::warn("Not 3 vertices per face in model.");
                    return {0, {}};
                }
                for (size_t k = 0; k < 3; k++) {
                    auto index = face->mIndices[k];
                    mesh_info.mesh.indices.push_back(index);
                }
            }
        }
    }
    // FIXME: Mesh id is worthless since it does not change or anything ...
    loaded_meshes.push_back(mesh_info.mesh);
    return {loaded_meshes.size() - 1, texture_info};
}
Exemple #5
0
MeshPtr AssimpMeshIO::load(const std::string &mesh_name, const std::string &file_name, unsigned int mesh_index, const BufferManagerPtr &buffer_manager, const VaoManagerPtr &vao_manager)
{
	auto scene = importer->ReadFile(file_name, aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_ConvertToLeftHanded);

	if (scene == nullptr)
	{
		throw clan::Exception(clan::string_format("Unable to locate (%1) for (%2)", file_name, mesh_name));
	}

	if (scene->mNumMeshes <= mesh_index)
		throw clan::Exception(clan::string_format("The mesh index (%1) was out of bounds for mesh %2.", mesh_index, mesh_name));

	auto scene_mesh = scene->mMeshes[mesh_index];

	unsigned int stride = 0;
	std::vector<Core::VertexAttribute> interleaved_spec;
	Core::VaoLayout vao_layout;
	Core::RenderCommand render_command;

	// vectors to store bounds position and size in.
	glm::vec3 mesh_bounds_pos = glm::vec3(0);
	glm::vec3 mesh_bounds_size = glm::vec3(0);

	if (scene_mesh->HasPositions() && scene_mesh->mNumVertices > 0)
	{
		mesh_bounds_pos = glm::vec3(scene_mesh->mVertices[0].x, scene_mesh->mVertices[0].y, scene_mesh->mVertices[0].z);
		mesh_bounds_size = mesh_bounds_pos;
	}

	//
	// Set up vertices
	//

	// Set up the interleaved vertex attributes
	if (scene_mesh->HasPositions())
	{
		stride += sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Position));
	}

	if (scene_mesh->HasNormals())
	{
		stride += sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Normal));
	}

	if (scene_mesh->HasTextureCoords(0))
	{
		stride += sizeof(glm::vec2);
		interleaved_spec.push_back(Core::VaoArg<glm::vec2>(Core::ShaderConstants::TexCoord));
	}

	if (scene_mesh->HasTangentsAndBitangents())
	{
		stride += 2*sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Tangent));
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Bitangent));
	}

	std::vector<float> vertices;
	vertices.reserve(scene_mesh->mNumVertices * stride / sizeof(float)); // This is how many floats we have

	for (unsigned int i = 0; i < scene_mesh->mNumVertices; i++) {
		// This may be made into a lambda for BuffeOperations::unsafe_upload
		if (scene_mesh->HasPositions())
		{
			auto position = scene_mesh->mVertices[i];
			vertices.push_back(position.x);
			vertices.push_back(position.y);
			vertices.push_back(position.z);

			// check for new min-max component in vertex, and update bounds.
			check_if_new_min_or_max_vertex(glm::vec3(position.x, position.y, position.z),
			                               mesh_bounds_pos, mesh_bounds_size);
		}

		if (scene_mesh->HasNormals())
		{
			auto normal = scene_mesh->mNormals[i];
			vertices.push_back(normal.x);
			vertices.push_back(normal.y);
			vertices.push_back(normal.z);
		}

		if (scene_mesh->HasTextureCoords(0))
		{
			auto texcoord = scene_mesh->mTextureCoords[0][i];
			vertices.push_back(texcoord.x);
			vertices.push_back(texcoord.y);
		}

		if (scene_mesh->HasTangentsAndBitangents())
		{
			auto tangent = scene_mesh->mTangents[i];
			vertices.push_back(tangent.x);
			vertices.push_back(tangent.y);
			vertices.push_back(tangent.z);

			auto bitangent = scene_mesh->mBitangents[i];
			vertices.push_back(bitangent.x);
			vertices.push_back(bitangent.y);
			vertices.push_back(bitangent.z);
		}
	}

	auto vertex_allocation = buffer_manager->allocate(vertices.size()*stride, stride);
	vertex_allocation.upload(vertices);

	vao_layout
		.for_buffer(vertex_allocation)
			.use_as(GL_ARRAY_BUFFER)
				.bind_interleaved(0, 0, interleaved_spec);
	
	render_command.set_draw_mode(GL_TRIANGLES);
	render_command.set_vertices(vertex_allocation, scene_mesh->mNumVertices, stride);

	//
	// Set up indices
	//

	if (scene_mesh->HasFaces()) {
		std::vector<unsigned int> indices;

		for (unsigned int i = 0; i < scene_mesh->mNumFaces; i++) {
			auto face = scene_mesh->mFaces[i];
			for (unsigned int j = 0; j < face.mNumIndices; j++) {
				indices.push_back(face.mIndices[j]);
			}
		}

		auto index_allocation = buffer_manager->allocate_and_upload(indices);

		vao_layout
			.for_buffer(index_allocation)
				.use_as(GL_ELEMENT_ARRAY_BUFFER);

		render_command.set_indices(index_allocation, indices);
	}

	// Ensure that mesh_bounds_size is the distance from mesh_bounds_pos to upper-right-back-corner of the bounds
	mesh_bounds_size = glm::vec3(
	                             mesh_bounds_size.x - mesh_bounds_pos.x,
	                             mesh_bounds_size.y - mesh_bounds_pos.y,
	                             mesh_bounds_size.z - mesh_bounds_pos.z
	                            );

	return std::make_shared<Mesh>(render_command, vao_layout, vao_manager, mesh_name, mesh_bounds_pos, mesh_bounds_size);
}
Exemple #6
0
std::vector<Vertex> ModelLoader::load(int& numTriangles, int& numTextures)
{
	std::ifstream fileCheck(filename);
	Vertex tempVert;
	std::vector<Vertex> geometry;
	std::deque<aiVector3D> texCoord;
	numTriangles = 0;
	numTextures = 0;

	for(int i = 0; i < 3; i++)
		tempVert.color[i] = 1.0;

	if(!fileCheck) {
		std::cerr << "Error: Unable to open object file" << std::endl;
		exit(-1);
	}

	fileCheck.close();

	Assimp::Importer importer;

	auto scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_Fast);

	if(!scene) {
		std::cerr << "Error: " << importer.GetErrorString() << std::endl;
		exit(-1);
	}

	std::cout << "Material Count: " << scene->mNumMaterials << std::endl;
	
	if(scene->HasMaterials()) {
		const auto& material = scene->mMaterials[0];
		aiColor3D color(0.0f,0.0f,0.0);
		material->Get(AI_MATKEY_COLOR_DIFFUSE, color);
		tempVert.color[0] = color.r;
		tempVert.color[1] = color.g;
		tempVert.color[2] = color.b;
	}

	for(unsigned int i = 0; i < scene->mNumMeshes; i++) {
		auto mesh = scene->mMeshes[i];

		if(scene->mNumMaterials > i+1) {
			auto material = scene->mMaterials[i+1];

			aiColor3D color(1.0f,1.0f,1.0f);
			material->Get(AI_MATKEY_COLOR_DIFFUSE, color);
			tempVert.color[0] = color.r;
			tempVert.color[1] = color.g;
			tempVert.color[2] = color.b;

			if(material->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
				aiString path;

				if(material->GetTexture(aiTextureType_DIFFUSE, 0, &path, 
					NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
					
					std::cout << "Texture Path: " << path.C_Str() << std::endl;
					numTextures++;
					loadTexture(path.C_Str());
/*
					for(unsigned int j = 0; j < mesh->mNumVertices; j++) {
						const auto textureCoords = mesh->HasTextureCoords(0) ?
							 mesh->mTextureCoords[0][j] : aiVector3D(0.0f,0.0f,0.0f);

						//texCoord.emplace_back(textureCoords);
					}
					*/
				}

			}

		}

		numTriangles += mesh->mNumFaces;
		for(unsigned int j = 0; j < mesh->mNumFaces; j++) {
			const auto& face = mesh->mFaces[j];

			for(unsigned int k = 0; k < face.mNumIndices; k++) {
				const auto& vertex = mesh->mVertices[face.mIndices[k]];
				tempVert.position[0] = vertex.x;
				tempVert.position[1] = vertex.y;
				tempVert.position[2] = vertex.z;
				
				const auto& textureVertex = mesh->HasTextureCoords(0) ? mesh->mTextureCoords[0][face.mIndices[k]]
						: aiVector3D(0,0,0);
				tempVert.textCoord[0] = textureVertex[0];
				tempVert.textCoord[1] = textureVertex[1];
			
				geometry.push_back(tempVert);
			}
		}
	}

	//loadTexture("checkerboard.jpg");
	std::cout << "size: " << geometry.size() << std::endl
			  << "bytes: " << sizeof(tempVert) * geometry.size() << std::endl;
	return geometry;
}