OpenGL Shader 加载3Dmax模型解析
关关 2018-07-05 来源 : 阅读 712 评论 0

摘要:本篇3Dmax教程探讨了OpenGL Shader 加载3Dmax模型,希望阅读本篇文章以后大家有所收获,帮助大家对3Dmax的掌握更加熟练。

现在市面上有一个很流行的模型加载库,叫做Assimp,全称为Open Asset Import Library。Assimp可以导入几十种不同格式的模型文件(同样也可以导出部分模型格式)。只要Assimp加载完了模型文件,我们就可以从Assimp上获取所有我们需要的模型数据。Assimp把不同的模型文件都转换为一个统一的数据结构,所有无论我们导入何种格式的模型文件,都可以用同一个方式去访问我们需要的模型数据。

当导入一个模型文件时,即Assimp加载一整个包含所有模型和场景数据的模型文件到一个scene对象时,Assimp会为这个模型文件中的所有场景节点、模型节点都生成一个具有对应关系的数据结构,且将这些场景中的各种元素与模型数据对应起来。

 

Assimp:

下载,解压, 然后用CMake加载,指定输出路径后
Configure,再Generate,
然后用VS2015打开 H:\assimp-3.3.1\bin\Assimp.sln 编译
在 H:\assimp-3.3.1\bin\code\Debug 中,即可生成 
assimp-vc140-mt.lib assimp-vc140-mt.dll
然后在项目中即可使用

VS2015 可用:

包含: lib , dll 以及头文件, 可以直接使用. .VS2015....assimp-3.3.1

//download.csdn.net/detail/yulinxx/9714936

 

代码:

main.cpp

[html] view plain copy

1. // Std. Includes  

2. #include <string>  

3.   

4. // GLEW  

5. #define GLEW_STATIC  

6. #include <GL/glew.h>  

7.   

8. // GLFW  

9. #include <GLFW/glfw3.h>  

10.   

11. // GL includes  

12. #include "Shader.h"  

13. #include "Camera.h"  

14. #include "Model.h"  

15.   

16. // GLM Mathemtics  

17. #include <glm/glm.hpp>  

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

19. #include <glm/gtc/type_ptr.hpp>  

20.   

21. // Other Libs  

22. #include <SOIL/SOIL.h>  

23.   

24.   

25. #pragma comment(lib, "./SOIL.lib")  

26.   

27. #pragma comment (lib, "opengl32.lib")  

28. #pragma comment (lib, "glew32s.lib")  

29. #pragma comment (lib, "glfw3.lib")   

30. #pragma comment (lib, "glfw3dll.lib")   

31. #pragma comment (lib, "glew32mxs.lib")  

32. #pragma comment (lib, "assimp.lib")  

33.   

34.   

35. // Properties  

36. GLuint screenWidth = 800, screenHeight = 600;  

37.   

38. // Function prototypes  

39. void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);  

40. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);  

41. void mouse_callback(GLFWwindow* window, double xpos, double ypos);  

42. void Do_Movement();  

43.   

44. // Camera  

45. Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));  

46. bool keys[1024];  

47. GLfloat lastX = 400, lastY = 300;  

48. bool firstMouse = true;  

49.   

50. GLfloat deltaTime = 0.0f;  

51. GLfloat lastFrame = 0.0f;  

52.   

53. // The MAIN function, from here we start our application and run the Game loop  

54. int main()  

55. {  

56.     // Init GLFW  

57.     glfwInit();  

58.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);  

59.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);  

60.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  

61.     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);  

62.   

63.     GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "LearnOpenGL", nullptr, nullptr); // Windowed  

64.     glfwMakeContextCurrent(window);  

65.   

66.     // Set the required callback functions  

67.     glfwSetKeyCallback(window, key_callback);  

68.     glfwSetCursorPosCallback(window, mouse_callback);  

69.     glfwSetScrollCallback(window, scroll_callback);  

70.   

71.     // Options  

72.     //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);  

73.   

74.     // Initialize GLEW to setup the OpenGL Function pointers  

75.     glewExperimental = GL_TRUE;  

76.     glewInit();  

77.   

78.     // Define the viewport dimensions  

79.     glViewport(0, 0, screenWidth, screenHeight);  

80.   

81.     // Setup some OpenGL options  

82.     glEnable(GL_DEPTH_TEST);  

83.   

84.     // Setup and compile our shaders  

85.     Shader shader("./Shader/obj_vertex", "./Shader/obj_fragement");  

86.     Shader lampShader("./Shader/lamp_vertex", "./Shader/lamp_fragement");  

87.   

88.     // Load models  

89.     Model ourModel("./nanosuit.obj");  

90.     // Used a lamp object here. Find one yourself on the internet, or create your own one ;) (or be oldschool and set the VBO and VAO yourselves)  

91.     //Model lightBulb("./Bulb.obj");  

92.     Model lightBulb("./nanosuit.obj");  

93.   

94.     // Draw in wireframe  

95.     //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  

96.   

97.     // Point light positions  

98.     glm::vec3 pointLightPositions[] = {  

99.         glm::vec3(2.3f, -1.6f, -3.0f),  

100.         glm::vec3(-1.7f, 0.9f, 1.0f)  

101.     };  

102.   

103.     // Game loop  

104.     while (!glfwWindowShouldClose(window))  

105.     {  

106.         // Set frame time  

107.         GLfloat currentFrame = glfwGetTime();  

108.         deltaTime = currentFrame - lastFrame;  

109.         lastFrame = currentFrame;  

110.   

111.         // Check and call events  

112.         glfwPollEvents();  

113.         Do_Movement();  

114.   

115.         // Clear the colorbuffer  

116.         glClearColor(0.1f, 0.1f, 0.1f, 1.0f);  

117.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

118.   

119.         shader.useShaderPrograme();   // <-- Don't forget this one!  

120.         // Transformation matrices  

121.         glm::mat4 projection = glm::perspective(camera.Zoom, (float)screenWidth / (float)screenHeight, 0.1f, 100.0f);  

122.         glm::mat4 view = camera.GetViewMatrix();  

123.         glUniformMatrix4fv(glGetUniformLocation(shader.getPrograme(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));  

124.         glUniformMatrix4fv(glGetUniformLocation(shader.getPrograme(), "view"), 1, GL_FALSE, glm::value_ptr(view));  

125.   

126.         // Set the lighting uniforms  

127.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "viewPos"), camera.Position.x, camera.Position.y, camera.Position.z);  

128.         // Point light 1  

129.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].position"), pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z);  

130.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].ambient"), 0.5f, 0.5f, 0.05f);  

131.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].diffuse"), 1.0f, 1.0f, 1.0f);  

132.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].specular"), 1.0f, 1.0f, 1.0f);  

133.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].constant"), 1.0f);  

134.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].linear"), 0.9);  

135.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].quadratic"), 0.32);  

136.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].ambient"), 0.05f, 0.05f, 0.05f);  

137.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].diffuse"), 1.0f, 1.0f, 1.0f);  

138.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].specular"), 1.0f, 1.0f, 1.0f);  

139.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].constant"), 1.0f);  

140.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].linear"), 0.009);  

141.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[0].quadratic"), 0.0032);  

142.         // Point light 2  

143.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].position"), pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z);  

144.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].ambient"), 0.5f, 0.5f, 0.5f);  

145.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].diffuse"), 1.0f, 1.0f, 1.0f);  

146.         //glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].specular"), 1.0f, 1.0f, 1.0f);  

147.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].constant"), 1.0f);  

148.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].linear"), 0.9);  

149.         //glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].quadratic"), 0.32);  

150.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].ambient"), 0.05f, 0.05f, 0.05f);  

151.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].diffuse"), 1.0f, 1.0f, 1.0f);  

152.         glUniform3f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].specular"), 1.0f, 1.0f, 1.0f);  

153.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].constant"), 1.0f);  

154.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].linear"), 0.009);  

155.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "pointLights[1].quadratic"), 0.0032);  

156.   

157.         // Draw the loaded model  

158.         glm::mat4 model;  

159.         model = glm::translate(model, glm::vec3(0.0f, -1.75f, 0.0f)); // Translate it down a bit so it's at the center of the scene  

160.         model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f)); // It's a bit too big for our scene, so scale it down  

161.         glUniformMatrix4fv(glGetUniformLocation(shader.getPrograme(), "model"), 1, GL_FALSE, glm::value_ptr(model));  

162.         ourModel.Draw(shader);  

163.   

164.         // Draw the lamps  

165.         lampShader.useShaderPrograme();  

166.         glUniformMatrix4fv(glGetUniformLocation(lampShader.getPrograme(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));  

167.         glUniformMatrix4fv(glGetUniformLocation(lampShader.getPrograme(), "view"), 1, GL_FALSE, glm::value_ptr(view));  

168.         for (GLuint i = 0; i < 2; i++)  

169.         {  

170.             model = glm::mat4();  

171.             model = glm::translate(model, pointLightPositions[i]);  

172.             model = glm::scale(model, glm::vec3(0.3f, 0.3f, 0.3f)); // Downscale lamp object (a bit too large)  

173.             glUniformMatrix4fv(glGetUniformLocation(lampShader.getPrograme(), "model"), 1, GL_FALSE, glm::value_ptr(model));  

174.             lightBulb.Draw(lampShader);  

175.         }  

176.   

177.         // Swap the buffers  

178.         glfwSwapBuffers(window);  

179.     }  

180.   

181.     glfwTerminate();  

182.     return 0;  

183. }  

184.   

185. #pragma region "User input"  

186.   

187. // Moves/alters the camera positions based on user input  

188. void Do_Movement()  

189. {  

190.     // Camera controls  

191.     if (keys[GLFW_KEY_W])  

192.         camera.ProcessKeyboard(FORWARD, deltaTime);  

193.     if (keys[GLFW_KEY_S])  

194.         camera.ProcessKeyboard(BACKWARD, deltaTime);  

195.     if (keys[GLFW_KEY_A])  

196.         camera.ProcessKeyboard(LEFT, deltaTime);  

197.     if (keys[GLFW_KEY_D])  

198.         camera.ProcessKeyboard(RIGHT, deltaTime);  

199. }  

200.   

201. // Is called whenever a key is pressed/released via GLFW  

202. void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)  

203. {  

204.     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)  

205.         glfwSetWindowShouldClose(window, GL_TRUE);  

206.   

207.     if (action == GLFW_PRESS)  

208.         keys[key] = true;  

209.     else if (action == GLFW_RELEASE)  

210.         keys[key] = false;  

211. }  

212.   

213. void mouse_callback(GLFWwindow* window, double xpos, double ypos)  

214. {  

215.     if (firstMouse)  

216.     {  

217.         lastX = xpos;  

218.         lastY = ypos;  

219.         firstMouse = false;  

220.     }  

221.   

222.     GLfloat xoffset = xpos - lastX;  

223.     GLfloat yoffset = lastY - ypos;  

224.   

225.     lastX = xpos;  

226.     lastY = ypos;  

227.   

228.     camera.ProcessMouseMovement(xoffset, yoffset);  

229. }  

230.   

231. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)  

232. {  

233.     camera.ProcessMouseScroll(yoffset);  

234. }  

235.   

236. #pragma endregion  

 

 

 

mesh.h

 

[html] view plain copy

1. #pragma once  

2. // Std. Includes  

3. #include <string>  

4. #include <fstream>  

5. #include <sstream>  

6. #include <iostream>  

7. #include <vector>  

8. using namespace std;  

9. // GL Includes  

10. #include <GL/glew.h> // Contains all the necessery OpenGL includes  

11. #include <glm/glm.hpp>  

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

13.   

14.   

15. struct Vertex {  

16.     // Position  

17.     glm::vec3 Position;  

18.     // Normal  

19.     glm::vec3 Normal;  

20.     // TexCoords  

21.     glm::vec2 TexCoords;  

22. };  

23.   

24. struct Texture {  

25.     GLuint id;  

26.     string type;  

27.     aiString path;  

28. };  

29.   

30. class Mesh {  

31. public:  

32.     /*  Mesh Data  */  

33.     vector<Vertex> vertices;  

34.     vector<GLuint> indices;  

35.     vector<Texture> textures;  

36.   

37.     /*  Functions  */  

38.     // Constructor  

39.     Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<Texture> textures)  

40.     {  

41.         this->vertices = vertices;  

42.         this->indices = indices;  

43.         this->textures = textures;  

44.   

45.         // Now that we have all the required data, set the vertex buffers and its attribute pointers.  

46.         this->setupMesh();  

47.     }  

48.   

49.     // Render the mesh  

50.     void Draw(Shader shader)  

51.     {  

52.         // Bind appropriate textures  

53.         GLuint diffuseNr = 1;  

54.         GLuint specularNr = 1;  

55.         for (GLuint i = 0; i < this->textures.size(); i++)  

56.         {  

57.             glActiveTexture(GL_TEXTURE0 + i); // Active proper texture unit before binding  

58.                                               // Retrieve texture number (the N in diffuse_textureN)  

59.             stringstream ss;  

60.             string number;  

61.             string name = this->textures[i].type;  

62.             if (name == "texture_diffuse")  

63.                 ss << diffuseNr++; // Transfer GLuint to stream  

64.             else if (name == "texture_specular")  

65.                 ss << specularNr++; // Transfer GLuint to stream  

66.             number = ss.str();  

67.             // Now set the sampler to the correct texture unit  

68.             glUniform1i(glGetUniformLocation(shader.getPrograme(), (name + number).c_str()), i);  

69.             // And finally bind the texture  

70.             glBindTexture(GL_TEXTURE_2D, this->textures[i].id);  

71.         }  

72.   

73.         // Also set each mesh's shininess property to a default value (if you want you could extend this to another mesh property and possibly change this value)  

74.         glUniform1f(glGetUniformLocation(shader.getPrograme(), "material.shininess"), 16.0f);  

75.   

76.         // Draw mesh  

77.         glBindVertexArray(this->VAO);  

78.         glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);  

79.         glBindVertexArray(0);  

80.   

81.         // Always good practice to set everything back to defaults once configured.  

82.         for (GLuint i = 0; i < this->textures.size(); i++)  

83.         {  

84.             glActiveTexture(GL_TEXTURE0 + i);  

85.             glBindTexture(GL_TEXTURE_2D, 0);  

86.         }  

87.     }  

88.   

89. private:  

90.     /*  Render data  */  

91.     GLuint VAO, VBO, EBO;  

92.   

93.     /*  Functions    */  

94.     // Initializes all the buffer objects/arrays  

95.     void setupMesh()  

96.     {  

97.         // Create buffers/arrays  

98.         glGenVertexArrays(1, &this->VAO);  

99.         glGenBuffers(1, &this->VBO);  

100.         glGenBuffers(1, &this->EBO);  

101.   

102.         glBindVertexArray(this->VAO);  

103.         // Load data into vertex buffers  

104.         glBindBuffer(GL_ARRAY_BUFFER, this->VBO);  

105.         // A great thing about structs is that their memory layout is sequential for all its items.  

106.         // The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which  

107.         // again translates to 3/2 floats which translates to a byte array.  

108.         glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &this->vertices[0], GL_STATIC_DRAW);  

109.   

110.         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);  

111.         glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);  

112.   

113.         // Set the vertex attribute pointers  

114.         // Vertex Positions  

115.         glEnableVertexAttribArray(0);  

116.         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);  

117.         // Vertex Normals  

118.         glEnableVertexAttribArray(1);  

119.         glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Normal));  

120.         // Vertex Texture Coords  

121.         glEnableVertexAttribArray(2);  

122.         glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, TexCoords));  

123.   

124.         glBindVertexArray(0);  

125.     }  

126. };  

 

 

model.h

 

[html] view plain copy

1. #pragma once  

2. // Std. Includes  

3. #include <string>  

4. #include <fstream>  

5. #include <sstream>  

6. #include <iostream>  

7. #include <map>  

8. #include <vector>  

9. using namespace std;  

10. // GL Includes  

11. #include <GL/glew.h> // Contains all the necessery OpenGL includes  

12. #include <glm/glm.hpp>  

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

14. #include <SOIL/SOIL.h>  

15. #include <assimp/Importer.hpp>  

16. #include <assimp/scene.h>  

17. #include <assimp/postprocess.h>  

18.   

19. #include "Mesh.h"  

20.   

21. GLint TextureFromFile(const char* path, string directory);  

22.   

23. class Model  

24. {  

25. public:  

26.     /*  Functions   */  

27.     // Constructor, expects a filepath to a 3D model.  

28.     Model(GLchar* path)  

29.     {  

30.         this->loadModel(path);  

31.     }  

32.   

33.     // Draws the model, and thus all its meshes  

34.     void Draw(Shader shader)  

35.     {  

36.         for (GLuint i = 0; i < this->meshes.size(); i++)  

37.             this->meshes[i].Draw(shader);  

38.     }  

39.   

40. private:  

41.     /*  Model Data  */  

42.     vector<Mesh> meshes;  

43.     string directory;  

44.     vector<Texture> textures_loaded;  // Stores all the textures loaded so far, optimization to make sure textures aren't loaded more than once.  

45.   

46.                                         /*  Functions   */  

47.                                         // Loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector.  

48.     void loadModel(string path)  

49.     {  

50.         // Read file via ASSIMP  

51.         Assimp::Importer importer;  

52.         const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);  

53.         // Check for errors  

54.         if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero  

55.         {  

56.             cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;  

57.             return;  

58.         }  

59.         // Retrieve the directory path of the filepath  

60.         this->directory = path.substr(0, path.find_last_of('/'));  

61.   

62.         // Process ASSIMP's root node recursively  

63.         this->processNode(scene->mRootNode, scene);  

64.     }  

65.   

66.     // Processes a node in a recursive fashion. Processes each individual mesh located at the node and repeats this process on its children nodes (if any).  

67.     void processNode(aiNode* node, const aiScene* scene)  

68.     {  

69.         // Process each mesh located at the current node  

70.         for (GLuint i = 0; i < node->mNumMeshes; i++)  

71.         {  

72.             // The node object only contains indices to index the actual objects in the scene.   

73.             // The scene contains all the data, node is just to keep stuff organized (like relations between nodes).  

74.             aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];  

75.             this->meshes.push_back(this->processMesh(mesh, scene));  

76.         }  

77.         // After we've processed all of the meshes (if any) we then recursively process each of the children nodes  

78.         for (GLuint i = 0; i < node->mNumChildren; i++)  

79.         {  

80.             this->processNode(node->mChildren[i], scene);  

81.         }  

82.   

83.     }  

84.   

85.     Mesh processMesh(aiMesh* mesh, const aiScene* scene)  

86.     {  

87.         // Data to fill  

88.         vector<Vertex> vertices;  

89.         vector<GLuint> indices;  

90.         vector<Texture> textures;  

91.   

92.         // Walk through each of the mesh's vertices  

93.         for (GLuint i = 0; i < mesh->mNumVertices; i++)  

94.         {  

95.             Vertex vertex;  

96.             glm::vec3 vector; // We declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first.  

97.                               // Positions  

98.             vector.x = mesh->mVertices[i].x;  

99.             vector.y = mesh->mVertices[i].y;  

100.             vector.z = mesh->mVertices[i].z;  

101.             vertex.Position = vector;  

102.             // Normals  

103.             vector.x = mesh->mNormals[i].x;  

104.             vector.y = mesh->mNormals[i].y;  

105.             vector.z = mesh->mNormals[i].z;  

106.             vertex.Normal = vector;  

107.             // Texture Coordinates  

108.             if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?  

109.             {  

110.                 glm::vec2 vec;  

111.                 // A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't   

112.                 // use models where a vertex can have multiple texture coordinates so we always take the first set (0).  

113.                 vec.x = mesh->mTextureCoords[0][i].x;  

114.                 vec.y = mesh->mTextureCoords[0][i].y;  

115.                 vertex.TexCoords = vec;  

116.             }  

117.             else  

118.                 vertex.TexCoords = glm::vec2(0.0f, 0.0f);  

119.             vertices.push_back(vertex);  

120.         }  

121.         // Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.  

122.         for (GLuint i = 0; i < mesh->mNumFaces; i++)  

123.         {  

124.             aiFace face = mesh->mFaces[i];  

125.             // Retrieve all indices of the face and store them in the indices vector  

126.             for (GLuint j = 0; j < face.mNumIndices; j++)  

127.                 indices.push_back(face.mIndices[j]);  

128.         }  

129.         // Process materials  

130.         if (mesh->mMaterialIndex >= 0)  

131.         {  

132.             aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];  

133.             // We assume a convention for sampler names in the shaders. Each diffuse texture should be named  

134.             // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.   

135.             // Same applies to other texture as the following list summarizes:  

136.             // Diffuse: texture_diffuseN  

137.             // Specular: texture_specularN  

138.             // Normal: texture_normalN  

139.   

140.             // 1. Diffuse maps  

141.             vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");  

142.             textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());  

143.             // 2. Specular maps  

144.             vector<Texture> specularMaps = this->loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");  

145.             textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());  

146.         }  

147.   

148.         // Return a mesh object created from the extracted mesh data  

149.         return Mesh(vertices, indices, textures);  

150.     }  

151.   

152.     // Checks all material textures of a given type and loads the textures if they're not loaded yet.  

153.     // The required info is returned as a Texture struct.  

154.     vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName)  

155.     {  

156.         vector<Texture> textures;  

157.         for (GLuint i = 0; i < mat->GetTextureCount(type); i++)  

158.         {  

159.             aiString str;  

160.             mat->GetTexture(type, i, &str);  

161.             // Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture  

162.             GLboolean skip = false;  

163.             for (GLuint j = 0; j < textures_loaded.size(); j++)  

164.             {  

165.                 if (textures_loaded[j].path == str)  

166.                 {  

167.                     textures.push_back(textures_loaded[j]);  

168.                     skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)  

169.                     break;  

170.                 }  

171.             }  

172.             if (!skip)  

173.             {   // If texture hasn't been loaded already, load it  

174.                 Texture texture;  

175.                 texture.id = TextureFromFile(str.C_Str(), this->directory);  

176.                 texture.type = typeName;  

177.                 texture.path = str;  

178.                 textures.push_back(texture);  

179.                 this->textures_loaded.push_back(texture);  // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.  

180.             }  

181.         }  

182.         return textures;  

183.     }  

184. };  

185.   

186.   

187.   

188.   

189. GLint TextureFromFile(const char* path, string directory)  

190. {  

191.     //Generate texture ID and load texture data   

192.     string filename = string(path);  

193.     filename = directory + '/' + filename;  

194.     GLuint textureID;  

195.     glGenTextures(1, &textureID);  

196.     int width, height;  

197.     unsigned char* image = SOIL_load_image(filename.c_str(), &width, &height, 0, SOIL_LOAD_RGB);  

198.     // Assign texture to ID  

199.     glBindTexture(GL_TEXTURE_2D, textureID);  

200.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);  

201.     glGenerateMipmap(GL_TEXTURE_2D);  

202.   

203.     // Parameters  

204.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);  

205.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);  

206.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);  

207.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  

208.     glBindTexture(GL_TEXTURE_2D, 0);  

209.     SOIL_free_image_data(image);  

210.     return textureID;  

211. }  

 

 

camera.h

[html] view plain copy

1. //Camera.h   

2.   

3. #pragma once  

4.   

5. // Std. Includes  

6. #include <vector>  

7.   

8. // GL Includes  

9. #include <GL/glew.h>  

10. #include <glm/glm.hpp>  

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

12.   

13.   

14. // 摄像机移动方向  程序中用WSAD控制  

15. enum Camera_Movement {  

16.     FORWARD,  

17.     BACKWARD,  

18.     LEFT,  

19.     RIGHT  

20. };  

21.   

22. // Default camera values  

23. const GLfloat YAW = -90.0f;  

24. const GLfloat PITCH = 0.0f;  

25. const GLfloat SPEED = 3.0f;  

26. const GLfloat SENSITIVTY = 0.25f;  

27. const GLfloat ZOOM = 45.0f;  

28.   

29.   

30. class Camera  

31. {  

32. public:  

33.     // Camera Attributes  

34.     glm::vec3 Position;  

35.     glm::vec3 Front;  

36.     glm::vec3 Up;  

37.     glm::vec3 Right;  

38.     glm::vec3 WorldUp;  

39.     // Eular Angles  

40.     GLfloat Yaw;  

41.     GLfloat Pitch;  

42.     // Camera options  

43.     GLfloat MovementSpeed;  

44.     GLfloat MouseSensitivity;  

45.     GLfloat Zoom;  

46.   

47.     // Constructor with vectors  

48.     Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f),   

49.         glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW,   

50.         GLfloat pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)),   

51.         MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)  

52.     {  

53.         this->Position = position;  

54.         this->WorldUp = up;  

55.         this->Yaw = yaw;  

56.         this->Pitch = pitch;  

57.         this->updateCameraVectors();  

58.     }  

59.     // Constructor with scalar values  

60.     Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY,   

61.         GLfloat upZ, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)),   

62.         MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)  

63.     {  

64.         this->Position = glm::vec3(posX, posY, posZ);  

65.         this->WorldUp = glm::vec3(upX, upY, upZ);  

66.         this->Yaw = yaw;  

67.         this->Pitch = pitch;  

68.         this->updateCameraVectors();  

69.     }  

70.   

71.     // Returns the view matrix calculated using Eular Angles and the LookAt Matrix  

72.     glm::mat4 GetViewMatrix()  

73.     {  

74.         return glm::lookAt(this->Position, this->Position + this->Front, this->Up);  

75.     }  

76.   

77.     // 按键处理  

78.     void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime)  

79.     {  

80.         GLfloat velocity = this->MovementSpeed * deltaTime;  

81.         if (direction == FORWARD)  

82.             this->Position += this->Front * velocity;  

83.         if (direction == BACKWARD)  

84.             this->Position -= this->Front * velocity;  

85.         if (direction == LEFT)  

86.             this->Position -= this->Right * velocity;  

87.         if (direction == RIGHT)  

88.             this->Position += this->Right * velocity;  

89.     }  

90.   

91.     // 鼠标移动处理  

92.     void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset,   

93.         GLboolean constrainPitch = true)  

94.     {  

95.         xoffset *= this->MouseSensitivity;  

96.         yoffset *= this->MouseSensitivity;  

97.   

98.         this->Yaw += xoffset;  

99.         this->Pitch += yoffset;  

100.   

101.         // Make sure that when pitch is out of bounds, screen doesn't get flipped  

102.         if (constrainPitch)  

103.         {  

104.             if (this->Pitch > 89.0f)  

105.                 this->Pitch = 89.0f;  

106.             if (this->Pitch < -89.0f)  

107.                 this->Pitch = -89.0f;  

108.         }  

109.   

110.         // Update Front, Right and Up Vectors using the updated Eular angles  

111.         this->updateCameraVectors();  

112.     }  

113.   

114.     // Processes input received from a mouse scroll-wheel event.   

115.     //      Only requires input on the vertical wheel-axis  

116.     void ProcessMouseScroll(GLfloat yoffset)  

117.     {  

118.         if (this->Zoom >= 1.0f && this->Zoom <= 45.0f)  

119.             this->Zoom -= yoffset;  

120.         if (this->Zoom <= 1.0f)  

121.             this->Zoom = 1.0f;  

122.         if (this->Zoom >= 45.0f)  

123.             this->Zoom = 45.0f;  

124.     }  

125.   

126. private:  

127.     // Calculates the front vector from the Camera's (updated) Eular Angles  

128.     void updateCameraVectors()  

129.     {  

130.         // Calculate the new Front vector  

131.         glm::vec3 front;  

132.         front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));  

133.         front.y = sin(glm::radians(this->Pitch));  

134.         front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));  

135.         this->Front = glm::normalize(front);  

136.         // Also re-calculate the Right and Up vector  

137.         // Normalize the vectors, because their length gets closer to 0 the more   

138.         //      you look up or down which results in slower movement.  

139.         this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp));    

140.         this->Up = glm::normalize(glm::cross(this->Right, this->Front));  

141.     }  

142. };  

 

shader.h

 

[html] view plain copy

1. //Shader.h   

2. #pragma once  

3.   

4. #ifndef TEXTURE_SHADER_H_  

5. #define TEXTURE_SHADER_H_  

6.   

7. #include <string>  

8. #include <fstream>  

9. #include <sstream>  

10. #include <iostream>  

11.   

12. #include <gl/glew.h>  

13.   

14. #include <string>  

15. #include <fstream>  

16. #include <sstream>  

17. #include <iostream>  

18.   

19. #include <GL/glew.h>  

20.   

21. class Shader  

22. {  

23. public:  

24.     Shader(const GLchar* vertexPath, const GLchar* fragmentPath);  

25.     ~Shader();  

26.   

27. public:  

28.     void useShaderPrograme();  

29.   

30.     GLuint getPrograme() {  

31.         return this->m_nProgram;  

32.     }  

33.   

34. private:  

35.     GLuint  m_nProgram;  

36. };  

37.   

38. Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)  

39. {  

40.     std::string vertexCode;  

41.     std::string fragmentCode;  

42.     std::ifstream vertexShaderF;  

43.     std::ifstream fragementShaderF;  

44.   

45.     vertexShaderF.exceptions(std::ifstream::badbit);  

46.     fragementShaderF.exceptions(std::ifstream::badbit);  

47.   

48.     try  

49.     {  

50.         vertexShaderF.open(vertexPath);     // 打开文件  

51.         fragementShaderF.open(fragmentPath);  

52.   

53.         std::stringstream vertexShaderStream, fragementShaderStream;  

54.         vertexShaderStream << vertexShaderF.rdbuf();  // 读取文件至stringstream中  

55.         fragementShaderStream << fragementShaderF.rdbuf();  

56.   

57.         vertexShaderF.close();  

58.         fragementShaderF.close();  

59.   

60.         vertexCode = vertexShaderStream.str();      // 转换成string类型  

61.         fragmentCode = fragementShaderStream.str();  

62.     }  

63.     catch (std::ifstream::failure e)  

64.     {  

65.         std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ:" << std::endl;  

66.     }  

67.   

68.     const GLchar* pVertexCode = vertexCode.c_str(); // string 转 char*  

69.     const GLchar* pFragementCode = fragmentCode.c_str();  

70.   

71.     GLuint nVertexShader, nFragementShader;  

72.     GLint nRes = 0;  

73.     GLchar chLogInfo[512] = { '\0' };  

74.   

75.     // 创建顶点着色器  

76.     nVertexShader = glCreateShader(GL_VERTEX_SHADER);  

77.     // 将顶点着色程序的源代码字符数组绑定到顶点着色器对象  

78.     glShaderSource(nVertexShader, 1, &pVertexCode, nullptr);  

79.     glCompileShader(nVertexShader); // compile shader 编译着色器  

80.   

81.     // 获取编译结果  

82.     glGetShaderiv(nVertexShader, GL_COMPILE_STATUS, &nRes);  

83.     if (!nRes)  

84.     {  

85.         glGetShaderInfoLog(nVertexShader, 512, nullptr, chLogInfo);  

86.         std::cout << "ERROR::SHADEF::VERTEX::COMPILATION_FAILED:" << chLogInfo << std::endl;  

87.     }  

88.   

89.     // 创建片断着色器  

90.     nFragementShader = glCreateShader(GL_FRAGMENT_SHADER);  

91.     // 将片段着色程序的源代码字符数组绑定到片段着色器对象  

92.     glShaderSource(nFragementShader, 1, &pFragementCode, nullptr);  

93.     glCompileShader(nFragementShader);  

94.     glGetShaderiv(nFragementShader, GL_COMPILE_STATUS, &nRes);  

95.     if (!nRes)  

96.     {  

97.         glGetShaderInfoLog(nFragementShader, 512, nullptr, chLogInfo);  

98.         std::cout << "ERROR::SHADEF::FRAGEMENT::COMPILATION_FAILED:" << chLogInfo << std::endl;  

99.     }  

100.   

101.     this->m_nProgram = glCreateProgram();    // 创建GLSL程序  

102.     glAttachShader(this->m_nProgram, nVertexShader); // 绑定shader到program  

103.     glAttachShader(this->m_nProgram, nFragementShader);  

104.   

105.     // glLinkProgram操作产生最后的可执行程序,它包含最后可以在硬件上执行的硬件指令  

106.     glLinkProgram(this->m_nProgram);     // 链接  

107.     glGetProgramiv(this->m_nProgram, GL_LINK_STATUS, &nRes);  

108.     if (!nRes)  

109.     {  

110.         glGetProgramInfoLog(this->m_nProgram, 512, nullptr, chLogInfo);  

111.         std::cout << "ERROR::SHADEF::FRAGEMENT::LINK_FAILED:" << chLogInfo << std::endl;  

112.     }  

113.   

114.     glDeleteShader(nVertexShader);  

115.     glDeleteShader(nFragementShader);  

116. }  

117.   

118. Shader::~Shader()  

119. {  

120. }  

121.   

122. #include <glm/glm.hpp>  

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

124. #include <glm/gtc/type_ptr.hpp>  

125.   

126. void Shader::useShaderPrograme()  

127. {  

128.     glUseProgram(this->m_nProgram);  // 使用porgram  

129. }  

130.   

131. #endif  

 

***********************************Shader 源码部分************************************

obj_vertex:

 

[html] view plain copy

1. // Vertex shader:  

2. // ================  

3. #version 330 core  

4. layout (location = 0) in vec3 position;  

5. layout (location = 1) in vec3 normal;  

6. layout (location = 2) in vec2 texCoords;  

7.   

8. out vec2 TexCoords;  

9. out vec3 fragPosition;  

10. out vec3 Normal;  

11.   

12. uniform mat4 model;  

13. uniform mat4 view;  

14. uniform mat4 projection;  

15.   

16. void main()  

17. {  

18.     gl_Position = projection * view * model * vec4(position, 1.0f);  

19.     fragPosition = vec3(model * vec4(position, 1.0f));  

20.     Normal = mat3(transpose(inverse(model))) * normal;  

21.     TexCoords = texCoords;  

22. }  

 

 

obj_fragement:

 

[html] view plain copy

1. // Fragment shader:  

2. // ================  

3. #version 330 core  

4. struct Material {  

5.     sampler2D texture_diffuse1;  

6.     sampler2D texture_specular1;  

7.     float shininess;  

8. };   

9. /* Note: because we now use a material struct again you want to change your  

10. mesh class to bind all the textures using material.texture_diffuseN instead of  

11. texture_diffuseN. */  

12.   

13. struct PointLight {  

14.     vec3 position;  

15.       

16.     float constant;  

17.     float linear;  

18.     float quadratic;  

19.       

20.     vec3 ambient;  

21.     vec3 diffuse;  

22.     vec3 specular;  

23. };  

24.   

25. #define NR_POINT_LIGHTS 2  

26.   

27. in vec3 fragPosition;  

28. in vec3 Normal;  

29. in vec2 TexCoords;  

30.   

31. out vec4 color;  

32.   

33. uniform vec3 viewPos;  

34. uniform PointLight pointLights[NR_POINT_LIGHTS];  

35. uniform Material material;  

36.   

37. // Function prototypes  

38. vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir);  

39.   

40. void main()  

41. {      

42.     vec3 result;  

43.     vec3 viewDir = normalize(viewPos - fragPosition);  

44.     vec3 norm = normalize(Normal);  

45.       

46.     for(int i = 0; i < NR_POINT_LIGHTS; i++)  

47.         result += CalcPointLight(pointLights[i], material, norm, fragPosition, viewDir);  

48.           

49.     color = vec4(result, 1.0f);  

50. }  

51.   

52.   

53. // Calculates the color when using a point light.  

54. vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir)  

55. {  

56.     vec3 lightDir = normalize(light.position - fragPos);  

57.     // Diffuse shading  

58.     float diff = max(dot(normal, lightDir), 0.0);  

59.     // Specular shading  

60.     vec3 reflectDir = reflect(-lightDir, normal);  

61.     float spec = pow(max(dot(viewDir, reflectDir), 0.0), mat.shininess);  

62.     // Attenuation  

63.     float distance = length(light.position - fragPos);  

64.     float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));      

65.     // Combine results  

66.     vec3 ambient = light.ambient * vec3(texture(mat.texture_diffuse1, TexCoords));  

67.     vec3 diffuse = light.diffuse * diff * vec3(texture(mat.texture_diffuse1, TexCoords));  

68.     vec3 specular = light.specular * spec * vec3(texture(mat.texture_specular1, TexCoords));  

69.     ambient *= attenuation;  

70.     diffuse *= attenuation;  

71.     specular *= attenuation;  

72.     return (ambient + diffuse + specular);  

73. }  

 

 

lamp_vertex:

 

[html] view plain copy

1. #version 330 core  

2. layout (location = 0) in vec3 position;  

3. layout (location = 1) in vec3 normal;  

4. layout (location = 2) in vec2 texCoords;  

5.   

6. out vec2 TexCoords;  

7.   

8. uniform mat4 model;  

9. uniform mat4 view;  

10. uniform mat4 projection;  

11.   

12. void main()  

13. {  

14.     gl_Position = projection * view * model * vec4(position, 1.0f);  

15.     TexCoords = texCoords;  

16. }  

 

 

lamp_fragement:

 

[html] view plain copy

1. #version 330 core  

2.   

3. in vec2 TexCoords;  

4.   

5. out vec4 color;  

6.   

7. uniform sampler2D texture_diffuse1;  

8.   

9. void main()  

10. {      

11.     color = vec4(texture(texture_diffuse1, TexCoords));  

12. }  

 

本文由职坐标整理发布,更多相关知识,请关注职坐标常用软件3Dmax频道!

本文由 @关关 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程