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;
- GLFWwindow* g_window;
- GLuint g_shaderProgram;
- GLint g_uMVP;
- GLint g_uMV;
- chrono::time_point<chrono::system_clock> g_callTime;
- class Model
- {
- public:
- GLuint vbo;
- GLuint ibo;
- GLuint vao;
- GLsizei indexCount;
- };
- Model g_model;
- 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;"
- ""
- "uniform mat4 u_mv;"
- "uniform mat4 u_mvp;"
- ""
- "out vec3 v_p;"
- "out vec3 v_normal;"
- ""
- "void main()"
- "{"
- " float x = a_position[0];"
- " float z = a_position[1];"
- " float func =0.25 *(1-x* z)* sin(1-x *z); "
- " vec4 pos = vec4(a_position[0], func, a_position[1], 1.0);"
- " gl_Position = u_mvp*pos;"
- " v_p = (u_mv*pos).xyz;"
- " float g_x = -0.25*z*sin(1 - x*z) - 0.25*z*(1 - x*z)*cos(-1 + x*z);"
- " float g_z = -0.25*x*sin(1 - x*z) - 0.25*x*(1 - x*z)*cos(-1 + x*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);
- //Матрицы
- g_uMV = glGetUniformLocation(g_shaderProgram, "u_mv");
- g_uMVP = glGetUniformLocation(g_shaderProgram, "u_mvp");
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- return g_shaderProgram != 0;
- }
- //Получение порядкового номера вершины по индексам i, j
- GLint getNumVertex(int j, int i, int n) {
- return (GLint)(i + j * (n + 1));
- }
- bool createModel() {
- GLint arr_vertex_size = (n + 1) * (n + 1) * 2; //Размерность одномерного массива с вершинами
- GLint arr_index_size = 2 * (n + 1) * n + (n - 1); //Размерность одномерного массива с индексами
- GLfloat* arr_x = new GLfloat[n + 1];//координаты x
- GLfloat* arr_z = new GLfloat[n + 1];//координаты z
- GLfloat* vertices = new GLfloat[arr_vertex_size]; //Создали массив с координатами вершин x, y, z
- GLint* indices = new GLint[arr_index_size]; //Создали массив с индексами обхода
- //Заполнение массива с координатами x
- for (int i = 0; i <= n; i++) {
- arr_x[i] = x0 + i * dx;
- }
- //Заполнение массива с координатами z
- for (int i = 0; i <= n; i++) {
- arr_z[i] = z0 + i * dz;
- }
- //Заполнение итогового массива с вершинами
- int k = 0;
- for (int j = 0; j <= n; j++) {
- for (int i = 0; i <= n; i++) {
- //Координаты
- vertices[k] = arr_x[i];
- k++;
- vertices[k] = arr_z[j];
- k++;
- }
- }
- //Заполнение массив с индексами
- k = 0;
- int j = 0;
- while (j < n) {
- for (int i = 0; i <= n; i++) {
- indices[k] = getNumVertex(j, i, n);
- k++;
- indices[k] = getNumVertex(j + 1, i, n);
- k++;
- }
- if (j < n - 1) {
- indices[k] = getNumVertex(j + 1, n, n);
- k++;
- }
- j++;
- if (j < n) {
- for (int i = n; i >= 0; i--) {
- indices[k] = getNumVertex(j, i, n);
- k++;
- indices[k] = getNumVertex(j + 1, i, n);
- k++;
- }
- if (j < n - 1) {
- indices[k] = getNumVertex(j + 1, 0, n);
- k++;
- }
- j++;
- }
- }
- 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, arr_vertex_size * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- glGenBuffers(1, &g_model.ibo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_model.ibo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, arr_index_size * sizeof(GLint), indices, GL_STATIC_DRAW);
- g_model.indexCount = arr_index_size;
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (const GLvoid*)0);
- 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);
- glEnable(GL_DEPTH_TEST);
- return createShaderProgram() && createModel();
- }
- void reshape(GLFWwindow* window, int width, int height) {
- glViewport(0, 0, width, height);
- }
- 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()
- {
- 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();
- system("pause");
- return isOk ? 0 : -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement