//-----------------------------------------------------------------------
	MeshReadHelper::Face MeshReadHelper::getFace(size_t _subMeshIndex, size_t _faceIndex)
	{
		if(_subMeshIndex != mCurSubMeshInfoFi)
		{
			prepareFaces(_subMeshIndex);
		}

		Face face;
		size_t indexInID = _faceIndex * 3 + mCurSubMeshInfoF->indexStart;
		switch(mIndexType)
		{
			case HardwareIndexBuffer::IT_16BIT:
			{
				face.i[0] = ((uint16*) mIndexPtr)[indexInID + 0];
				face.i[1] = ((uint16*) mIndexPtr)[indexInID + 1];
				face.i[2] = ((uint16*) mIndexPtr)[indexInID + 2];
				break;
			}
			case HardwareIndexBuffer::IT_32BIT:
			{
				face.i[0] = ((uint32*) mIndexPtr)[indexInID + 0];
				face.i[1] = ((uint32*) mIndexPtr)[indexInID + 1];
				face.i[2] = ((uint32*) mIndexPtr)[indexInID + 2];
				break;
			}
		}

		size_t ofs = mCurSubMeshInfoF->vertexStartInJoinedList - mCurSubMeshInfoF->vertexStart;
		face.i[0] += ofs;
		face.i[1] += ofs;
		face.i[2] += ofs;
		return face;
	}
	//-----------------------------------------------------------------------
	const String& MeshReadHelper::getMaterialName(size_t _subMeshIndex)
	{
		if(_subMeshIndex != mCurSubMeshInfoFi)
		{
			prepareFaces(_subMeshIndex);
		}
		return mCurSubMeshInfoF->subMesh->getMaterialName();
	}
	//-----------------------------------------------------------------------
	size_t MeshReadHelper::getNumFaces(size_t _subMeshIndex)
	{
		if(_subMeshIndex != mCurSubMeshInfoFi)
		{
			prepareFaces(_subMeshIndex);
		}
		return mCurSubMeshInfoF->indexCount / 3;
	}
Пример #4
0
        //-------------------------------------------------------------------------------------------------------
        bool Exporter::processMesh(RawMesh& rawMesh, const char* fileName)
        {
                rawMesh_ = &rawMesh;
                meshData_.reset(new(std::nothrow) Mesh::Data);
                if(!meshData_)
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                numVertices_ = rawMesh_->positions_.getSize();
                meshData_->boundingBox = rawMesh_->boundingBox_;

                boneIndices_.destroy();
                boneWeights_.destroy();

                vertices_.clear();
                newToOldVertexMapping_.clear();

                std::cout << "processing raw mesh..." << std::endl;
                faces_ = rawMesh_->faces_;
                if(faces_.getSize() != rawMesh_->faces_.getSize())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "merging faces..." << std::endl;

                numVertices_ = mergeFaces(faces_, rawMesh_->normalFaces_, faces_, numVertices_);
                if(numVertices_ == 0)
                {
                        std::cout << "error: could not merge faces" << std::endl;
                        return false;
                }

                numVertices_ = mergeFaces(faces_, rawMesh_->textureFaces_, faces_, numVertices_);
                if(numVertices_ == 0)
                {
                        std::cout << "error: could not merge faces" << std::endl;
                        return false;
                }

                if(!rawMesh_->bones_.isEmpty())
                {
                        std::cout << "reading bone indices and weights..." << std::endl;

                        if(!boneIndices_.create(numVertices_) || !boneWeights_.create(numVertices_))
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }

                        uint32_t numFaces = faces_.getSize();
                        for(uint32_t i = 0; i < numFaces; ++i)
                        {
                                const RawMesh::Face& face = rawMesh_->faces_[i];

                                for(uint8_t j = 0; j < 3; ++j)
                                {
                                        uint32_t vertexIndex = faces_[i].indices[j];
                                        boneIndices_[vertexIndex] = rawMesh_->boneIndices_[face.indices[j]];
                                        boneWeights_[vertexIndex] = rawMesh_->boneWeights_[face.indices[j]];
                                }
                        }
                }

                std::cout << "computing tangent space..." << std::endl;
                if(!computeTangentSpace())
                {
                        std::cout << "error: broken mesh" << std::endl;
                        return false;
                }

                std::cout << "preparing vertex streams..." << std::endl;
                if(!prepareVertexStreams())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "preparing faces..." << std::endl;
                if(!prepareFaces())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "preparing subsets..." << std::endl;
                if(!prepareSubsets())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                if(!rawMesh_->bones_.isEmpty())
                {
                        std::cout << "preparing skeleton...";
                        auto& skeleton = meshData_->skeleton;

                        skeleton.reset(new(std::nothrow) Skeleton);
                        if(!skeleton)
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }

                        skeleton->getBones() = rawMesh_->bones_;
                        if(skeleton->getBones().getSize() != rawMesh_->bones_.getSize())
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }
                }

                std::cout << "writing mesh to the file..." << std::endl;

                std::ofstream stream(fileName, std::ios_base::binary);
                MeshManager meshManager;

                if(!meshManager.writeMesh(stream, *meshData_))
                {
                        std::cout << "error: could not write mesh to the file" << std::endl;
                        return false;
                }

                std::cout << "mesh has " << numVertices_;
                std::cout << " vertices and " << faces_.getSize() << " faces" << std::endl;

                return true;
        }
Пример #5
0
void Game::run() {
	// build and compile our shader program
	Shader ourShader("basic.vert", "basic.frag");

	// load the map
	auto result = bsp.parse(mapName.c_str());
	
	prepareFaces();

	/////////////////////////////////////
	glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	glEnable(GL_DEBUG_OUTPUT);
	glDebugMessageCallback(openglCallbackFunction, nullptr);

	GLuint VBO, VAO, EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);

	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	glBindVertexArray(VAO);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*indexes.size(), &indexes[0], GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, bsp.getVertexes().size() * sizeof(BSP_vertex), &bsp.getVertexes()[0], GL_STATIC_DRAW);

	// Position attribute
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)0);
	glEnableVertexAttribArray(0);

	// Color attribute
	glVertexAttribPointer(1, 4, GL_BYTE, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)((10 * sizeof(GL_FLOAT))));
	glEnableVertexAttribArray(1);

	// Texel attribute
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)((3 * sizeof(GL_FLOAT))));
	glEnableVertexAttribArray(2);

	// Texture array depth/id attribute
	glVertexAttribIPointer(3, 1, GL_INT, sizeof(BSP_vertex), (GLvoid*)((4 * sizeof(GLbyte)) + (10 * sizeof(GL_FLOAT))));
	glEnableVertexAttribArray(3);

	// Lightmap array depth/id attribute
	glVertexAttribIPointer(4, 1, GL_INT, sizeof(BSP_vertex), (GLvoid*)((1 * sizeof(GLint)) + (4 * sizeof(GLbyte)) + (10 * sizeof(GL_FLOAT))));
	glEnableVertexAttribArray(4);

	// Lightmap uv
	glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)(5 * sizeof(GL_FLOAT)));
	glEnableVertexAttribArray(5);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	glBindVertexArray(0); // Unbind VAO

	glm::mat4 projection = camera.getProjection();
	camera.setPosition(glm::vec3(0.0, 0.0, 40.0));

	ourShader.Use();
	auto texLocation = glGetUniformLocation(ourShader.Program, "_texture");
	auto lmLocation = glGetUniformLocation(ourShader.Program, "_lightmap");

	glUniform1i(texLocation, 0);
	glUniform1i(lmLocation, 1);

	assert(texLocation != -1, "texLocation uniform was optimized");
	assert(lmLocation != -1, "lmLocation uniform was optimized");

	while (!glfwWindowShouldClose(window))
	{
		deltaTime = glfwGetTime() - lastFrameTime;
		lastFrameTime = glfwGetTime();

		// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
		glfwPollEvents();
		processInputs();

		// Render
		// Clear the colorbuffer
		glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glActiveTexture(GL_TEXTURE0 + 0);
		glBindTexture(GL_TEXTURE_2D_ARRAY, bsp.getTextureHandle());

		glActiveTexture(GL_TEXTURE0 + 1);
		glBindTexture(GL_TEXTURE_2D_ARRAY, bsp.getLightmapHandle());

		GLint modelLoc = glGetUniformLocation(ourShader.Program, "model");
		GLint viewLoc = glGetUniformLocation(ourShader.Program, "view");
		GLint projLoc = glGetUniformLocation(ourShader.Program, "projection");
		GLint angleLoc = glGetUniformLocation(ourShader.Program, "angle");

		glm::mat4 view;
		camera.setDeltaTime(deltaTime);
		view = camera.getView();

		// Get their uniform location
		glUniform1f(angleLoc, glfwGetTime());
		glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
		glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

		glm::mat4 model = glm::mat4(1.0);	// just identity

		glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

		glBindVertexArray(VAO);

		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

		glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_INT, 0);

		glBindVertexArray(0);

		glfwSwapBuffers(window);
	}

	// Properly de-allocate all resources once they've outlived their purpose
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);

	glfwTerminate();
}