Advertisement
Margoshinka

texture1

Mar 13th, 2023
731
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.89 KB | None | 0 0
  1. // lab_2_3.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include <iostream>
  5. #include <GL/glew.h>
  6. #include <GLFW/glfw3.h>
  7. #include <chrono>
  8. #include <glm/glm.hpp>
  9. #include <glm/gtc/matrix_transform.hpp>
  10. #include <glm/gtx/transform.hpp>
  11. #include <glm/vec3.hpp>
  12. #include <glm/vec4.hpp>
  13. #include <glm/mat4x4.hpp>
  14. #include <soil.h>
  15.  
  16. using namespace std;
  17. using namespace glm;
  18.  
  19. #pragma comment(lib, "glfw3.lib")
  20. #pragma comment(lib, "glew32.lib")
  21. #pragma comment(lib, "opengl32.lib")
  22.  
  23. // Матрица модели : единичная матрица (Модель находится в начале координат)
  24. mat4 ModelMatrix = mat4(1.0f);
  25.  
  26. GLFWwindow* g_window;
  27.  
  28. GLuint g_shaderProgram;
  29. GLint g_uMVP;
  30. GLint g_uMV;
  31.  
  32. // Текстуры
  33. const int countTextures = 2;
  34. GLuint texIDs[countTextures];
  35.  
  36. struct Texture
  37. {
  38.     const GLchar* fileName;     // Имя файла с картинкой
  39.     const GLchar* uniformMapName;       // Имя юниформа
  40.     GLint mapLocation;                  // Идентификатор юниформа
  41.     GLint texUnit;
  42.  
  43.     Texture(const GLchar* fileName, const GLchar* uniformMapName, GLint texUnit)
  44.     {
  45.         this->fileName = fileName;
  46.         this->uniformMapName = uniformMapName;
  47.         this->texUnit = texUnit;
  48.     }
  49. };
  50.  
  51. Texture textures[countTextures] =
  52. {
  53.     Texture("C:\\Users\\margo\\source\\repos\\OpenGLDemo2\\x64\\Debug\\1.png", "u_map1", 0),
  54.     Texture("C:\\Users\\margo\\source\\repos\\OpenGLDemo2\\x64\\Debug\\2.png", "u_map2", 1)
  55. };
  56.  
  57. class Model
  58. {
  59. public:
  60.     GLuint vbo;
  61.     GLuint ibo;
  62.     GLuint vao;
  63.     GLsizei indexCount;
  64. };
  65.  
  66. Model g_model;
  67.  
  68. void generateTexture(const GLchar* file_name, GLint texID)
  69. {
  70.     GLint texW, texH;
  71.     GLint channels;
  72.     unsigned char* image = SOIL_load_image(file_name, &texW, &texH, &channels, SOIL_LOAD_RGBA);
  73.     cout << SOIL_last_result();
  74.     // Привязка текстуры к цели текстуирования
  75.     glBindTexture(GL_TEXTURE_2D, texID);
  76.     // Задаем изображение текстуры
  77.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
  78.  
  79.     SOIL_free_image_data(image);
  80.  
  81.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  82.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  83.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  84.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  85. }
  86.  
  87. void initTextures()
  88. {
  89.     // Генерируем id для текстур и сохраняем их в массив
  90.     glGenTextures(2, texIDs);
  91.  
  92.     for (int i = 0; i < countTextures; i++)
  93.     {
  94.         generateTexture(textures[i].fileName, texIDs[i]);
  95.         textures[i].mapLocation = glGetUniformLocation(g_shaderProgram, textures[i].uniformMapName);
  96.     }
  97. }
  98.  
  99. GLuint createShader(const GLchar* code, GLenum type)
  100. {
  101.     GLuint result = glCreateShader(type);
  102.  
  103.     glShaderSource(result, 1, &code, NULL);
  104.     glCompileShader(result);
  105.  
  106.     GLint compiled;
  107.     glGetShaderiv(result, GL_COMPILE_STATUS, &compiled);
  108.  
  109.     if (!compiled)
  110.     {
  111.         GLint infoLen = 0;
  112.         glGetShaderiv(result, GL_INFO_LOG_LENGTH, &infoLen);
  113.         if (infoLen > 0)
  114.         {
  115.             char* infoLog = new char[infoLen];
  116.             glGetShaderInfoLog(result, infoLen, NULL, infoLog);
  117.             cout << "Shader compilation error" << endl << infoLog << endl;
  118.         }
  119.         glDeleteShader(result);
  120.         return 0;
  121.     }
  122.  
  123.     return result;
  124. }
  125.  
  126. GLuint createProgram(GLuint vsh, GLuint fsh)
  127. {
  128.     GLuint result = glCreateProgram();
  129.  
  130.     glAttachShader(result, vsh);
  131.     glAttachShader(result, fsh);
  132.  
  133.     glLinkProgram(result);
  134.  
  135.     GLint linked;
  136.     glGetProgramiv(result, GL_LINK_STATUS, &linked);
  137.  
  138.     if (!linked)
  139.     {
  140.         GLint infoLen = 0;
  141.         glGetProgramiv(result, GL_INFO_LOG_LENGTH, &infoLen);
  142.         if (infoLen > 0)
  143.         {
  144.             char* infoLog = (char*)alloca(infoLen);
  145.             glGetProgramInfoLog(result, infoLen, NULL, infoLog);
  146.             cout << "Shader program linking error" << endl << infoLog << endl;
  147.         }
  148.         glDeleteProgram(result);
  149.         return 0;
  150.     }
  151.  
  152.     return result;
  153. }
  154.  
  155. bool createShaderProgram()
  156. {
  157.     g_shaderProgram = 0;
  158.  
  159.     const GLchar vsh[] =
  160.         "#version 330\n"
  161.         ""
  162.         "layout(location = 0) in vec2 a_position;"
  163.         "layout(location = 1) in vec2 a_texCoord;"
  164.         ""
  165.         "uniform mat4 u_mv;"
  166.         "uniform mat4 u_mvp;"
  167.         ""
  168.         "out vec3 v_position;"
  169.         "out vec3 v_normal;"
  170.         "out vec2 v_texCoord;"
  171.         ""
  172.         "void main()"
  173.         "{"
  174.         "    v_texCoord = a_texCoord;"
  175.         "   vec3 position = vec3(a_position[0], sin(a_position[0]*10)*sin(a_position[1]*10)/5, a_position[1]);"
  176.         "    v_position = (u_mv * vec4(position, 1.0)).xyz;"
  177.         "    v_normal = normalize(transpose(inverse(mat3(u_mv)))*vec3(-cos(10*a_position[0])*sin(10*a_position[1]), "
  178.         "    1.0, -cos(10*a_position[1])*sin(10*a_position[0])));"
  179.         "    gl_Position = u_mvp * vec4(position, 1.0);"
  180.         "}"
  181.         ;
  182.  
  183.     const GLchar fsh[] =
  184.         "#version 330\n"
  185.         ""
  186.         "in vec3 v_position;"
  187.         "in vec3 v_normal;"
  188.         "in vec2 v_texCoord;"
  189.         ""
  190.         "layout(location = 0) out vec4 o_color;"
  191.         ""
  192.         "uniform sampler2D u_map1;"
  193.         "uniform sampler2D u_map2;"
  194.         ""
  195.         "void main()"
  196.         "{"
  197.         "   const int br_coef = 20;"                // Коэффициент светильности
  198.         "   vec3 u_l = vec3(10.0, 10.0, 0.0);"     // Положение источника света
  199.         "   vec3 n = normalize(v_normal);"         // Нормирование нормали
  200.         "   vec3 l = normalize(v_position - u_l);" // Поток света
  201.         "   float a = dot(-l, n);"                 // Угол между нормалью и лучом света
  202.         "   float d = max(a, 0.1);"               // Диффузное освещение
  203.         "   vec3 r = reflect(l, n);"               // Вектор отражения
  204.         "   vec3 e = normalize(-v_position);"      // Вектор, направленный в сторону наблюдателя
  205.         "   float s = pow(max(dot(r, e), 0.0), br_coef) * int(a >= 0);" // Уничтожение зеркального блика
  206.             "vec4 texel = mix(texture(u_map1, v_texCoord), texture(u_map2, v_texCoord), 0.5);"
  207.         "   o_color = vec4(d*texel.xyz + s*vec3(1.0), 1.0);" // Цвет поверхности
  208.         /*"o_color = vec4(texel.xyz, 1.0);"*/
  209.         "}"
  210.         ;
  211.  
  212.     GLuint vertexShader, fragmentShader;
  213.  
  214.     vertexShader = createShader(vsh, GL_VERTEX_SHADER);
  215.     fragmentShader = createShader(fsh, GL_FRAGMENT_SHADER);
  216.  
  217.     g_shaderProgram = createProgram(vertexShader, fragmentShader);
  218.  
  219.     g_uMVP = glGetUniformLocation(g_shaderProgram, "u_mvp");
  220.     g_uMV = glGetUniformLocation(g_shaderProgram, "u_mv");
  221.  
  222.     glDeleteShader(vertexShader);
  223.     glDeleteShader(fragmentShader);
  224.  
  225.     initTextures();
  226.  
  227.     return g_shaderProgram != 0;
  228. }
  229.  
  230. bool createModel()
  231. {
  232.     GLint const m = 100;
  233.  
  234.     GLfloat vertices[(m + 1) * (m + 1) * 4];
  235.  
  236.     int k = 0;
  237.     for (int i = 0; i <= m; i++)
  238.     {
  239.         for (int j = 0; j <= m; j += 1)
  240.         {
  241.             vertices[k++] = float(j) / m;
  242.             vertices[k++] = float(i) / m;
  243.             vertices[k++] = float(j) / m;
  244.             vertices[k++] = float(i) / m;
  245.         }
  246.     }
  247.     GLuint indices[m * m * 6];
  248.     k = 0;
  249.     for (int i = 0; i < m; i++)
  250.     {
  251.         for (int j = 0; j < m; j++)
  252.         {
  253.             indices[k++] = (m + 1) * i + j;
  254.             indices[k++] = (m + 1) * i + j + 1;
  255.             indices[k++] = (m + 1) * i + j + m + 2;
  256.             indices[k++] = (m + 1) * i + j + m + 2;
  257.             indices[k++] = (m + 1) * i + j + m + 1;
  258.             indices[k++] = (m + 1) * i + j;
  259.         }
  260.     }
  261.  
  262.     glGenVertexArrays(1, &g_model.vao);
  263.     glBindVertexArray(g_model.vao);
  264.  
  265.     glGenBuffers(1, &g_model.vbo);
  266.     glBindBuffer(GL_ARRAY_BUFFER, g_model.vbo);
  267.     glBufferData(GL_ARRAY_BUFFER, (m + 1) * (m + 1) * 4 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
  268.  
  269.     glGenBuffers(1, &g_model.ibo);
  270.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_model.ibo);
  271.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, m * m * 6 * sizeof(GLuint), indices, GL_STATIC_DRAW);
  272.  
  273.     g_model.indexCount = m * m * 6;
  274.  
  275.     glEnableVertexAttribArray(0);
  276.     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const GLvoid*)0);
  277.     glEnableVertexAttribArray(1);
  278.     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const GLvoid*)(2 * sizeof(GLfloat)));
  279.  
  280.     return g_model.vbo != 0 && g_model.ibo != 0 && g_model.vao != 0;
  281. }
  282.  
  283. bool init()
  284. {
  285.     // Set initial color of color buffer to white.
  286.     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  287.  
  288.     glEnable(GL_DEPTH_TEST);
  289.  
  290.     glEnable(GL_TEXTURE_2D);
  291.  
  292.     return createShaderProgram() && createModel();
  293. }
  294.  
  295. void reshape(GLFWwindow* window, int width, int height)
  296. {
  297.     glViewport(0, 0, width, height);
  298. }
  299.  
  300. void draw(GLfloat delta_draw)
  301. {
  302.     // Clear color buffer.
  303.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  304.  
  305.     glUseProgram(g_shaderProgram);
  306.     glBindVertexArray(g_model.vao);
  307.  
  308.     GLfloat near = 0.1;
  309.     GLfloat far = 100.;
  310.  
  311.     // Проекционная матрица
  312.     mat4 Projection = perspective(
  313.         radians(60.0f), // Угол обзора
  314.         4.0f / 3.0f,   // Соотншение сторон окна
  315.         near,             // Ближняя плоскость отсечения
  316.         far         // Дальняя плоскость отсечения
  317.     );
  318.  
  319.     // Коеффициент удаленности камеры
  320.     float scale_coef = 0.5f;
  321.  
  322.     mat4 View = lookAt(
  323.         vec3(3, 3, 3) * scale_coef, // Координаты камеры
  324.         vec3(0, 0, 0), // Направление камеры в начало координат
  325.         vec3(0, 1, 0)  // Координаты наблюдателя
  326.     );
  327.  
  328.     if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_RIGHT)) {
  329.         ModelMatrix = rotate(ModelMatrix, delta_draw, vec3(1.0, 0.0, 0.0));
  330.     }
  331.     else if (glfwGetKey(g_window, GLFW_KEY_UP) || glfwGetKey(g_window, GLFW_KEY_DOWN)) {
  332.         ModelMatrix = rotate(ModelMatrix, delta_draw, vec3(0.0, 1.0, 0.0));
  333.     }
  334.     else if (glfwGetKey(g_window, GLFW_KEY_Q) || glfwGetKey(g_window, GLFW_KEY_E)) {
  335.         ModelMatrix = rotate(ModelMatrix, delta_draw, vec3(0.0, 0.0, 1.0));
  336.     }
  337.  
  338.     // Матрица MV
  339.     mat4 mv = View * ModelMatrix;
  340.  
  341.     // Матрица MVP
  342.     mat4 mvp = Projection * mv;
  343.  
  344.     glUniformMatrix4fv(g_uMV, 1, GL_FALSE, &mv[0][0]);
  345.     glUniformMatrix4fv(g_uMVP, 1, GL_FALSE, &mvp[0][0]);
  346.  
  347.     for (int i = 0; i < countTextures; i++)
  348.     {
  349.         glActiveTexture(GL_TEXTURE0 + textures[i].texUnit);
  350.         glBindTexture(GL_TEXTURE_2D, texIDs[i]);
  351.         glUniform1i(textures[i].mapLocation, textures[i].texUnit);
  352.     }
  353.  
  354.     glDrawElements(GL_TRIANGLES, g_model.indexCount, GL_UNSIGNED_INT, NULL);
  355. }
  356.  
  357. void cleanup()
  358. {
  359.     if (g_shaderProgram != 0)
  360.         glDeleteProgram(g_shaderProgram);
  361.     if (g_model.vbo != 0)
  362.         glDeleteBuffers(1, &g_model.vbo);
  363.     if (g_model.ibo != 0)
  364.         glDeleteBuffers(1, &g_model.ibo);
  365.     if (g_model.vao != 0)
  366.         glDeleteVertexArrays(1, &g_model.vao);
  367.  
  368.     glDeleteTextures(countTextures, texIDs);
  369. }
  370.  
  371. bool initOpenGL()
  372. {
  373.     // Initialize GLFW functions.
  374.     if (!glfwInit())
  375.     {
  376.         cout << "Failed to initialize GLFW" << endl;
  377.         return false;
  378.     }
  379.  
  380.     // Request OpenGL 3.3 without obsoleted functions.
  381.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  382.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  383.     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  384.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  385.  
  386.     // Create window.
  387.     g_window = glfwCreateWindow(800, 600, "OpenGL Test", NULL, NULL);
  388.     if (g_window == NULL)
  389.     {
  390.         cout << "Failed to open GLFW window" << endl;
  391.         glfwTerminate();
  392.         return false;
  393.     }
  394.  
  395.     // Initialize OpenGL context with.
  396.     glfwMakeContextCurrent(g_window);
  397.  
  398.     // Set internal GLEW variable to activate OpenGL core profile.
  399.     glewExperimental = true;
  400.  
  401.     // Initialize GLEW functions.
  402.     if (glewInit() != GLEW_OK)
  403.     {
  404.         cout << "Failed to initialize GLEW" << endl;
  405.         return false;
  406.     }
  407.  
  408.     // Ensure we can capture the escape key being pressed.
  409.     glfwSetInputMode(g_window, GLFW_STICKY_KEYS, GL_TRUE);
  410.  
  411.     // Set callback for framebuffer resizing event.
  412.     glfwSetFramebufferSizeCallback(g_window, reshape);
  413.  
  414.     return true;
  415. }
  416.  
  417. void tearDownOpenGL()
  418. {
  419.     // Terminate GLFW.
  420.     glfwTerminate();
  421. }
  422.  
  423. int main()
  424. {
  425.     // Initialize OpenGL
  426.     if (!initOpenGL())
  427.         return -1;
  428.  
  429.     // Initialize graphical resources.
  430.     bool isOk = init();
  431.  
  432.     if (isOk)
  433.     {
  434.         GLfloat lastTime = glfwGetTime();
  435.  
  436.         // Main loop until window closed or escape pressed.
  437.         while (glfwGetKey(g_window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(g_window) == 0)
  438.         {
  439.             GLfloat currentTime = glfwGetTime();
  440.             GLfloat deltaTime = GLfloat(currentTime - lastTime);
  441.             lastTime = currentTime;
  442.  
  443.             GLfloat delta = 0.0;
  444.             // Угол поворота
  445.             GLfloat angle = 100.0;
  446.             // Обработка нажатий
  447.             if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_UP) || glfwGetKey(g_window, GLFW_KEY_Q)) {
  448.                 delta = radians(angle) * deltaTime;
  449.             }
  450.             else if (glfwGetKey(g_window, GLFW_KEY_RIGHT) || glfwGetKey(g_window, GLFW_KEY_DOWN) || glfwGetKey(g_window, GLFW_KEY_E)) {
  451.                 delta = -radians(angle) * deltaTime;
  452.             }
  453.             // Draw scene.
  454.             draw(delta);
  455.  
  456.             // Swap buffers.
  457.             glfwSwapBuffers(g_window);
  458.             // Poll window events.
  459.             glfwPollEvents();
  460.         }
  461.     }
  462.  
  463.     // Cleanup graphical resources.
  464.     cleanup();
  465.  
  466.     // Tear down OpenGL.
  467.     tearDownOpenGL();
  468.  
  469.     return isOk ? 0 : -1;
  470. }
  471.  
  472.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement