Advertisement
Margoshinka

2

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