void LodInputProviderBuffer::initialize( LodData* data )
    {
#if OGRE_DEBUG_MODE
        data->mMeshName = mBuffer.meshName;
#endif
        data->mMeshBoundingSphereRadius = mBuffer.boundingSphereRadius;
        unsigned short submeshCount = ushort(mBuffer.submesh.size());
        for (unsigned short i = 0; i < submeshCount; ++i) {
            LodInputBuffer::Submesh& submesh = mBuffer.submesh[i];
            LodVertexBuffer& vertexBuffer =
                (submesh.useSharedVertexBuffer ? mBuffer.sharedVertexBuffer : submesh.vertexBuffer);
            addVertexData(data, vertexBuffer, submesh.useSharedVertexBuffer);
            addIndexData(data, submesh.indexBuffer, submesh.useSharedVertexBuffer, i);
        }

        // These were only needed for addIndexData() and addVertexData().
        mSharedVertexLookup.clear();
        mVertexLookup.clear();
    }
	void LodInputProviderMesh::initialize( LodData* data )
	{
#if OGRE_DEBUG_MODE
		data->mMeshName = mMesh->getName();
#endif
		data->mMeshBoundingSphereRadius = mMesh->getBoundingSphereRadius();
		unsigned short submeshCount = mMesh->getNumSubMeshes();
		for (unsigned short i = 0; i < submeshCount; ++i) {
			const SubMesh* submesh = mMesh->getSubMesh(i);
			VertexData* vertexData = (submesh->useSharedVertices ? mMesh->sharedVertexData : submesh->vertexData);
			addVertexData(data, vertexData, submesh->useSharedVertices);
			if(submesh->indexData->indexCount > 0)
				addIndexData(data, submesh->indexData, submesh->useSharedVertices, i);
		}

		// These were only needed for addIndexData() and addVertexData().
		mSharedVertexLookup.clear();
		mVertexLookup.clear();
	}
示例#3
0
/*
	Loads a heightmap from a grey scaled image which must have square dimensions.

	@param the path to the file
	@return whether the file was correctly loaded or not
*/
bool Ground::loadHeightMap(string path) {

	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	FIBITMAP* dib(0);

	fif = FreeImage_GetFileType(path.c_str(), 0);
	if (fif == FIF_UNKNOWN) {
		fif = FreeImage_GetFIFFromFilename(path.c_str());
	}

	if (fif == FIF_UNKNOWN) {
		std::cout << "Unknown Filetype\n";
		return false;
	}

	if (FreeImage_FIFSupportsReading(fif)) {
		dib = FreeImage_Load(fif, path.c_str());
	}

	if (!dib) {
		std::cout << "Unable to load height map\n";
		return false;
	}

	BYTE* dataPointer = FreeImage_GetBits(dib);
	hmRows = FreeImage_GetHeight(dib);
	hmCols = FreeImage_GetWidth(dib);

	// How much to increase data pointer to get to next pixel data
	unsigned int ptr_inc = FreeImage_GetBPP(dib) == 24 ? 3 : 1;

	// Length of one row in data
	unsigned int row_step = ptr_inc * hmCols;

	glGenBuffers(1, &hmdataVertexBufferID);

	vector<vector<glm::vec2>> UVcoordinates(hmRows, vector<glm::vec2>(hmCols)); 
	vector<vector<glm::vec3>> vertices(hmRows, vector<glm::vec3>(hmCols));

	float textureU = float(hmCols * 0.1);
	float textureV = float(hmRows * 0.1);

	// Calculate vertex and texture data from the value of the color in the height map
	for (int i = 0; i < hmRows; i++) {
		for (int j = 0; j < hmCols; j++) {
			float x = float(j) / float(hmCols - 1);
			float z = float(i) / float(hmRows - 1);
			float y = float(*(dataPointer + row_step * i + j * ptr_inc)) / 255.f;
			vertices[i][j] = glm::vec3(-.5 + x, y, -.5 + z);
			UVcoordinates[i][j] = glm::vec2(textureU * x, textureV * z);
			scaledHeight.insert(std::pair<std::pair<float, float>, float>(std::pair<float, float>(x, z), y));
		}
	}
	
	// Calculate the normals by getting the normals of both triangles in a quad and storing them in a 3 dimensional vector
	vector<vector<glm::vec3>> triangleNormals[2]; // Every quad has 2 triangles
	for (int i = 0; i < 2; i++) {
		triangleNormals[i] = vector<vector<glm::vec3>>(hmRows - 1, vector<glm::vec3>(hmCols - 1));
	}

	// iterate through every quad and calculate the normals
	for (int i = 0; i < hmRows - 1; i++){
		for (int j = 0; j < hmCols - 1; j++) {
			glm::vec3 triangle0[] = {vertices[i][j], vertices[i+1][j], vertices[i+1][j+1]};
			glm::vec3 triangle1[] = {vertices[i+1][j+1], vertices[i][j+1], vertices[i][j]};
			glm::vec3 triangle0Norm = glm::cross(triangle0[0] - triangle0[1], triangle0[1] - triangle0[2]);
			glm::vec3 triangle1Norm = glm::cross(triangle1[0] - triangle1[1], triangle1[1] - triangle1[2]);
			triangleNormals[0][i][j] = glm::normalize(triangle0Norm);
			triangleNormals[1][i][j] = glm::normalize(triangle1Norm);
		}
	}

	// Calculate the normal of every vertex by taking the average of each adjacent triangle's normal
	vector<vector<glm::vec3>> vertexNormals = vector<vector<glm::vec3>>(hmRows, vector<glm::vec3>(hmCols));

	for (int i = 0; i < hmRows; i++) {
		for (int j = 0; j < hmCols; j++) {

			glm::vec3 norm(0,0,0);
			
			if (i != 0 && j != 0) {
				for(int	k = 0; k < 2; k++) {
					norm += triangleNormals[k][i-1][j-1];
				}
			}
			if (i != (hmRows - 1) && j != (hmCols - 1)) {
				for (int k = 0; k < 2; k++) {
					norm += triangleNormals[k][i][j];
				}
			}
			if (i != 0 && j != (hmCols - 1)) {
				norm += triangleNormals[0][i-1][j];
			}
			if (i != (hmRows - 1) && j != 0 ) {
				norm += triangleNormals[1][i][j-1];
			}

			norm = glm::normalize(norm);

			vertexNormals[i][j] = norm;
		}
	}

	// Create the buffer for the indexed drawing
	glGenBuffers(1, &hmdataVertexBufferID);
	data.reserve(hmRows * hmCols * (2 * sizeof(glm::vec3) + sizeof(glm::vec2)));
	dataSize = hmRows * hmCols * (2 * sizeof(glm::vec3) + sizeof(glm::vec2));
	currentDataSize = 0;

	glGenBuffers(1, &hmdataVertexBufferID);

	for (int i = 0; i < hmRows; i++) {
		for (int j = 0; j < hmCols; j++) {
			addData(&vertices[i][j], sizeof(glm::vec3));
			addData(&UVcoordinates[i][j], sizeof(glm::vec2));
			addData(&vertexNormals[i][j], sizeof(glm::vec3));
		}
	}

	glGenBuffers(1, &indexVertexBufferID);
	indexSize = 0;
	currentIndexSize = 0;

	int restartIndex = hmRows * hmCols;
	
	for (int i = 0; i < hmRows - 1; i++) {
		for (int j = 0; j < hmCols; j++) {
			for (int k = 0; k < 2; k++) {
				int row = i + (1 - k);
				int index = row * hmCols + j;
				addIndexData(&index, sizeof(int));
			}
		}
		addIndexData(&restartIndex, sizeof(int));
	}
	
	glGenVertexArrays(1, &vertexArrayID);
	glBindVertexArray(vertexArrayID);

	glBindBuffer(GL_ARRAY_BUFFER, hmdataVertexBufferID);
	glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
	


	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3)+sizeof(glm::vec2), 0);
	// Texture coordinates
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3)+sizeof(glm::vec2), (void*)sizeof(glm::vec3));
	// Normal vectors
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3)+sizeof(glm::vec2), (void*)(sizeof(glm::vec3)+sizeof(glm::vec2)));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVertexBufferID);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, iData.size(), &iData[0], GL_STATIC_DRAW);

	return true;
}
示例#4
0
	//---------------------------------------------------------------------
	void OptimiseTool::processMesh(Ogre::MeshPtr mesh)
	{
		bool rebuildEdgeList = false;
		// Shared geometry
		if (mesh->sharedVertexData)
		{
			print("Optimising mesh shared vertex data...");
			setTargetVertexData(mesh->sharedVertexData);

			for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
			{
				SubMesh* sm = mesh->getSubMesh(i);
				if (sm->useSharedVertices)
				{
					addIndexData(sm->indexData);
				}
			}

			if (optimiseGeometry())
			{
				if (mesh->getSkeletonName() != StringUtil::BLANK)
				{
					print("    fixing bone assignments...");
					Mesh::BoneAssignmentIterator currentIt = mesh->getBoneAssignmentIterator();
					Mesh::VertexBoneAssignmentList newList =
						getAdjustedBoneAssignments(currentIt);
					mesh->clearBoneAssignments();
					for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
						bi != newList.end(); ++bi)
					{
						mesh->addBoneAssignment(bi->second);
					}

				}

				for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
				{
					SubMesh* sm = mesh->getSubMesh(i);
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}
					if (sm->useSharedVertices)
					{
						fixLOD(sm->mLodFaceList);
					}
				}
				rebuildEdgeList = true;

			}
		}

		// Dedicated geometry
		for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
		{
			SubMesh* sm = mesh->getSubMesh(i);
			if (!sm->useSharedVertices)
			{
				print("Optimising submesh " +
					StringConverter::toString(i) + " dedicated vertex data ");
				setTargetVertexData(sm->vertexData);
				addIndexData(sm->indexData);
				if (optimiseGeometry())
				{
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}

					fixLOD(sm->mLodFaceList);
					rebuildEdgeList = true;
				}
			}
		}

		if (rebuildEdgeList && mesh->isEdgeListBuilt())
		{
			// force rebuild of edge list
			mesh->freeEdgeList();
			mesh->buildEdgeList();
		}


	}