SHARE
TWEET

Untitled

a guest Apr 21st, 2019 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top