Advertisement
Margoshinka

Untitled

Feb 24th, 2023
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.00 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. mat4 ModelObj = mat4(1.0f);
  19. //размерность n x n
  20. GLint n_size = 9;
  21. //Точка отсчета
  22. GLfloat x0 = -(GLfloat)n_size / 2.0; //x
  23. GLfloat z0 = x0;//z
  24. //Шаг
  25. GLfloat dx = 0.1; //по x
  26. GLfloat dz = dx; //по z
  27. //Количество ячеек
  28. GLint n = n_size / dx;
  29. chrono::time_point<chrono::system_clock> g_callTime;
  30. GLFWwindow* g_window;
  31. GLint g_uMVP;
  32. GLint g_uMV;
  33. GLuint g_shaderProgram;
  34.  
  35. class Model
  36. {
  37. public:
  38. GLuint vbo;
  39. GLuint ibo;
  40. GLuint vao;
  41. GLsizei indexCount;
  42. };
  43.  
  44. class MyMatrix {
  45. float m_mat[16];
  46. public:
  47. static MyMatrix translation(float x, float y, float z) { //матрица переноса
  48. MyMatrix mat;
  49. mat.m_mat[0] = 1.0f; mat.m_mat[1] = 0.0f; mat.m_mat[2] = 0.0f; mat.m_mat[3] = 0.0f;
  50. mat.m_mat[4] = 0.0f; mat.m_mat[5] = 1.0f; mat.m_mat[6] = 0.0f; mat.m_mat[7] = 0.0f;
  51. mat.m_mat[8] = 0.0f; mat.m_mat[9] = 0.0f; mat.m_mat[10] = 1.0f; mat.m_mat[11] = 0.0f;
  52. mat.m_mat[12] = x; mat.m_mat[13] = y; mat.m_mat[14] = z; mat.m_mat[15] = 1.0f;
  53. return mat;
  54. }
  55. static MyMatrix xRotation(float a) {
  56. float cosA = cos(a);
  57. float sinA = sin(a);
  58. MyMatrix mat;
  59. mat.m_mat[0] = 1.0f; mat.m_mat[1] = 0.0f; mat.m_mat[2] = 0.0f; mat.m_mat[3] = 0.0f;
  60. mat.m_mat[4] = 0.0f; mat.m_mat[5] = cosA; mat.m_mat[6] = sinA; mat.m_mat[7] = 0.0f;
  61. mat.m_mat[8] = 0.0f; mat.m_mat[9] = -sinA; mat.m_mat[10] = cosA; mat.m_mat[11] = 0.0f;
  62. mat.m_mat[12] = 0.0f; mat.m_mat[13] = 0.0f; mat.m_mat[14] = 0.0f; mat.m_mat[15] = 1.0f;
  63. return mat;
  64. }
  65. MyMatrix operator * (const MyMatrix& m) {
  66. MyMatrix mat;
  67. const float* a = m_mat;
  68. const float* b = m.m_mat;
  69. float* c = mat.m_mat;
  70. for (int i = 0; i < 4; ++i) {
  71. for (int j = 0; j < 4; ++j) {
  72. *c = a[0] * b[j] + a[4] * b[j + 4] + a[8] * b[j + 8] + a[12] * b[j + 12];
  73. ++c;
  74. }
  75. a += 4;
  76. }
  77. return mat;
  78. }
  79. static MyMatrix scale(float x, float y, float z) {
  80. MyMatrix mat;
  81. mat.m_mat[0] = x;
  82. mat.m_mat[5] = y;
  83. mat.m_mat[10] = z;
  84. mat.m_mat[15] = 1.0f;
  85. return mat;
  86. }
  87. static MyMatrix zRotation(float a)
  88. {
  89. MyMatrix m;
  90. float c = cos(a);
  91. float s = sin(a);
  92. m.m_mat[0] = c;
  93. m.m_mat[1] = s;
  94. m.m_mat[4] = -s;
  95. m.m_mat[5] = c;
  96. m.m_mat[10] = 1.0f;
  97. m.m_mat[15] = 1.0f;
  98. return m;
  99. }
  100. static MyMatrix yRotation(float a) {
  101. MyMatrix m;
  102. float c = cos(a);
  103. float s = sin(a);
  104.  
  105. m.m_mat[0] = c;
  106. m.m_mat[2] = -s;
  107. m.m_mat[5] = 1.0f;
  108. m.m_mat[8] = s;
  109. m.m_mat[10] = c;
  110. m.m_mat[15] = 1.0f;
  111.  
  112. return m;
  113. }
  114.  
  115. const float* get() const { return m_mat; };
  116. };
  117. Model g_model;
  118.  
  119. const int Tess_N = 128;
  120.  
  121. float func(float x, float z) {
  122. return 10*cosf(10*(x*x+z*z))*expf(10*(x*x+z*z));
  123. }
  124.  
  125. float d_f_x(float x, float z) {
  126. return -2*10*10*10*x*sinf(10 * (x*x + z*z))*expf(10*(x*x + z*z)) - 2*10*10*x*sinf(10*(x*x + z*z))*expf(10*(x*x + z*z));
  127. }
  128.  
  129. float d_f_z(float x, float z) {
  130. return -2*10*10*10*z*sinf(10 * (x*x + z*z))*expf(10*(x*x + z*z)) - 2*10*10*z*sinf(10*(x*x + z*z))*expf(10*(x*x + z*z));
  131. }
  132.  
  133. GLuint createShader(const GLchar* code, GLenum type)
  134. {
  135. GLuint result = glCreateShader(type);
  136.  
  137. glShaderSource(result, 1, &code, NULL);
  138. glCompileShader(result);
  139.  
  140. GLint compiled;
  141. glGetShaderiv(result, GL_COMPILE_STATUS, &compiled);
  142.  
  143. if (!compiled)
  144. {
  145. GLint infoLen = 0;
  146. glGetShaderiv(result, GL_INFO_LOG_LENGTH, &infoLen);
  147. if (infoLen > 0)
  148. {
  149. char* infoLog = (char*)alloca(infoLen);
  150. glGetShaderInfoLog(result, infoLen, NULL, infoLog);
  151. cout << "Shader compilation error" << endl << infoLog << endl;
  152. }
  153. glDeleteShader(result);
  154. return 0;
  155. }
  156.  
  157. return result;
  158. }
  159.  
  160. GLuint createProgram(GLuint vsh, GLuint fsh)
  161. {
  162. GLuint result = glCreateProgram();
  163.  
  164. glAttachShader(result, vsh);
  165. glAttachShader(result, fsh);
  166.  
  167. glLinkProgram(result);
  168.  
  169. GLint linked;
  170. glGetProgramiv(result, GL_LINK_STATUS, &linked);
  171.  
  172. if (!linked)
  173. {
  174. GLint infoLen = 0;
  175. glGetProgramiv(result, GL_INFO_LOG_LENGTH, &infoLen);
  176. if (infoLen > 0)
  177. {
  178. char* infoLog = (char*)alloca(infoLen);
  179. glGetProgramInfoLog(result, infoLen, NULL, infoLog);
  180. cout << "Shader program linking error" << endl << infoLog << endl;
  181. }
  182. glDeleteProgram(result);
  183. return 0;
  184. }
  185.  
  186. return result;
  187. }
  188.  
  189. bool createShaderProgram()
  190. {
  191. g_shaderProgram = 0;
  192.  
  193.  
  194. //const GLchar vsh[] =
  195. // "#version 330\n"
  196. // ""
  197. // "layout(location = 0) in vec2 a_position;"
  198. // "layout(location = 1) in vec3 a_color;"
  199. //
  200. // ""
  201. // "out vec2 v_position;"
  202. // "out vec3 v_color;"
  203. // ""
  204. // "void main()"
  205. // "{"
  206. // " v_position = a_position;"
  207. // " v_color = a_color;"
  208. // " gl_Position = vec4(a_position, 0.0, 1.0);"
  209. // "}"
  210. // ;
  211. //const GLchar fsh[] =
  212. // "#version 330\n"
  213. // ""
  214. // "in vec2 v_position;"
  215. // "in vec3 v_color;"
  216. // ""
  217. // "layout(location = 0) out vec4 o_color;"
  218. // ""
  219. // "void main()"
  220. // "{"
  221. // // Много полос
  222. // /*" float c = v_direction;"
  223. // " const float n = 20 * 3.1415926;"
  224. // " o_color = vec4(vec3(sin(c * n)), 1.0);"*/
  225. // // Волны
  226. // /* " float n = 15.;"
  227. // " float d = 60.;"
  228. // " o_color = vec4(vec3(sin((sin(v_position[0] * n) / n - v_position[1]) * d)), 1.0);"*/
  229. // // Круги
  230. // " float d = length( abs(v_position) );"
  231. // " o_color = vec4(vec3(sin(d*100.)),1.0);"
  232. // "}"
  233. // ;
  234. const GLchar vsh[] =
  235. "#version 330\n"
  236. ""
  237. "layout(location = 0) in vec2 a_position;"
  238. ""
  239. "uniform mat4 u_mv;"
  240. "uniform mat4 u_mvp;"
  241. ""
  242. "out vec3 v_p;"
  243. "out vec3 v_normal;"
  244. ""
  245. "void main()"
  246. "{"
  247. " vec4 pos = vec4(a_position[0], 10*cos(10*(a_position[0]*a_position[0]+a_position[1]*a_position[1]))*exp(10*(a_position[0]*a_position[0]+a_position[1]*a_position[1])), a_position[1], 1.0);"
  248. " gl_Position = u_mvp*pos;"
  249. " v_p = (u_mv*pos).xyz;"
  250. " float x = a_position[0];"
  251. " float z = a_position[1];"
  252. " float g_x = -2*10*10*10*x*sin(10 * (x*x + z*z))*exp(10*(x*x + z*z)) - 2*10*10*x*sin(10*(x*x + z*z))*exp(10*(x*x + z*z));"
  253. " float g_z = -2*10*10*10*z*sin(10 * (x*x + z*z))*exp(10*(x*x + z*z)) - 2*10*10*z*sin(10*(x*x + z*z))*exp(10*(x*x + z*z));"
  254. "v_normal = vec3(0); "
  255. /* " v_normal = normalize(transpose(inverse(mat3(u_mv)))*vec3(g_x, 1.0, g_z));"*/
  256. "}"
  257. ;
  258.  
  259. const GLchar fsh[] =
  260. "#version 330\n"
  261. ""
  262. "in vec3 v_p;"
  263. "in vec3 v_normal;"
  264. ""
  265. "layout(location = 0) out vec4 o_color;"
  266. ""
  267. "void main()"
  268. "{"
  269. " vec3 u_l = vec3(5.0, 10.0, 0.0);" //Положение источника света
  270. " vec3 n = normalize(v_normal);" //нормировка нормали
  271. " vec3 l = normalize(v_p-u_l);"
  272. " float a = dot(-l, n);"
  273. " float d = max(a, 0.1);" //диффузное освещение
  274. " vec3 r = reflect(l, n);" //вектор отражения
  275. " vec3 e = normalize(-v_p);"
  276. " float s = pow(max(dot(r, e), 0.0), 5.0)*int(a >= 0);" //компонент зеркального блика
  277. " o_color = vec4(d*vec3(1.0, 0.0, 0.0)+s*vec3(1.0), 1.0);" //цвет поверхности
  278. "}"
  279. ;
  280.  
  281. GLuint vertexShader, fragmentShader;
  282.  
  283. vertexShader = createShader(vsh, GL_VERTEX_SHADER);
  284. fragmentShader = createShader(fsh, GL_FRAGMENT_SHADER);
  285.  
  286. g_shaderProgram = createProgram(vertexShader, fragmentShader);
  287.  
  288. glDeleteShader(vertexShader);
  289. glDeleteShader(fragmentShader);
  290.  
  291. return g_shaderProgram != 0;
  292. }
  293. void generateMesh(GLfloat* vertices, GLuint* indices, int Tess_N) {
  294. int index = 0;
  295.  
  296. // Проходим по сетке точек
  297. for (int i = 0; i < Tess_N; i++) {
  298. for (int j = 0; j < Tess_N; j++) {
  299. GLfloat x = (GLfloat)i / (Tess_N - 1);
  300. GLfloat z = (GLfloat)j / (Tess_N - 1);
  301. vertices[(i * Tess_N + j) * 2] = x;
  302. vertices[(i * Tess_N + j) * 2 + 1] = z;
  303. }
  304. }
  305.  
  306. // Заполняем массив индексов
  307. index = 0;
  308. for (int i = 0; i < Tess_N - 1; i++) {
  309. for (int j = 0; j < Tess_N - 1; j++) {
  310. GLuint topLeft = i * Tess_N + j;
  311. GLuint topRight = topLeft + 1;
  312. GLuint bottomLeft = (i + 1) * Tess_N + j;
  313. GLuint bottomRight = bottomLeft + 1;
  314.  
  315. indices[index++] = topLeft;
  316. indices[index++] = bottomLeft;
  317. indices[index++] = topRight;
  318.  
  319. indices[index++] = topRight;
  320. indices[index++] = bottomLeft;
  321. indices[index++] = bottomRight;
  322. }
  323. }
  324. }
  325. bool createModel()
  326. {
  327. GLfloat* vertices = (GLfloat*)malloc(Tess_N * Tess_N * 2 * sizeof(GLfloat));
  328.  
  329. /*for (int x = 0; x < Tess_N; x++) {
  330. for (int y = 0; y < Tess_N; y++) {
  331. float f_x = x / (GLfloat)Tess_N;
  332. float f_y = y / (GLfloat)Tess_N;
  333.  
  334. vertices[(x * Tess_N + y) * 6 + 0] = f_x;
  335. vertices[(x * Tess_N + y) * 6 + 1] = func(f_x, f_y);
  336. vertices[(x * Tess_N + y) * 6 + 2] = -f_y;
  337.  
  338. vertices[(x * Tess_N + y) * 6 + 3] = d_f_x(f_x, f_y);
  339. vertices[(x * Tess_N + y) * 6 + 4] = 0.0;
  340. vertices[(x * Tess_N + y) * 6 + 5] = d_f_y(f_x, f_y);
  341. }
  342. }*/
  343.  
  344. GLuint* indices = (GLuint*)malloc(
  345. (Tess_N - 1) * (Tess_N - 1) * 2 * 3 * sizeof(GLuint)
  346. );
  347.  
  348. //for (int x = 0; x < Tess_N - 1; x++) {
  349. // for (int y = 0; y < Tess_N - 1; y++) {
  350. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 0] = (x + 0) * Tess_N + y + 0;
  351. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 1] = (x + 1) * Tess_N + y + 1;
  352. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 2] = (x + 1) * Tess_N + y + 0;
  353.  
  354. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 3] = (x + 0) * Tess_N + y + 0;
  355. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 4] = (x + 0) * Tess_N + y + 1;
  356. // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 5] = (x + 1) * Tess_N + y + 1;
  357. // }
  358. //}
  359. /* const GLfloat vertices[] =
  360. {
  361. -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
  362. 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
  363. 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
  364. -0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
  365. };
  366.  
  367. const GLuint indices[] =
  368. {
  369. 0, 1, 3, 2
  370. };*/
  371. generateMesh(vertices, indices, Tess_N);
  372.  
  373. glGenVertexArrays(1, &g_model.vao);
  374. glBindVertexArray(g_model.vao);
  375.  
  376. glGenBuffers(1, &g_model.vbo);
  377. glBindBuffer(GL_ARRAY_BUFFER, g_model.vbo);
  378. glBufferData(GL_ARRAY_BUFFER, Tess_N * Tess_N * 2 * sizeof(GLfloat) , vertices, GL_STATIC_DRAW);
  379.  
  380. glGenBuffers(1, &g_model.ibo);
  381. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_model.ibo);
  382. glBufferData(GL_ELEMENT_ARRAY_BUFFER, (Tess_N - 1) * (Tess_N - 1) * 2 * 3 * sizeof(GLuint), indices, GL_STATIC_DRAW);
  383. g_model.indexCount = (Tess_N - 1) * (Tess_N - 1) * 2 * 3;
  384.  
  385. glEnableVertexAttribArray(0);
  386. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (const GLvoid*)0);
  387. /* glEnableVertexAttribArray(1);
  388. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid*)(2 * sizeof(GLfloat)));*/
  389.  
  390. return g_model.vbo != 0 && g_model.ibo != 0 && g_model.vao != 0;
  391. }
  392.  
  393. bool init()
  394. {
  395. // Set initial color of color buffer to white.
  396. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  397.  
  398. return createShaderProgram() && createModel();
  399. }
  400.  
  401. void reshape(GLFWwindow* window, int width, int height)
  402. {
  403. glViewport(0, 0, width, height);
  404. //P=...
  405. }
  406.  
  407. void draw(GLfloat delta_draw)
  408. {
  409. // Clear color buffer.
  410. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  411.  
  412. glUseProgram(g_shaderProgram);
  413. glBindVertexArray(g_model.vao);
  414.  
  415. //Проекционная матрица: 45 градусов, соотношение 4:3
  416. mat4 Projection = perspective(radians(45.0f), 4.0f / 3.0f, x0, abs(x0));
  417.  
  418.  
  419. mat4 View = lookAt(
  420. vec3(5, 3, 3) * abs(x0), //Положение камеры
  421. vec3(0, 0, 0), //Направление камеры в точку
  422. vec3(0, 1, 0) //Наблюдатель
  423. );
  424.  
  425. GLfloat a = delta_draw;
  426.  
  427. if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_RIGHT)) {
  428. ModelObj = rotate(ModelObj, delta_draw, vec3(0.0, 1.0, 0.0));
  429. }
  430. else if (glfwGetKey(g_window, GLFW_KEY_UP) || glfwGetKey(g_window, GLFW_KEY_DOWN))
  431. {
  432. ModelObj = rotate(ModelObj, delta_draw, vec3(0.0, 0.0, 1.0));
  433. }
  434.  
  435. //Матрица MV
  436. mat4 MV = View * ModelObj;
  437.  
  438. //Матрица MVP
  439. mat4 MVP = Projection * MV;
  440.  
  441. //Передача данных в шейдер
  442. glUniformMatrix4fv(g_uMV, 1, GL_FALSE, &MV[0][0]);
  443. glUniformMatrix4fv(g_uMVP, 1, GL_FALSE, &MVP[0][0]);
  444. glDrawElements(GL_TRIANGLE_STRIP, g_model.indexCount, GL_UNSIGNED_INT, NULL);
  445. }
  446.  
  447. void cleanup()
  448. {
  449. if (g_shaderProgram != 0)
  450. glDeleteProgram(g_shaderProgram);
  451. if (g_model.vbo != 0)
  452. glDeleteBuffers(1, &g_model.vbo);
  453. if (g_model.ibo != 0)
  454. glDeleteBuffers(1, &g_model.ibo);
  455. if (g_model.vao != 0)
  456. glDeleteVertexArrays(1, &g_model.vao);
  457. }
  458.  
  459. bool initOpenGL()
  460. {
  461. // Initialize GLFW functions.
  462. if (!glfwInit())
  463. {
  464. cout << "Failed to initialize GLFW" << endl;
  465. return false;
  466. }
  467.  
  468. // Request OpenGL 3.3 without obsoleted functions.
  469. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  470. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  471. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  472. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  473.  
  474. // Create window.
  475. g_window = glfwCreateWindow(800, 600, "OpenGL Test", NULL, NULL);
  476. if (g_window == NULL)
  477. {
  478. cout << "Failed to open GLFW window" << endl;
  479. glfwTerminate();
  480. return false;
  481. }
  482.  
  483. // Initialize OpenGL context with.
  484. glfwMakeContextCurrent(g_window);
  485.  
  486. // Set internal GLEW variable to activate OpenGL core profile.
  487. glewExperimental = true;
  488.  
  489. // Initialize GLEW functions.
  490. if (glewInit() != GLEW_OK)
  491. {
  492. cout << "Failed to initialize GLEW" << endl;
  493. return false;
  494. }
  495.  
  496. // Ensure we can capture the escape key being pressed.
  497. glfwSetInputMode(g_window, GLFW_STICKY_KEYS, GL_TRUE);
  498.  
  499. // Set callback for framebuffer resizing event.
  500. glfwSetFramebufferSizeCallback(g_window, reshape);
  501.  
  502. return true;
  503. }
  504.  
  505. void tearDownOpenGL()
  506. {
  507. // Terminate GLFW.
  508. glfwTerminate();
  509. }
  510.  
  511.  
  512. int main()
  513. {
  514. // Initialize OpenGL
  515. //cout << n << ", " << x0 << ", " << dx;
  516. // Initialize OpenGL
  517. if (!initOpenGL())
  518. return -1;
  519.  
  520. // Initialize graphical resources.
  521. bool isOk = init();
  522.  
  523. if (isOk)
  524. {
  525. GLfloat lastTime = glfwGetTime();
  526.  
  527. // Main loop until window closed or escape pressed.
  528. while (glfwGetKey(g_window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(g_window) == 0)
  529. {
  530. GLfloat currentTime = glfwGetTime();
  531. GLfloat deltaTime = GLfloat(currentTime - lastTime);
  532. lastTime = currentTime;
  533.  
  534. GLfloat delta = 0;
  535. GLfloat angle = 200.0;
  536. if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_UP)) {
  537. delta = radians(angle) * deltaTime;
  538. }
  539. else if (glfwGetKey(g_window, GLFW_KEY_RIGHT) || glfwGetKey(g_window, GLFW_KEY_DOWN)) {
  540. delta = -radians(angle) * deltaTime;
  541. }
  542. draw(delta);
  543. // Swap buffers.
  544. glfwSwapBuffers(g_window);
  545. // Poll window events.
  546. glfwPollEvents();
  547. }
  548. }
  549.  
  550. // Cleanup graphical resources.
  551. cleanup();
  552.  
  553. // Tear down OpenGL.
  554. tearDownOpenGL();
  555.  
  556. return isOk ? 0 : -1;
  557. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement