Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.68 KB | None | 0 0
  1. #include <glad/glad.h>
  2. #include <GLFW/glfw3.h>
  3.  
  4. #include "stb_image.h"
  5.  
  6. #include <glm/glm.hpp>
  7. #include <glm/gtc/matrix_transform.hpp>
  8. #include <glm/gtc/type_ptr.hpp>
  9.  
  10.  
  11. #define STB_IMAGE_IMPLEMENTATION
  12. #include "shader.h"
  13. #include "camera.h"
  14. #include "model.h"
  15.  
  16.  
  17. #include <iostream>
  18. void framebuffer(GLFWwindow* window, int width, int height);
  19. void mouse_move(GLFWwindow* window, double xpos, double ypos);
  20. void scrolled(GLFWwindow* window, double xoffset, double yoffset);
  21. void input(GLFWwindow *window);
  22. unsigned int getTexture(const char *path);
  23. unsigned int loadSkybox(vector<std::string> faces);
  24. void renderCarpet();
  25.  
  26. // settings
  27. const unsigned int screenWidth = 1280;
  28. const unsigned int screenHeight = 720;
  29.  
  30. // camera
  31. Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
  32. float lastX = (float)screenWidth / 2.0;
  33. float lastY = (float)screenHeight / 2.0;
  34. bool firstMouse = true;
  35.  
  36. // timing
  37. float deltaTime = 0.0f;
  38. float lastFrame = 0.0f;
  39.  
  40. int main()
  41. {
  42. // initializing
  43. glfwInit();
  44. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  45. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  46. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  47.  
  48. #ifdef __APPLE__
  49. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  50. #endif
  51.  
  52. // creating window
  53. GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "Flying Carpet", NULL, NULL);
  54. if (window == NULL)
  55. {
  56. std::cout << "Failed to create GLFW window" << std::endl;
  57. glfwTerminate();
  58. return -1;
  59. }
  60. glfwMakeContextCurrent(window);
  61. glfwSetFramebufferSizeCallback(window, framebuffer);
  62. glfwSetCursorPosCallback(window, mouse_move);
  63. glfwSetScrollCallback(window, scrolled);
  64.  
  65. // GLFW mouse capture
  66. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  67.  
  68. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
  69. {
  70. std::cout << "Failed to initialize GLAD" << std::endl;
  71. return -1;
  72. }
  73.  
  74. glEnable(GL_DEPTH_TEST);
  75.  
  76. // building and compiling shaders
  77. Shader shader("/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/4.normal_mapping.vs", "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/4.normal_mapping.fs");
  78. Shader skyboxShader("/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/6.1.skybox.vs", "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/6.1.skybox.fs");
  79.  
  80. float skyboxVertices[] = {
  81. -1.0f, 1.0f, -1.0f,
  82. -1.0f, -1.0f, -1.0f,
  83. 1.0f, -1.0f, -1.0f,
  84. 1.0f, -1.0f, -1.0f,
  85. 1.0f, 1.0f, -1.0f,
  86. -1.0f, 1.0f, -1.0f,
  87.  
  88. -1.0f, -1.0f, 1.0f,
  89. -1.0f, -1.0f, -1.0f,
  90. -1.0f, 1.0f, -1.0f,
  91. -1.0f, 1.0f, -1.0f,
  92. -1.0f, 1.0f, 1.0f,
  93. -1.0f, -1.0f, 1.0f,
  94.  
  95. 1.0f, -1.0f, -1.0f,
  96. 1.0f, -1.0f, 1.0f,
  97. 1.0f, 1.0f, 1.0f,
  98. 1.0f, 1.0f, 1.0f,
  99. 1.0f, 1.0f, -1.0f,
  100. 1.0f, -1.0f, -1.0f,
  101.  
  102. -1.0f, -1.0f, 1.0f,
  103. -1.0f, 1.0f, 1.0f,
  104. 1.0f, 1.0f, 1.0f,
  105. 1.0f, 1.0f, 1.0f,
  106. 1.0f, -1.0f, 1.0f,
  107. -1.0f, -1.0f, 1.0f,
  108.  
  109. -1.0f, 1.0f, -1.0f,
  110. 1.0f, 1.0f, -1.0f,
  111. 1.0f, 1.0f, 1.0f,
  112. 1.0f, 1.0f, 1.0f,
  113. -1.0f, 1.0f, 1.0f,
  114. -1.0f, 1.0f, -1.0f,
  115.  
  116. -1.0f, -1.0f, -1.0f,
  117. -1.0f, -1.0f, 1.0f,
  118. 1.0f, -1.0f, -1.0f,
  119. 1.0f, -1.0f, -1.0f,
  120. -1.0f, -1.0f, 1.0f,
  121. 1.0f, -1.0f, 1.0f
  122. };
  123.  
  124. unsigned int skyboxVAO, skyboxVBO;
  125. glGenVertexArrays(1, &skyboxVAO);
  126. glGenBuffers(1, &skyboxVBO);
  127. glBindVertexArray(skyboxVAO);
  128. glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
  129. glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
  130. glEnableVertexAttribArray(0);
  131. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
  132.  
  133. //getting skybox map
  134. vector<std::string> faces
  135. {
  136. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_lf.jpg",
  137. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_rt.jpg",
  138. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_up.jpg",
  139. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_dn.jpg",
  140. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_ft.jpg",
  141. "/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/cottoncandy_bk.jpg"
  142. };
  143.  
  144. // loading textures
  145. unsigned int skyboxTexture = loadSkybox(faces);
  146. unsigned int map = getTexture("/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/carpet.jpg");
  147. unsigned int normalMap = getTexture("/Users/emilpettersen/Documents/datagrafikk/prosjekt/prosjekt/carpet_normal.png");
  148.  
  149. // configure shader
  150. shader.use();
  151. shader.setInt("map", 0);
  152. shader.setInt("normalMap", 1);
  153.  
  154. skyboxShader.use();
  155. skyboxShader.setInt("skybox", 0);
  156.  
  157. // lighting
  158. glm::vec3 lightPos(0.5f, 1.0f, 0.3f);
  159.  
  160. // render loop
  161. while (!glfwWindowShouldClose(window))
  162. {
  163. // per-frame time logic
  164. float currentFrame = glfwGetTime();
  165. deltaTime = currentFrame - lastFrame;
  166. lastFrame = currentFrame;
  167.  
  168. // input
  169. // -----
  170. input(window);
  171.  
  172. // render
  173. // ------
  174. glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
  175. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  176.  
  177. // configuring matrices
  178. glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)screenWidth / (float)screenHeight, 0.1f, 100.0f);
  179. glm::mat4 view = camera.GetViewMatrix();
  180. shader.use();
  181. shader.setMat4("projection", projection);
  182. shader.setMat4("view", view);
  183. // render carpet
  184. glm::mat4 model = glm::mat4(1.0f);
  185. // rotating the carpet
  186. model = glm::rotate(model, glm::radians((float)glfwGetTime() * -10.0f), glm::normalize(glm::vec3(1.0, 0.0, 1.0)));
  187. shader.setMat4("model", model);
  188. shader.setVec3("viewPos", camera.Position);
  189. shader.setVec3("lightPos", lightPos);
  190. glActiveTexture(GL_TEXTURE0);
  191. glBindTexture(GL_TEXTURE_2D, map);
  192. glActiveTexture(GL_TEXTURE1);
  193. glBindTexture(GL_TEXTURE_2D, normalMap);
  194. renderCarpet();
  195.  
  196. // render light source
  197. model = glm::mat4(1.0f);
  198. model = glm::translate(model, lightPos);
  199. model = glm::scale(model, glm::vec3(0.1f));
  200. shader.setMat4("model", model);
  201.  
  202. glDepthFunc(GL_LEQUAL);
  203. skyboxShader.use();
  204. view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
  205. skyboxShader.setMat4("view", view);
  206. skyboxShader.setMat4("projection", projection);
  207. // binding map to skybox cube
  208. glBindVertexArray(skyboxVAO);
  209. glActiveTexture(GL_TEXTURE0);
  210. glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);
  211. glDrawArrays(GL_TRIANGLES, 0, 36);
  212. glBindVertexArray(0);
  213. glDepthFunc(GL_LESS);
  214.  
  215. glfwSwapBuffers(window);
  216. glfwPollEvents();
  217. }
  218.  
  219. // de-allocate all resources to save memory after usage
  220. glDeleteVertexArrays(1, &skyboxVAO);
  221. glDeleteBuffers(1, &skyboxVAO);
  222.  
  223. glfwTerminate();
  224. return 0;
  225. }
  226.  
  227. // renders a 1x1 quad
  228. unsigned int quadVAO = 0;
  229. unsigned int quadVBO;
  230. void renderCarpet()
  231. {
  232. if (quadVAO == 0)
  233. {
  234. // positions
  235. glm::vec3 pos1(-0.65f, 1.0f, 0.0f);
  236. glm::vec3 pos2(-0.65f, -1.0f, 0.0f);
  237. glm::vec3 pos3( 1.0f, -1.0f, 0.0f);
  238. glm::vec3 pos4( 1.0f, 1.0f, 0.0f);
  239. // texture coordinates
  240. glm::vec2 uv1(0.0f, 1.0f);
  241. glm::vec2 uv2(0.0f, 0.0f);
  242. glm::vec2 uv3(1.0f, 0.0f);
  243. glm::vec2 uv4(1.0f, 1.0f);
  244. // normal vector
  245. glm::vec3 nm(0.0f, 0.0f, 1.0f);
  246.  
  247. // calculate tangent/bitangent vectors of both triangles
  248. glm::vec3 tangent1, bitangent1;
  249. glm::vec3 tangent2, bitangent2;
  250. // triangle 1
  251. glm::vec3 edge1 = pos2 - pos1;
  252. glm::vec3 edge2 = pos3 - pos1;
  253. glm::vec2 deltaUV1 = uv2 - uv1;
  254. glm::vec2 deltaUV2 = uv3 - uv1;
  255.  
  256. GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
  257.  
  258. tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
  259. tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
  260. tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
  261. tangent1 = glm::normalize(tangent1);
  262.  
  263. bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
  264. bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
  265. bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
  266. bitangent1 = glm::normalize(bitangent1);
  267.  
  268.  
  269. edge1 = pos3 - pos1;
  270. edge2 = pos4 - pos1;
  271. deltaUV1 = uv3 - uv1;
  272. deltaUV2 = uv4 - uv1;
  273.  
  274. f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
  275.  
  276. tangent2.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
  277. tangent2.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
  278. tangent2.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
  279. tangent2 = glm::normalize(tangent2);
  280.  
  281.  
  282. bitangent2.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
  283. bitangent2.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
  284. bitangent2.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
  285. bitangent2 = glm::normalize(bitangent2);
  286.  
  287.  
  288. float quadVertices[] = {
  289. // positions // normal // texcoords // tangent // bitangent
  290. pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z,
  291. pos2.x, pos2.y, pos2.z, nm.x, nm.y, nm.z, uv2.x, uv2.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z,
  292. pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z,
  293.  
  294. pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z,
  295. pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z,
  296. pos4.x, pos4.y, pos4.z, nm.x, nm.y, nm.z, uv4.x, uv4.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z
  297. };
  298.  
  299. glGenVertexArrays(1, &quadVAO);
  300. glGenBuffers(1, &quadVBO);
  301. glBindVertexArray(quadVAO);
  302. glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
  303. glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
  304. glEnableVertexAttribArray(0);
  305. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)0);
  306. glEnableVertexAttribArray(1);
  307. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(3 * sizeof(float)));
  308. glEnableVertexAttribArray(2);
  309. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(6 * sizeof(float)));
  310. glEnableVertexAttribArray(3);
  311. glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(8 * sizeof(float)));
  312. glEnableVertexAttribArray(4);
  313. glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(11 * sizeof(float)));
  314. }
  315. glBindVertexArray(quadVAO);
  316. glDrawArrays(GL_TRIANGLES, 0, 6);
  317. glBindVertexArray(0);
  318. }
  319.  
  320. // adding user inputs to move camera and close window
  321. void input(GLFWwindow *window)
  322. {
  323. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
  324. glfwSetWindowShouldClose(window, true);
  325.  
  326. if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
  327. camera.ProcessKeyboard(FORWARD, deltaTime);
  328. if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
  329. camera.ProcessKeyboard(BACKWARD, deltaTime);
  330. if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
  331. camera.ProcessKeyboard(LEFT, deltaTime);
  332. if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
  333. camera.ProcessKeyboard(RIGHT, deltaTime);
  334. }
  335.  
  336. // whenever the window size changed this function is executed
  337. void framebuffer(GLFWwindow* window, int width, int height)
  338. {
  339. glViewport(0, 0, width, height);
  340. }
  341.  
  342. // whenever the mouse moves, this callback is called
  343. void mouse_move(GLFWwindow* window, double xpos, double ypos)
  344. {
  345. if (firstMouse)
  346. {
  347. lastX = xpos;
  348. lastY = ypos;
  349. firstMouse = false;
  350. }
  351.  
  352. float xoffset = xpos - lastX;
  353. float yoffset = lastY - ypos;
  354.  
  355. lastX = xpos;
  356. lastY = ypos;
  357.  
  358. camera.ProcessMouseMovement(xoffset, yoffset);
  359. }
  360.  
  361. // whenever the mouse scroll wheel scrolls, this callback is called
  362. void scrolled(GLFWwindow* window, double xoffset, double yoffset)
  363. {
  364. camera.ProcessMouseScroll(yoffset);
  365. }
  366.  
  367. // function for loading a texture from file
  368. unsigned int getTexture(char const * path)
  369. {
  370. unsigned int textureID;
  371. glGenTextures(1, &textureID);
  372.  
  373. int width, height, nrComponents;
  374. unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
  375. if (data)
  376. {
  377. GLenum format;
  378. if (nrComponents == 1)
  379. format = GL_RED;
  380. else if (nrComponents == 3)
  381. format = GL_RGB;
  382. else if (nrComponents == 4)
  383. format = GL_RGBA;
  384.  
  385. glBindTexture(GL_TEXTURE_2D, textureID);
  386. glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
  387. glGenerateMipmap(GL_TEXTURE_2D);
  388.  
  389. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT);
  390. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT);
  391. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  392. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  393.  
  394. stbi_image_free(data);
  395. }
  396. else
  397. {
  398. std::cout << "Texture failed to load at path: " << path << std::endl;
  399. stbi_image_free(data);
  400. }
  401.  
  402. return textureID;
  403. }
  404. unsigned int loadSkybox(vector<std::string> faces)
  405. {
  406. unsigned int textureID;
  407. glGenTextures(1, &textureID);
  408. glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
  409.  
  410. int width, height, nrChannels;
  411. for (unsigned int i = 0; i < faces.size(); i++)
  412. {
  413. unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
  414. if (data)
  415. {
  416. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  417. stbi_image_free(data);
  418. }
  419. else
  420. {
  421. std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
  422. stbi_image_free(data);
  423. }
  424. }
  425. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  426. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  427. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  428. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  429. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  430.  
  431. return textureID;
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement