使用Assimp库读取mtl文件数据

最近在使用opengl做学校的大作业,在读取模型时遇到了无法显示材质的问题,在通过研究obj与mtl文件格式时发现了原因。

由于之前一直是使用别人做好的读取类,对于有贴图的模型可以正常处理,但是这次的模型没有贴图,材质都是用属性直接指定的,如

其中,Ka代表环境光,Kd代表漫反射光,Ks代表镜面高光。

为了读取这些数据,在已有的代码中进行了修改(代码在最下)。assimp中其实提供了方法读取这些数据,我们只要保存在mesh信息中,并传入着色器即可使用。

		aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
		Material mat;
		aiColor3D color;
		//读取mtl文件顶点数据
		material->Get(AI_MATKEY_COLOR_AMBIENT, color);
		mat.Ka = glm::vec4(color.r, color.g, color.b,1.0);

其中AI_MATKEY_COLOR_AMBIENT即对应了环境光的信息。

在将数据传入着色器时,使用了ubo对象,因为vbo中已经保存了模型的顶点和法线等信息,所以单独处理材质。

 

代码如下:

mesh.h

#pragma once
#ifndef MESH_H
#define MESH_H

#include <glad/glad.h> // holds all OpenGL type declarations

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include "shader_m.h"

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;

struct Vertex {
	// position
	glm::vec3 Position;
	// normal
	glm::vec3 Normal;
	// texCoords
	glm::vec2 TexCoords;
	// tangent
	glm::vec3 Tangent;
	// bitangent
	glm::vec3 Bitangent;
};

struct Material {
	//材质颜色光照
	glm::vec4 Ka;
	//漫反射
	glm::vec4 Kd;
	//镜反射
	glm::vec4 Ks;
};

struct Texture {
	unsigned int id;
	string type;
	string path;
};

class Mesh {
public:
	/*  Mesh Data  */
	vector<Vertex> vertices;
	vector<unsigned int> indices;
	vector<Texture> textures;
	Material mats;
	unsigned int VAO;
	unsigned int uniformBlockIndex;
	/*  Functions  */
	// constructor
	Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures, Material mat)
	{
		this->vertices = vertices;
		this->indices = indices;
		this->textures = textures;
		this->mats = mat;
		// now that we have all the required data, set the vertex buffers and its attribute pointers.
		setupMesh();
	}

	// render the mesh
	void Draw(Shader shader)
	{
		// bind appropriate textures
		unsigned int diffuseNr = 1;
		unsigned int specularNr = 1;
		unsigned int normalNr = 1;
		unsigned int heightNr = 1;
		for (unsigned int i = 0; i < textures.size(); i++)
		{
			glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
											  // retrieve texture number (the N in diffuse_textureN)
			string number;
			string name = textures[i].type;
			if (name == "texture_diffuse")
				number = std::to_string(diffuseNr++);
			else if (name == "texture_specular")
				number = std::to_string(specularNr++); // transfer unsigned int to stream
			else if (name == "texture_normal")
				number = std::to_string(normalNr++); // transfer unsigned int to stream
			else if (name == "texture_height")
				number = std::to_string(heightNr++); // transfer unsigned int to stream

													 // now set the sampler to the correct texture unit

			glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i);
			// and finally bind the texture
			glBindTexture(GL_TE
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值