void MyView::loadMeshes()
{

	generateLightMeshes();

	std::vector<SceneModel::Mesh> meshes = SceneModel::GeometryBuilder().getAllMeshes();
	std::vector<SceneModel::Instance> instances = scene_->getAllInstances();

	Mesh mesh;
	//for each mesh
	for (int i = 0; i < meshes.size(); i++)
	{
		std::vector<glm::vec3> positions = meshes[i].getPositionArray();
		std::vector<glm::vec3> normals = meshes[i].getNormalArray();
		std::vector<glm::vec2> texCoords = meshes[i].getTextureCoordinateArray();
		std::vector<unsigned int> elements = meshes[i].getElementArray();

		std::vector<vertex> vertexData;

		bool hasTexCoords = texCoords.size() > 0;

		for (int j = 0; j < positions.size(); j++)
		{
			vertex v;
			v.pos = positions[j];
			v.normal = normals[j];

			if (hasTexCoords)
			{
				v.texCoords = texCoords[j];
			}
			else
			{
				//mesh has no tex coords... fill with 0s for now, refactor later
				v.texCoords = glm::vec2(0, 0);
			}

			vertexData.push_back(v);
		}

		glGenBuffers(1, &mesh.vertex_data_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_data_vbo);
		glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(vertex), vertexData.data(), GL_STATIC_DRAW);

		glGenBuffers(1, &mesh.element_vbo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.element_vbo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(unsigned int), elements.data(), GL_STATIC_DRAW);
		mesh.element_count = elements.size();

		glGenVertexArrays(1, &mesh.vao);
		glBindVertexArray(mesh.vao);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.element_vbo);

		glEnableVertexAttribArray(POSITION);
		glVertexAttribPointer(POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), TGL_BUFFER_OFFSET_OF(vertex, pos));

		glEnableVertexAttribArray(NORMAL);
		glVertexAttribPointer(NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), TGL_BUFFER_OFFSET_OF(vertex, normal));

		glEnableVertexAttribArray(TEX_COORD);
		glVertexAttribPointer(TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), TGL_BUFFER_OFFSET_OF(vertex, texCoords));

		glBindBuffer(GL_ARRAY_BUFFER, 0);

		std::vector<InstanceData> instancesData;

		mesh.instanceIDs.clear();

		for (int x = 0; x < instances.size(); x++){
			if (instances[x].getMeshId() == meshes[i].getId()){

				InstanceData id;
				id.xForm = glm::mat4(instances[x].getTransformationMatrix());
				id.matColour = (float)(instances[x].getMaterialId() - 200) + 0.5f;
				instancesData.push_back(id);
				mesh.instanceIDs.push_back(instances[x].getId());
			}
		}

		int numInstances = instancesData.size();
		GLsizei vec4Size = sizeof(glm::vec4);

		//instanced data
		glGenBuffers(1, &mesh.instance_data_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, mesh.instance_data_vbo);
		glBufferData(GL_ARRAY_BUFFER, numInstances * sizeof(InstanceData), instancesData.data(), GL_STREAM_DRAW);

		glEnableVertexAttribArray(MATERIAL_COLOUR);
		glVertexAttribPointer(MATERIAL_COLOUR, 1, GL_FLOAT, GL_FALSE, sizeof(InstanceData), TGL_BUFFER_OFFSET_OF(InstanceData, matColour));
		glVertexAttribDivisor(MATERIAL_COLOUR, 1);

		//mat4 needs to be passed as 4 lots of vec4s
		for (int n = 0; n < 4; n++){
			glEnableVertexAttribArray(X_FORM + n);
			glVertexAttribPointer(X_FORM + n, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), TGL_BUFFER_OFFSET_OF(InstanceData, xForm) + (n * vec4Size));
			glVertexAttribDivisor(X_FORM + n, 1);
		}

		glBindVertexArray(0);

		meshes_.push_back(mesh);
	}

}
Beispiel #2
0
void MyView::
windowViewWillStart(std::shared_ptr<tygra::Window> window)
{
	assert(scene_ != nullptr);
	
	

	ResetConsole();
	
	/*
	Create and fill the vbos and vao in an interleaved manner from the scene data. Interleaving was chosen because
	the data would arrive to the gpu in a stream that would be in the order it would need for the shader and specific
	draw function to expect speeding up chache hits. The textures are also loaded on start so they can be assigned to 
	maps and used in rendering the specific mesh using its material data.
	*/

#pragma region
	SceneModel::GeometryBuilder builder;
	std::vector<Vertex> vertices;
	std::vector<unsigned int> elements;
	const auto& scene_meshes = builder.getAllMeshes();
	for (const auto& scene_mesh : scene_meshes) {

		MeshGL& newMesh = meshes_[scene_mesh.getId()];
		const auto& source_mesh = builder.getMeshById(scene_mesh.getId());
		const auto& positions = source_mesh.getPositionArray();
		const auto& elementsArr = source_mesh.getElementArray();
		const auto& normals = source_mesh.getNormalArray();
		const auto& tangents = source_mesh.getTangentArray();
		const auto& text_coord = source_mesh.getTextureCoordinateArray();

		newMesh.first_vertex_index = vertices.size();
		vertices.reserve(vertices.size() + positions.size());

		for (unsigned int i = 0; i < positions.size(); ++i)
		{
			Vertex vertex;
			vertex.position = positions[i];
			vertex.normal = normals[i];
			vertex.tangent = tangents[i];
			vertex.texcoord = text_coord[i];
			vertices.push_back(vertex);
		}

		newMesh.first_element_index = elements.size();
		elements.insert(elements.end(), elementsArr.begin(), elementsArr.end());
		newMesh.element_count = elementsArr.size();
	}

	glGenBuffers(1, &vertex_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo);
	glBufferData(GL_ARRAY_BUFFER,
		vertices.size() * sizeof(Vertex), // size of data in bytes
		vertices.data(), // pointer to the data
		GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glGenBuffers(1, &element_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, element_vbo);
	glBufferData(GL_ARRAY_BUFFER,
		elements.size() * sizeof(unsigned int), // size of data in bytes
		elements.data(), // pointer to the data
		GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), TGL_BUFFER_OFFSET_OF(Vertex, position));
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), TGL_BUFFER_OFFSET_OF(Vertex, normal));
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), TGL_BUFFER_OFFSET_OF(Vertex, tangent));
	glEnableVertexAttribArray(3);
	glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), TGL_BUFFER_OFFSET_OF(Vertex, texcoord));

	// make nothing active (deactivate vbo and vao)
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

#pragma endregion //Load the mesh into buffers

#pragma region

	//Load the textures into a map of handles
	LoadTexture("diff0.png");
	LoadTexture("diff1.png");
	LoadTexture("spec1.png");
	LoadTexture("spec2.png");
	
	//Create the light vector so there will be memory already reserved that can just be overwritten if values have been changed. This has been done on 
	//start for effiences in the constant render loop function.
	for (unsigned int i = 0; i < scene_->getAllLights().size(); ++i)
	{
		Light light;
		light.position = scene_->getAllLights()[i].getPosition();
		light.range = scene_->getAllLights()[i].getRange();
		light.intensity = scene_->getAllLights()[i].getIntensity();
		lights.push_back(light);
	}

#pragma endregion // Textures and Lights



}