Beispiel #1
0
void FMesh::Init(const FMeshData& MeshData, const FImageCache& ImageCache)
{
	// #FIXME: This function could be more maintainable than it currently is.
	// Specifically: VertexAttribPointer and EnableVertexAttribArray.
	F_Assert(MeshData.Positions.size(), "Position data is missing.");
	F_Assert(MeshData.Normals.size(), "Normal data is missing.");
	F_Assert(MeshData.UVCoords.size(), "UVCoords data is missing.");
	F_Assert(MeshData.Indices.size(), "Index data is missing.");

	F_GLDisplayErrors();

	DeInit();

	F_GL(GL::GenVertexArrays(1, &VertexArray));
	F_GL(GL::GenBuffers(1, &VertexBuffer));
	F_GL(GL::GenBuffers(1, &ElementBuffer));

	F_GL(GL::BindVertexArray(VertexArray));

	{
		const GLsizeiptr PositionsSize = MeshData.Positions.size() * sizeof(FMeshData::PositionT);
		const GLsizeiptr NormalsSize = MeshData.Normals.size() * sizeof(FMeshData::NormalT);
		const GLsizeiptr UVCoordsSize = MeshData.UVCoords.size() * sizeof(FMeshData::UVCoordT);

		const GLsizeiptr TotalSize = PositionsSize + NormalsSize + UVCoordsSize;

		const GLsizeiptr NormalsStart = PositionsSize;
		const GLsizeiptr UVCoordsStart = NormalsStart + NormalsSize;

		const GLvoid* const NormalsStartPtr = reinterpret_cast<GLvoid*>(NormalsStart);
		const GLvoid* const UVCoordsStartPtr = reinterpret_cast<GLvoid*>(UVCoordsStart);

		F_GL(GL::BindBuffer(GL::EBuffer::Array, VertexArray));
		F_GL(GL::BufferData(GL::EBuffer::Array, TotalSize, nullptr, GL::EUsage::StaticDraw));

		F_GL(GL::BufferSubData(GL::EBuffer::Array, 0, PositionsSize, &MeshData.Positions[0]));
		F_GL(GL::BufferSubData(GL::EBuffer::Array, NormalsStart, NormalsSize, &MeshData.Normals[0]));
		F_GL(GL::BufferSubData(GL::EBuffer::Array, UVCoordsStart, UVCoordsSize, &MeshData.UVCoords[0]));

		F_GL(GL::EnableVertexAttribArray(0));
		F_GL(GL::EnableVertexAttribArray(1));
		F_GL(GL::EnableVertexAttribArray(2));

		F_GL(GL::VertexAttribPointer(0, 3, GL::EType::Float, GL::EBool::False, 3 * sizeof(GLfloat), nullptr));
		F_GL(GL::VertexAttribPointer(1, 3, GL::EType::Float, GL::EBool::False, 3 * sizeof(GLfloat), NormalsStartPtr));
		F_GL(GL::VertexAttribPointer(2, 2, GL::EType::Float, GL::EBool::False, 2 * sizeof(GLfloat), UVCoordsStartPtr));
	}

	{
		const GLsizeiptr Size = MeshData.Indices.size() * sizeof(FMeshData::IndexT);

		F_GL(GL::BindBuffer(GL::EBuffer::ElementArray, ElementBuffer));
		F_GL(GL::BufferData(GL::EBuffer::ElementArray, Size, &MeshData.Indices[0], GL::EUsage::StaticDraw));

		IndexCount = Size / MeshData.IndexTSize;
		IndexTSize = MeshData.IndexTSize;
		VertexCount = MeshData.VertexCount;

		F_GL(GL::BindVertexArray(0));
	}

	{
		if (MeshData.HasTextureName(EMeshDataIndex::Diffuse))
		{
			const FChar* const DiffuseName = MeshData.GetTextureName(EMeshDataIndex::Diffuse);
			DiffuseImage = ImageCache.GetItem(DiffuseName, DiffuseImage);
		}
	}
}
Beispiel #2
0
void FMesh::Init(const FMeshData& MeshData, const FImageCache& ImageCache)
{
	F_Assert(MeshData.Positions.size(), "Position data is missing.");

	const bool bNormalsProvided = !MeshData.Normals.empty();
	const bool bUVCoordsProvided = !MeshData.UVCoords.empty();
	const bool bIndicesProvided = !MeshData.Indices.empty();
	
	DeInit();

	F_GL(GL::GenVertexArrays(1, &VertexArray));
	F_GL(GL::GenBuffers(1, &VertexBuffer));

	F_GL(GL::BindVertexArray(VertexArray));

	{
		const GLsizeiptr PositionsSize = MeshData.Positions.size() * sizeof(FMeshData::PositionT);
		const GLsizeiptr NormalsSize = MeshData.Normals.size() * sizeof(FMeshData::NormalT);
		const GLsizeiptr UVCoordsSize = MeshData.UVCoords.size() * sizeof(FMeshData::UVCoordT);

		const GLsizeiptr TotalSize = PositionsSize + NormalsSize + UVCoordsSize;

		const GLsizeiptr NormalsStart = PositionsSize;
		const GLsizeiptr UVCoordsStart = NormalsStart + NormalsSize;

		const GLvoid* const NormalsStartPtr = reinterpret_cast<GLvoid*>(NormalsStart);
		const GLvoid* const UVCoordsStartPtr = reinterpret_cast<GLvoid*>(UVCoordsStart);

		F_GL(GL::BindBuffer(EBuffer::Array, VertexArray));
		F_GL(GL::BufferData(EBuffer::Array, TotalSize, nullptr, EUsage::StaticDraw));

		GLuint CurrentIndex = 0;

		const EMeshPositionType::SizeType Size = EMeshPositionType::GetSize(MeshData.PositionType);

		F_GL(GL::BufferSubData(EBuffer::Array, 0, PositionsSize, &MeshData.Positions[0]));
		F_GL(GL::EnableVertexAttribArray(CurrentIndex));
		F_GL(GL::VertexAttribPointer(CurrentIndex, Size, EType::Float, EBool::False, Size * sizeof(GLfloat), nullptr));
		
		if (bNormalsProvided)
		{
			++CurrentIndex;
			F_GL(GL::BufferSubData(EBuffer::Array, NormalsStart, NormalsSize, &MeshData.Normals[0]));
			F_GL(GL::EnableVertexAttribArray(CurrentIndex));
			F_GL(GL::VertexAttribPointer(CurrentIndex, 3, EType::Float, EBool::False, 3 * sizeof(GLfloat), NormalsStartPtr));
		}

		if (bUVCoordsProvided)
		{
			++CurrentIndex;
			F_GL(GL::BufferSubData(EBuffer::Array, UVCoordsStart, UVCoordsSize, &MeshData.UVCoords[0]));
			F_GL(GL::EnableVertexAttribArray(CurrentIndex));
			F_GL(GL::VertexAttribPointer(CurrentIndex, 2, EType::Float, EBool::False, 2 * sizeof(GLfloat), UVCoordsStartPtr));
		}
	}

	if (bIndicesProvided)
	{
		const GLsizeiptr Size = MeshData.Indices.size() * sizeof(FMeshData::IndexT);

		F_GL(GL::GenBuffers(1, &ElementBuffer));
		F_GL(GL::BindBuffer(EBuffer::ElementArray, ElementBuffer));
		F_GL(GL::BufferData(EBuffer::ElementArray, Size, &MeshData.Indices[0], EUsage::StaticDraw));

		IndexCount = Size / MeshData.IndexTSize;
		IndexTSize = MeshData.IndexTSize;
	}

	VertexCount = MeshData.VertexCount;

	F_GL(GL::BindVertexArray(0));

	if (MeshData.HasTextureName(EMeshDataIndex::Diffuse))
	{
		const FChar* const DiffuseName = MeshData.GetTextureName(EMeshDataIndex::Diffuse);
		DiffuseImage = ImageCache.GetItem(DiffuseName, DiffuseImage);
	}
	
	F_GFXLog("Mesh VAO Created: " << VertexArray << " " << VertexBuffer << " " << ElementBuffer);
}