Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <GL/glew.h>
- #include <GLFW/glfw3.h>
- #include <chrono>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtx/transform.hpp>
- #include <glm/vec3.hpp> // vec3
- #include <glm/vec4.hpp> // vec4
- #include <glm/mat4x4.hpp>
- #pragma comment(lib, "glfw3.lib")
- #pragma comment(lib, "glew32.lib")
- #pragma comment(lib, "opengl32.lib")
- using namespace std;
- using namespace glm;
- mat4 ModelObj = mat4(1.0f);
- //размерность n x n
- GLint n_size = 9;
- //Точка отсчета
- GLfloat x0 = -(GLfloat)n_size / 2.0; //x
- GLfloat z0 = x0;//z
- //Шаг
- GLfloat dx = 0.1; //по x
- GLfloat dz = dx; //по z
- //Количество ячеек
- GLint n = n_size / dx;
- chrono::time_point<chrono::system_clock> g_callTime;
- GLFWwindow* g_window;
- GLint g_uMVP;
- GLint g_uMV;
- GLuint g_shaderProgram;
- class Model
- {
- public:
- GLuint vbo;
- GLuint ibo;
- GLuint vao;
- GLsizei indexCount;
- };
- class MyMatrix {
- float m_mat[16];
- public:
- static MyMatrix translation(float x, float y, float z) { //матрица переноса
- MyMatrix mat;
- mat.m_mat[0] = 1.0f; mat.m_mat[1] = 0.0f; mat.m_mat[2] = 0.0f; mat.m_mat[3] = 0.0f;
- mat.m_mat[4] = 0.0f; mat.m_mat[5] = 1.0f; mat.m_mat[6] = 0.0f; mat.m_mat[7] = 0.0f;
- mat.m_mat[8] = 0.0f; mat.m_mat[9] = 0.0f; mat.m_mat[10] = 1.0f; mat.m_mat[11] = 0.0f;
- mat.m_mat[12] = x; mat.m_mat[13] = y; mat.m_mat[14] = z; mat.m_mat[15] = 1.0f;
- return mat;
- }
- static MyMatrix xRotation(float a) {
- float cosA = cos(a);
- float sinA = sin(a);
- MyMatrix mat;
- mat.m_mat[0] = 1.0f; mat.m_mat[1] = 0.0f; mat.m_mat[2] = 0.0f; mat.m_mat[3] = 0.0f;
- mat.m_mat[4] = 0.0f; mat.m_mat[5] = cosA; mat.m_mat[6] = sinA; mat.m_mat[7] = 0.0f;
- mat.m_mat[8] = 0.0f; mat.m_mat[9] = -sinA; mat.m_mat[10] = cosA; mat.m_mat[11] = 0.0f;
- mat.m_mat[12] = 0.0f; mat.m_mat[13] = 0.0f; mat.m_mat[14] = 0.0f; mat.m_mat[15] = 1.0f;
- return mat;
- }
- MyMatrix operator * (const MyMatrix& m) {
- MyMatrix mat;
- const float* a = m_mat;
- const float* b = m.m_mat;
- float* c = mat.m_mat;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- *c = a[0] * b[j] + a[4] * b[j + 4] + a[8] * b[j + 8] + a[12] * b[j + 12];
- ++c;
- }
- a += 4;
- }
- return mat;
- }
- static MyMatrix scale(float x, float y, float z) {
- MyMatrix mat;
- mat.m_mat[0] = x;
- mat.m_mat[5] = y;
- mat.m_mat[10] = z;
- mat.m_mat[15] = 1.0f;
- return mat;
- }
- static MyMatrix zRotation(float a)
- {
- MyMatrix m;
- float c = cos(a);
- float s = sin(a);
- m.m_mat[0] = c;
- m.m_mat[1] = s;
- m.m_mat[4] = -s;
- m.m_mat[5] = c;
- m.m_mat[10] = 1.0f;
- m.m_mat[15] = 1.0f;
- return m;
- }
- static MyMatrix yRotation(float a) {
- MyMatrix m;
- float c = cos(a);
- float s = sin(a);
- m.m_mat[0] = c;
- m.m_mat[2] = -s;
- m.m_mat[5] = 1.0f;
- m.m_mat[8] = s;
- m.m_mat[10] = c;
- m.m_mat[15] = 1.0f;
- return m;
- }
- const float* get() const { return m_mat; };
- };
- Model g_model;
- const int Tess_N = 128;
- float func(float x, float z) {
- return 10*cosf(10*(x*x+z*z))*expf(10*(x*x+z*z));
- }
- float d_f_x(float x, float z) {
- 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));
- }
- float d_f_z(float x, float z) {
- 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));
- }
- GLuint createShader(const GLchar* code, GLenum type)
- {
- GLuint result = glCreateShader(type);
- glShaderSource(result, 1, &code, NULL);
- glCompileShader(result);
- GLint compiled;
- glGetShaderiv(result, GL_COMPILE_STATUS, &compiled);
- if (!compiled)
- {
- GLint infoLen = 0;
- glGetShaderiv(result, GL_INFO_LOG_LENGTH, &infoLen);
- if (infoLen > 0)
- {
- char* infoLog = (char*)alloca(infoLen);
- glGetShaderInfoLog(result, infoLen, NULL, infoLog);
- cout << "Shader compilation error" << endl << infoLog << endl;
- }
- glDeleteShader(result);
- return 0;
- }
- return result;
- }
- GLuint createProgram(GLuint vsh, GLuint fsh)
- {
- GLuint result = glCreateProgram();
- glAttachShader(result, vsh);
- glAttachShader(result, fsh);
- glLinkProgram(result);
- GLint linked;
- glGetProgramiv(result, GL_LINK_STATUS, &linked);
- if (!linked)
- {
- GLint infoLen = 0;
- glGetProgramiv(result, GL_INFO_LOG_LENGTH, &infoLen);
- if (infoLen > 0)
- {
- char* infoLog = (char*)alloca(infoLen);
- glGetProgramInfoLog(result, infoLen, NULL, infoLog);
- cout << "Shader program linking error" << endl << infoLog << endl;
- }
- glDeleteProgram(result);
- return 0;
- }
- return result;
- }
- bool createShaderProgram()
- {
- g_shaderProgram = 0;
- //const GLchar vsh[] =
- // "#version 330\n"
- // ""
- // "layout(location = 0) in vec2 a_position;"
- // "layout(location = 1) in vec3 a_color;"
- //
- // ""
- // "out vec2 v_position;"
- // "out vec3 v_color;"
- // ""
- // "void main()"
- // "{"
- // " v_position = a_position;"
- // " v_color = a_color;"
- // " gl_Position = vec4(a_position, 0.0, 1.0);"
- // "}"
- // ;
- //const GLchar fsh[] =
- // "#version 330\n"
- // ""
- // "in vec2 v_position;"
- // "in vec3 v_color;"
- // ""
- // "layout(location = 0) out vec4 o_color;"
- // ""
- // "void main()"
- // "{"
- // // Много полос
- // /*" float c = v_direction;"
- // " const float n = 20 * 3.1415926;"
- // " o_color = vec4(vec3(sin(c * n)), 1.0);"*/
- // // Волны
- // /* " float n = 15.;"
- // " float d = 60.;"
- // " o_color = vec4(vec3(sin((sin(v_position[0] * n) / n - v_position[1]) * d)), 1.0);"*/
- // // Круги
- // " float d = length( abs(v_position) );"
- // " o_color = vec4(vec3(sin(d*100.)),1.0);"
- // "}"
- // ;
- const GLchar vsh[] =
- "#version 330\n"
- ""
- "layout(location = 0) in vec2 a_position;"
- ""
- "uniform mat4 u_mv;"
- "uniform mat4 u_mvp;"
- ""
- "out vec3 v_p;"
- "out vec3 v_normal;"
- ""
- "void main()"
- "{"
- " 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);"
- " gl_Position = u_mvp*pos;"
- " v_p = (u_mv*pos).xyz;"
- " float x = a_position[0];"
- " float z = a_position[1];"
- " 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));"
- " 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));"
- "v_normal = vec3(0); "
- /* " v_normal = normalize(transpose(inverse(mat3(u_mv)))*vec3(g_x, 1.0, g_z));"*/
- "}"
- ;
- const GLchar fsh[] =
- "#version 330\n"
- ""
- "in vec3 v_p;"
- "in vec3 v_normal;"
- ""
- "layout(location = 0) out vec4 o_color;"
- ""
- "void main()"
- "{"
- " vec3 u_l = vec3(5.0, 10.0, 0.0);" //Положение источника света
- " vec3 n = normalize(v_normal);" //нормировка нормали
- " vec3 l = normalize(v_p-u_l);"
- " float a = dot(-l, n);"
- " float d = max(a, 0.1);" //диффузное освещение
- " vec3 r = reflect(l, n);" //вектор отражения
- " vec3 e = normalize(-v_p);"
- " float s = pow(max(dot(r, e), 0.0), 5.0)*int(a >= 0);" //компонент зеркального блика
- " o_color = vec4(d*vec3(1.0, 0.0, 0.0)+s*vec3(1.0), 1.0);" //цвет поверхности
- "}"
- ;
- GLuint vertexShader, fragmentShader;
- vertexShader = createShader(vsh, GL_VERTEX_SHADER);
- fragmentShader = createShader(fsh, GL_FRAGMENT_SHADER);
- g_shaderProgram = createProgram(vertexShader, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- return g_shaderProgram != 0;
- }
- void generateMesh(GLfloat* vertices, GLuint* indices, int Tess_N) {
- int index = 0;
- // Проходим по сетке точек
- for (int i = 0; i < Tess_N; i++) {
- for (int j = 0; j < Tess_N; j++) {
- GLfloat x = (GLfloat)i / (Tess_N - 1);
- GLfloat z = (GLfloat)j / (Tess_N - 1);
- vertices[(i * Tess_N + j) * 2] = x;
- vertices[(i * Tess_N + j) * 2 + 1] = z;
- }
- }
- // Заполняем массив индексов
- index = 0;
- for (int i = 0; i < Tess_N - 1; i++) {
- for (int j = 0; j < Tess_N - 1; j++) {
- GLuint topLeft = i * Tess_N + j;
- GLuint topRight = topLeft + 1;
- GLuint bottomLeft = (i + 1) * Tess_N + j;
- GLuint bottomRight = bottomLeft + 1;
- indices[index++] = topLeft;
- indices[index++] = bottomLeft;
- indices[index++] = topRight;
- indices[index++] = topRight;
- indices[index++] = bottomLeft;
- indices[index++] = bottomRight;
- }
- }
- }
- bool createModel()
- {
- GLfloat* vertices = (GLfloat*)malloc(Tess_N * Tess_N * 2 * sizeof(GLfloat));
- /*for (int x = 0; x < Tess_N; x++) {
- for (int y = 0; y < Tess_N; y++) {
- float f_x = x / (GLfloat)Tess_N;
- float f_y = y / (GLfloat)Tess_N;
- vertices[(x * Tess_N + y) * 6 + 0] = f_x;
- vertices[(x * Tess_N + y) * 6 + 1] = func(f_x, f_y);
- vertices[(x * Tess_N + y) * 6 + 2] = -f_y;
- vertices[(x * Tess_N + y) * 6 + 3] = d_f_x(f_x, f_y);
- vertices[(x * Tess_N + y) * 6 + 4] = 0.0;
- vertices[(x * Tess_N + y) * 6 + 5] = d_f_y(f_x, f_y);
- }
- }*/
- GLuint* indices = (GLuint*)malloc(
- (Tess_N - 1) * (Tess_N - 1) * 2 * 3 * sizeof(GLuint)
- );
- //for (int x = 0; x < Tess_N - 1; x++) {
- // for (int y = 0; y < Tess_N - 1; y++) {
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 0] = (x + 0) * Tess_N + y + 0;
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 1] = (x + 1) * Tess_N + y + 1;
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 2] = (x + 1) * Tess_N + y + 0;
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 3] = (x + 0) * Tess_N + y + 0;
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 4] = (x + 0) * Tess_N + y + 1;
- // indices[(x * (Tess_N - 1) + y) * 2 * 3 + 5] = (x + 1) * Tess_N + y + 1;
- // }
- //}
- /* const GLfloat vertices[] =
- {
- -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
- 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
- -0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
- };
- const GLuint indices[] =
- {
- 0, 1, 3, 2
- };*/
- generateMesh(vertices, indices, Tess_N);
- glGenVertexArrays(1, &g_model.vao);
- glBindVertexArray(g_model.vao);
- glGenBuffers(1, &g_model.vbo);
- glBindBuffer(GL_ARRAY_BUFFER, g_model.vbo);
- glBufferData(GL_ARRAY_BUFFER, Tess_N * Tess_N * 2 * sizeof(GLfloat) , vertices, GL_STATIC_DRAW);
- glGenBuffers(1, &g_model.ibo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_model.ibo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, (Tess_N - 1) * (Tess_N - 1) * 2 * 3 * sizeof(GLuint), indices, GL_STATIC_DRAW);
- g_model.indexCount = (Tess_N - 1) * (Tess_N - 1) * 2 * 3;
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (const GLvoid*)0);
- /* glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid*)(2 * sizeof(GLfloat)));*/
- return g_model.vbo != 0 && g_model.ibo != 0 && g_model.vao != 0;
- }
- bool init()
- {
- // Set initial color of color buffer to white.
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- return createShaderProgram() && createModel();
- }
- void reshape(GLFWwindow* window, int width, int height)
- {
- glViewport(0, 0, width, height);
- //P=...
- }
- void draw(GLfloat delta_draw)
- {
- // Clear color buffer.
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUseProgram(g_shaderProgram);
- glBindVertexArray(g_model.vao);
- //Проекционная матрица: 45 градусов, соотношение 4:3
- mat4 Projection = perspective(radians(45.0f), 4.0f / 3.0f, x0, abs(x0));
- mat4 View = lookAt(
- vec3(5, 3, 3) * abs(x0), //Положение камеры
- vec3(0, 0, 0), //Направление камеры в точку
- vec3(0, 1, 0) //Наблюдатель
- );
- GLfloat a = delta_draw;
- if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_RIGHT)) {
- ModelObj = rotate(ModelObj, delta_draw, vec3(0.0, 1.0, 0.0));
- }
- else if (glfwGetKey(g_window, GLFW_KEY_UP) || glfwGetKey(g_window, GLFW_KEY_DOWN))
- {
- ModelObj = rotate(ModelObj, delta_draw, vec3(0.0, 0.0, 1.0));
- }
- //Матрица MV
- mat4 MV = View * ModelObj;
- //Матрица MVP
- mat4 MVP = Projection * MV;
- //Передача данных в шейдер
- glUniformMatrix4fv(g_uMV, 1, GL_FALSE, &MV[0][0]);
- glUniformMatrix4fv(g_uMVP, 1, GL_FALSE, &MVP[0][0]);
- glDrawElements(GL_TRIANGLE_STRIP, g_model.indexCount, GL_UNSIGNED_INT, NULL);
- }
- void cleanup()
- {
- if (g_shaderProgram != 0)
- glDeleteProgram(g_shaderProgram);
- if (g_model.vbo != 0)
- glDeleteBuffers(1, &g_model.vbo);
- if (g_model.ibo != 0)
- glDeleteBuffers(1, &g_model.ibo);
- if (g_model.vao != 0)
- glDeleteVertexArrays(1, &g_model.vao);
- }
- bool initOpenGL()
- {
- // Initialize GLFW functions.
- if (!glfwInit())
- {
- cout << "Failed to initialize GLFW" << endl;
- return false;
- }
- // Request OpenGL 3.3 without obsoleted functions.
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- // Create window.
- g_window = glfwCreateWindow(800, 600, "OpenGL Test", NULL, NULL);
- if (g_window == NULL)
- {
- cout << "Failed to open GLFW window" << endl;
- glfwTerminate();
- return false;
- }
- // Initialize OpenGL context with.
- glfwMakeContextCurrent(g_window);
- // Set internal GLEW variable to activate OpenGL core profile.
- glewExperimental = true;
- // Initialize GLEW functions.
- if (glewInit() != GLEW_OK)
- {
- cout << "Failed to initialize GLEW" << endl;
- return false;
- }
- // Ensure we can capture the escape key being pressed.
- glfwSetInputMode(g_window, GLFW_STICKY_KEYS, GL_TRUE);
- // Set callback for framebuffer resizing event.
- glfwSetFramebufferSizeCallback(g_window, reshape);
- return true;
- }
- void tearDownOpenGL()
- {
- // Terminate GLFW.
- glfwTerminate();
- }
- int main()
- {
- // Initialize OpenGL
- //cout << n << ", " << x0 << ", " << dx;
- // Initialize OpenGL
- if (!initOpenGL())
- return -1;
- // Initialize graphical resources.
- bool isOk = init();
- if (isOk)
- {
- GLfloat lastTime = glfwGetTime();
- // Main loop until window closed or escape pressed.
- while (glfwGetKey(g_window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(g_window) == 0)
- {
- GLfloat currentTime = glfwGetTime();
- GLfloat deltaTime = GLfloat(currentTime - lastTime);
- lastTime = currentTime;
- GLfloat delta = 0;
- GLfloat angle = 200.0;
- if (glfwGetKey(g_window, GLFW_KEY_LEFT) || glfwGetKey(g_window, GLFW_KEY_UP)) {
- delta = radians(angle) * deltaTime;
- }
- else if (glfwGetKey(g_window, GLFW_KEY_RIGHT) || glfwGetKey(g_window, GLFW_KEY_DOWN)) {
- delta = -radians(angle) * deltaTime;
- }
- draw(delta);
- // Swap buffers.
- glfwSwapBuffers(g_window);
- // Poll window events.
- glfwPollEvents();
- }
- }
- // Cleanup graphical resources.
- cleanup();
- // Tear down OpenGL.
- tearDownOpenGL();
- return isOk ? 0 : -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement