Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.84 KB | None | 0 0
  1. //internal includes
  2. #include "common.h"
  3. #include "ShaderProgram.h"
  4. #include <unistd.h>
  5.  
  6. //External dependencies
  7. #define GLFW_DLL
  8. #include <GLFW/glfw3.h>
  9. #include <random>
  10. #include <ctime>
  11.  
  12. #include <vector>
  13.  
  14. #include <assimp/Importer.hpp>
  15. #include <assimp/scene.h>
  16. #include <assimp/postprocess.h>
  17.  
  18. #include <glm/vec3.hpp>
  19.  
  20. static const GLsizei WIDTH = 1400, HEIGHT = 1000; //размеры окна
  21.  
  22. //Создание переменной для хранения идентификатора VBO(см.далее)
  23. GLuint g_vertexBufferObject;
  24.  
  25. //Создание переменной для хранения идентификатора VAO(см.далее)
  26. GLuint g_vertexArrayObject;
  27. GLuint g_vertexEBO;
  28.  
  29.  
  30. struct Vert {
  31. glm::vec3 v; //координаты вершины
  32. glm::vec3 n; //нормаль
  33. public:
  34. Vert(float v1, float v2, float v3, float n1, float n2, float n3) {
  35. v = glm::vec3(v1, v2, v3);
  36. n = glm::vec3(n1, n2, n3);
  37. }
  38. };
  39.  
  40.  
  41. void fun1(const aiScene * scene, std::vector <Vert> & v, std::vector <unsigned int> & ind) {
  42. //У vase - 1 потомок с 1 мешем, у table - 1 потомок с двумя мешами
  43. //Сразу перейдем к потомку
  44. aiNode * root = scene -> mRootNode;
  45. aiNode * child = root -> mChildren[0]; // только один потомок
  46.  
  47. for(unsigned int i = 0; i < child-> mNumMeshes; i++) {
  48. aiMesh *mesh = scene->mMeshes[child -> mMeshes[i]];
  49. for (int j = 0; j < 5/*mesh->mNumVertices */; j++) {
  50. Vert curtVert(mesh->mVertices[j].x, mesh->mVertices[j].y, mesh->mVertices[j].z, mesh->mNormals[j].x, mesh->mNormals[j].y, mesh->mNormals[j].z);
  51. v.push_back(curtVert);
  52. }
  53. for(unsigned int i = 0; i < mesh->mNumFaces; i++)
  54. {
  55. aiFace face = mesh->mFaces[i];
  56. for(unsigned int j = 0; j < face.mNumIndices; j++){
  57. ind.push_back(face.mIndices[j]);
  58. }
  59. // каждого меша еще надо сделать материалы, но потом
  60.  
  61. }
  62. }
  63.  
  64.  
  65. }
  66.  
  67. void load (std::string path, std::vector <Vert> & verts, std::vector <unsigned int> & indices)
  68. //Создаем и загружаем геометрию поверхности
  69. //
  70. {
  71. Assimp::Importer import;
  72. const aiScene * scene = import.ReadFile(path, aiProcess_Triangulate);
  73. //У vase - 1 потомок с 1 мешем, у table - 1 потомок с двумя мешами
  74.  
  75. fun1(scene, verts, indices);
  76.  
  77. g_vertexBufferObject = 0;
  78. GLuint vertexLocation = 0; // simple layout, assume have only positions at location = 0
  79.  
  80. /*Л. везде дальше GL_CHECK_ERRORS - полезный макрос для проверки ошибок в строчке, где он был записан */
  81.  
  82.  
  83. /*Л. Следующие три строки работаем с Vertex Buffer Object (VBO) — средством OpenGL, позволяющее загружать определенные данные в память GPU
  84. https://eax.me/opengl-vbo-vao-shaders/*/
  85.  
  86.  
  87. glGenBuffers(1, &g_vertexBufferObject); GL_CHECK_ERRORS;
  88. // Копируем массив с вершинами в буфер OpenGL
  89.  
  90. glBindBuffer(GL_ARRAY_BUFFER, g_vertexBufferObject);
  91. glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(Vert), &verts[0], GL_STATIC_DRAW); GL_CHECK_ERRORS;
  92.  
  93.  
  94. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_vertexEBO);
  95. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
  96.  
  97.  
  98. /*Еще 2 строчек - Vertex Arrays Object (VAO) — штука, которая говорит OpenGL, какую часть VBO следует использовать в последующих командах.
  99. Представьте, что VAO представляет собой массив, в элементах которого хранится информация о том, какую часть некого VBO использовать,
  100. и как эти данные нужно интерпретировать. Таким образом, один VAO по разным индексам может хранить координаты вершин, их цвета, нормали и прочие данные.
  101. Переключившись на нужный VAO мы можем эффективно обращаться к данным, на которые он «указывает», используя только индексы.
  102. https://eax.me/opengl-vbo-vao-shaders/*/
  103. glGenVertexArrays(1, &g_vertexArrayObject); GL_CHECK_ERRORS;
  104. // Привязываем VAO
  105. glBindVertexArray(g_vertexArrayObject); GL_CHECK_ERRORS;
  106.  
  107.  
  108. //очень возможно, следующая строка не нужна
  109. glBindBuffer(GL_ARRAY_BUFFER, g_vertexBufferObject); GL_CHECK_ERRORS;
  110.  
  111. //Устанавливаем указатели на вершинные атрибуты
  112. glEnableVertexAttribArray(0); /*здесь vertexlocation = 0*/ // GL_CHECK_ERRORS;
  113. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)0);
  114. glEnableVertexAttribArray(1); /*здесь vertexlocation = 0*/ // GL_CHECK_ERRORS;
  115. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, n));
  116. // Отвязываем VAO
  117. glBindVertexArray(0);
  118. }
  119.  
  120.  
  121.  
  122. void draw(ShaderProgram program, GLFWwindow* window, std::vector <Vert> & verts, std::vector <unsigned int> & indices /*, float ** col*/) {
  123. /* Л. glfwPollEvents обрабатывает только те события, которые уже находятся в очереди событий, а затем сразу же возвращается.
  124. Обработка событий вызовет окно и входные обратные вызовы, связанные с этими событиями. */
  125. glfwPollEvents();
  126.  
  127.  
  128. //Л. glClearColor задает красные, зеленые, синие и Альфа-значения, используемые glClear для очистки цветовых буферов.
  129. //очищаем экран каждый кадр
  130. glClearColor(0.1f, 0.1f, 0.1f, 1.0f); GL_CHECK_ERRORS;
  131.  
  132. /*Л. glClear устанавливает область окна к ранее выбранным значениям по glClearColor, glClearIndex, glClearDepth, glClearStencil, и glClearAccum.
  133. Несколько цветовых буферов можно очистить одновременно, выбрав более чем один буфер за раз, используя glDrawBuffer. */
  134. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_CHECK_ERRORS;
  135.  
  136. /* Л. program.StartUseShader() запускаем шейдеры*/
  137. program.StartUseShader(); GL_CHECK_ERRORS;
  138.  
  139.  
  140. // очистка и заполнение экрана цветом
  141. //
  142. /* Л. glViewport определяет аффинное преобразование координат x и y из нормализованных координат устройства в координаты окна.
  143. https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glViewport.xml*/
  144. glViewport (0, 0, WIDTH, HEIGHT);
  145.  
  146. /*Л. следующие две строчки - см.ранее*/
  147. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  148. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  149.  
  150. // draw call
  151. //
  152. /*Л. рисуем примитивы, которые загрузили ранее
  153. https://eax.me/opengl-vbo-vao-shaders/*/
  154. glBindVertexArray(g_vertexArrayObject); GL_CHECK_ERRORS;
  155.  
  156. glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
  157. glBindVertexArray(0);
  158.  
  159. program.StopUseShader();
  160.  
  161. //Л. glfwSwapBuffers меняет местами передний и задний буферы указанного окна.
  162. //Если интервал подкачки больше нуля, драйвер GPU ожидает указанное количество обновлений экрана перед заменой буферов.
  163. glfwSwapBuffers(window);
  164.  
  165. }
  166.  
  167. int initGL()
  168. {
  169. int res = 0;
  170. //грузим функции opengl через glad
  171. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
  172. {
  173. std::cout << "Failed to initialize OpenGL context" << std::endl;
  174. return -1;
  175. }
  176.  
  177. std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
  178. std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
  179. std::cout << "Version: " << glGetString(GL_VERSION) << std::endl;
  180. std::cout << "GLSL: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
  181.  
  182. return 0;
  183. }
  184.  
  185.  
  186. int main(int argc, char** argv)
  187. {
  188. /* glfwInit инициализирует библиотеку GLFW. Перед использованием большинства функций GLFW необходимо инициализировать GLFW,
  189. а перед завершением работы приложения необходимо завершить GLFW, чтобы освободить ресурсы, выделенные во время или после инициализации. */
  190. if(!glfwInit())
  191. return -1;
  192.  
  193. //запрашиваем контекст opengl версии 3.3
  194. //делаем начальные настройки Л.
  195. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  196. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  197. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  198. glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
  199.  
  200. GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL basic sample", nullptr, nullptr);
  201. //Эта функция создает окно и связанный с ним контекст OpenGL или OpenGL ES.
  202. // Большинство параметров, управляющих созданием окна и его контекста, задаются с помощью подсказок окна(window hints). Л.
  203.  
  204. if (window == nullptr)
  205. {
  206. std::cout << "Failed to create GLFW window" << std::endl;
  207. glfwTerminate();
  208. return -1;
  209. }
  210.  
  211. /* Л. glfwMakeContextCurrent делает контекст OpenGL или OpenGL ES указанного окна текущим в вызывающем потоке.
  212. Контекст можно сделать текущим только в одном потоке за один раз, и каждый поток может иметь только один текущий контекст за один раз. */
  213. glfwMakeContextCurrent(window);
  214.  
  215.  
  216. /* Л.
  217. glfwSetInputMode устанавливает режим ввода для указанного окна. Режим должен быть одним из GLFW_CURSOR, GLFW_STICKY_KEYS или GLFW_STICKY_MOUSE_BUTTONS.
  218. */
  219.  
  220. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  221.  
  222. //функция, см. выше Л.
  223. if(initGL() != 0)
  224. return -1;
  225.  
  226. //Reset any OpenGL errors which could be present for some reason
  227. GLenum gl_error = glGetError();
  228. while (gl_error != GL_NO_ERROR)
  229. gl_error = glGetError();
  230.  
  231. //создание шейдерной программы из двух файлов с исходниками шейдеров
  232. //используется класс-обертка ShaderProgram
  233. std::unordered_map<GLenum, std::string> shaders;
  234. shaders[GL_VERTEX_SHADER] = "vertex.glsl";
  235. shaders[GL_FRAGMENT_SHADER] = "fragment.glsl";
  236. ShaderProgram program(shaders); GL_CHECK_ERRORS;
  237.  
  238.  
  239.  
  240. // Л. glfwSwapInterval устанавливает интервал подкачки для текущего контекста OpenGL или OpenGL ES,
  241. // т. е. количество обновлений экрана, ожидающих с момента вызова glfwSwapBuffers до подкачки буферов и возврата.
  242. glfwSwapInterval(1); // force 60 frames per second
  243. time_t prev = time(0);
  244.  
  245. double ms_per_update = 0.115f;
  246. while (!glfwWindowShouldClose(window))
  247. {
  248. time_t begin = time(0);
  249. std::vector <Vert> verts;
  250. std::vector <unsigned int> indices;
  251. load("/media/derin/DATA/Computer_Graph/3/prob1/objects/vase.obj", verts, indices);
  252. std::cout << "----------------------------" << "\n";
  253. //load("/media/derin/DATA/Computer_Graph/3/prob1/objects/table_simple.obj");
  254. draw(program, window, verts, indices);
  255. sleep(ms_per_update - difftime(time(0), begin));
  256. break;
  257. }
  258.  
  259. //очищаем vbo и vao перед закрытием программы
  260. //
  261. glDeleteVertexArrays(1, &g_vertexArrayObject);
  262. glDeleteBuffers(1, &g_vertexBufferObject);
  263.  
  264. glfwTerminate();
  265. return 0;
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement