栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

[C++] [OpenGL] 加载obj文件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[C++] [OpenGL] 加载obj文件

前言

额,以前确实写过Java的加载obj文件,但那是Java,所以用C++再写一次
加载obj:1.0,2.0
嗯,各位,你们现在看到的这篇文章已经被我修改过了(增加了ObjModelLoader类的一些新特性),已经是2.0了

片段着色器代码
#version 330 core

in vec3 v_position;
in vec3 v_color;
in vec3 v_normal;
in vec3 v_normal2;
in vec2 v_texCoord;

out vec4 o_color;

uniform bool u_enableLighting;
uniform bool u_enableDoubleLighting;
uniform bool u_enableTexture;
uniform sampler2D s_sampler;
uniform vec4 u_color;
uniform bool u_enableUniformColor;

uniform vec3 u_cameraposition;

void main()
{
	vec3 light_direction = normalize(v_position - u_cameraposition);
	vec3 view_direction = normalize(v_position - u_cameraposition);

	float ambient = 0.1;
	float diffuse = 1.0;
	float specular = 0.0;
	float diffuse2 = 0.0;
	float specular2 = 0.0;
	if (u_enableLighting)
	{
		diffuse = max(dot(v_normal, -light_direction), 0.0);

		vec3 reflect_direction = reflect(light_direction, v_normal);
		specular = pow(max(dot(-view_direction, reflect_direction), 0.0), 32.0);

		if (u_enableDoubleLighting)
		{
			diffuse2 = max(dot(v_normal, -light_direction), 0.0);

			vec3 reflect_direction2 = reflect(light_direction, v_normal2);
			specular2 = pow(max(dot(-view_direction, reflect_direction2), 0.0), 32.0);
		}
	}

	vec4 color;
	if (u_enableTexture)
	{
		color = texture(s_sampler, v_texCoord);
	}
	else if (u_enableUniformColor)
	{
		color = u_color;
	}
	else
	{
		color = vec4(v_color, 1.0);
	}

	o_color = (ambient + diffuse + specular + diffuse2 + specular2) * color;
}
模型加载类代码
#ifndef __SIMPLEGL_MODEL_HPP__
#define __SIMPLEGL_MODEL_HPP__
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace SimpleGL
{
	class Model
	{
		public:
			std::vector vertices;
			std::vector normals;
			std::vector texCoords;

		public:
			Model(std::vector ver = std::vector(), std::vector nor = std::vector(), std::vector tex = std::vector()) : vertices(ver), normals(nor), texCoords(tex) {}
	};

	class ObjModelLoader
	{
		public:
			std::vector> results;
			bool success;
			std::stringstream error_log;

		public:
			ObjModelLoader() : success(false) {}
			ObjModelLoader(std::string filename)
			{
				loadFromFile(filename);
			}

		public:
			bool loadFromStream(std::istream& is)
			{
				bool result = true;
				std::string groupname = "";

				std::vector vertices0;
				std::vector normals0;
				std::vector texCoords0;

				std::vector vertices1;
				std::vector normals1;
				std::vector texCoords1;

				try
				{
					std::string temp;
					while (getline(is, temp))
					{
						std::vector items = split(temp, "[ ]");
						int length = items.size();
						if (items.at(0).compare("v") == 0)
						{
							float x = std::stof(items.at(1));
							float y = std::stof(items.at(2));
							float z = std::stof(items.at(3));
							vertices0.push_back(glm::vec3(x, y, z));
						}
						else if (items.at(0).compare("vn") == 0)
						{
							float x = std::stof(items.at(1));
							float y = std::stof(items.at(2));
							float z = std::stof(items.at(3));
							normals0.push_back(glm::vec3(x, y, z));
						}
						else if (items.at(0).compare("vt") == 0)
						{
							float x = std::stof(items.at(1));
							float y = std::stof(items.at(2));
							float z = 0.0f;
							if (length > 3)
								z = std::stof(items.at(3));
							texCoords0.push_back(glm::vec3(x, y, z));
						}
						else if (items.at(0).compare("f") == 0)
						{
							std::vector> indices;
							for (int i = 1; i < length; i++)
							{
								std::vector values0 = split(items.at(i), "[/]");
								std::vector values1;
								for (int j = 0; j < values0.size(); j++)
								{
									values1.push_back(std::stoi(values0.at(j)) - 1);
								}
								indices.push_back(values1);
							}

							if (vertices0.size() != 0)
							{
								for (int i = 2; i < indices.size(); i++)
								{
									vertices1.push_back(vertices0.at(indices.at(0).at(0)));
									vertices1.push_back(vertices0.at(indices.at(i - 1).at(0)));
									vertices1.push_back(vertices0.at(indices.at(i).at(0)));
								}
							}

							if (normals0.size() != 0)
							{
								for (int i = 2; i < indices.size(); i++)
								{
									normals1.push_back(normals0.at(indices.at(0).at(2)));
									normals1.push_back(normals0.at(indices.at(i - 1).at(2)));
									normals1.push_back(normals0.at(indices.at(i).at(2)));
								}
							}

							if (texCoords0.size() != 0)
							{
								for (int i = 2; i < indices.size(); i++)
								{
									texCoords1.push_back(texCoords0.at(indices.at(0).at(1)));
									texCoords1.push_back(texCoords0.at(indices.at(i - 1).at(1)));
									texCoords1.push_back(texCoords0.at(indices.at(i).at(1)));
								}
							}
						}
						else if (items.at(0).compare("g") == 0)
						{
							push_result(groupname, vertices1, normals1, texCoords1);
							groupname = items.at(1);
							vertices1 = std::vector();
							normals1 = std::vector();
							texCoords1 = std::vector();
						}
					}
				}
				catch (std::out_of_range& e)
				{
					error_log << e.what() << std::endl;
					result = false;
				}
				push_result(groupname, vertices1, normals1, texCoords1);
				return result;
			}

			bool loadFromFile(std::string filename)
			{
				std::ifstream fin;
				try
				{
					fin.open(filename);
					if (!fin.is_open())
					{
						error_log << "Failed to open file." << std::endl;
						success = false;
						return false;
					}
					success = loadFromStream(fin);
					fin.close();
				}
				catch (std::ifstream::failure& e)
				{
					error_log << e.what() << std::endl;
					success = false;
					return false;
				}
				return true;
			}

			void push_result(std::string groupname, std::vector vertices, std::vector normals, std::vector texCoords)
			{
				if (vertices.size() != 0)
				{
					std::vector ver = toFloatVector(vertices);
					std::vector nor;
					if (normals.size() == 0)
					{
						nor = calcNormals(ver);
					}
					else
					{
						nor = toFloatVector(normals);
					}
					std::vector tex = toFloatVector(texCoords);
					results.push_back(std::pair(groupname, Model(ver, nor, tex)));
				}
			}

		public:
			static std::vector split(std::string data, std::string reg)
			{
				std::vector res;
				std::regex regex("(.*)" + reg + "(.*)");
				std::smatch m;
				std::string last;
				for (; std::regex_search(data, m, regex); data = m.str(1))
				{
					last = m.str(1);
					res.push_back(m.str(2));
				}
				res.push_back(last);

				std::vector result;
				for (int i = res.size() - 1; i >= 0; i--)
				{
					result.push_back(res.at(i));
				}

				return result;
			}

			static std::vector toFloatVector(std::vector vertices)
			{
				std::vector v;
				for (int i = 0; i < vertices.size(); i++)
				{
					glm::vec3 vertex = vertices.at(i);
					v.push_back(vertex.x);
					v.push_back(vertex.y);
					v.push_back(vertex.z);
				}
				return v;
			}

			static Model toModel(std::vector vertices, std::vector normals, std::vector texCoords)
			{
				std::vector v = toFloatVector(vertices);
				std::vector n = toFloatVector(normals);
				std::vector t = toFloatVector(texCoords);
				return Model(v, n, t);
			}

			static std::vector calcNormals(std::vector vertices)
			{
				std::vector normals;
				for (int i = 0; i < vertices.size() / 9; i++)
				{
					glm::vec3 A = glm::vec3(vertices.at(i * 9 + 0), vertices.at(i * 9 + 1), vertices.at(i * 9 + 2));
					glm::vec3 B = glm::vec3(vertices.at(i * 9 + 3), vertices.at(i * 9 + 4), vertices.at(i * 9 + 5));
					glm::vec3 C = glm::vec3(vertices.at(i * 9 + 6), vertices.at(i * 9 + 7), vertices.at(i * 9 + 8));

					glm::vec3 AB = glm::normalize(B - A);
					glm::vec3 BC = glm::normalize(C - B);

					glm::vec3 N = glm::normalize(glm::cross(AB, BC));

					for (int j = 0; j < 3; j++)
					{
						normals.push_back(N.x);
						normals.push_back(N.y);
						normals.push_back(N.z);
					}
				}
				return normals;
			}
			
			static std::vector stretchTexCoords(std::vector texCoords,glm::vec3 value)
			{
				std::vector result;
				for(int i = 0;i < texCoords.size() / 3;i++)
				{
					result.push_back(texCoords.at(i * 3 + 0) * value.x);
					result.push_back(texCoords.at(i * 3 + 1) * value.y);
					result.push_back(texCoords.at(i * 3 + 2) * value.z);
				}
				return result;
			}
	};
}

#endif
效果

你问为什么和加了模糊滤镜一样?
因为全屏的GLFW截不了图,这个是用手机拍的…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/852235.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号