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);
- //const int Tess_N = 128;
- const GLint n_size = 10;
- //Точка отсчета
- GLfloat x0 = -(GLfloat)n_size / 2.0; //x
- GLfloat z0 = x0;//z
- //Шаг
- GLfloat dx = 0.1; //по x
- GLfloat dz = dx; //по z
- //Количество ячеек
- GLint Tess_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[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] = y;
- 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] = z;
- 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;
- }
- 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[2] = 0.0f;
- m.m_mat[3] = 0.0f;
- m.m_mat[4] = -s;
- m.m_mat[5] = c;
- m.m_mat[6] = 0.0f;
- m.m_mat[7] = 0.0f;
- m.m_mat[8] = 0.0f;
- m.m_mat[9] = 0.0f;
- m.m_mat[10] = 1.0f;
- m.m_mat[11] = 0.0f;
- m.m_mat[12] = 0.0f;
- m.m_mat[13] = 0.0f;
- m.m_mat[14] = 0.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[1] = 0.0f;
- m.m_mat[2] = -s;
- m.m_mat[3] = 0.0f;
- m.m_mat[4] = 0.0f;
- m.m_mat[5] = 1.0f;
- m.m_mat[6] = 0.0f;
- m.m_mat[7] = 0.0f;
- m.m_mat[8] = s;
- m.m_mat[9] = 0.0f;
- m.m_mat[10] = c;
- m.m_mat[11] = 0.0f;
- m.m_mat[12] = 0.0f;
- m.m_mat[13] = 0.0f;
- m.m_mat[14] = 0.0f;
- m.m_mat[15] = 1.0f;
- return m;
- }
- static MyMatrix Projection(float n, float r, float t, float l, float b, float f) {
- MyMatrix m;
- m.m_mat[0] = 2 * n / (r - l);
- m.m_mat[1] = 0.0f;
- m.m_mat[2] = (r + l) / (r - l);
- m.m_mat[3] = 0.0f;
- m.m_mat[4] = 0.0f;
- m.m_mat[5] = 2 * n / (t - b);
- m.m_mat[6] = (t + b) / (t - b);
- m.m_mat[7] = 0.0f;
- m.m_mat[8] = 0.0f;
- m.m_mat[9] = 0.0f;
- m.m_mat[10] = -(f + n) / (f - n);
- m.m_mat[11] = -2 * f * n / (f - n);
- m.m_mat[12] = 0.0f;
- m.m_mat[13] = 0.0f;
- m.m_mat[14] = -1;
- m.m_mat[15] = 0.0f;
- return m;
- }
- const float* get() const { return m_mat; };
- };
- Model g_model;
- float func(float x, float z) {
- return 0.25 * (1 - x * z) * sinf(1 - x * z);
- }
- float d_f_x(float x, float z) {
- return -0.25 * z * sinf(1 - x * z) - 0.25 * z * (1 - x * z) * cosf(-1 + x * z);
- }
- float d_f_z(float x, float z) {
- return -0.25 * x * sinf(1 - x * z) - 0.25 * x * (1 - x * z) * cosf(-1 + x * 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;"
- ""
- "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 = 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;
- }
- GLint getNumVertex(int j, int i, int n) {
- return (GLint)(i + j * (n + 1));
- }
- void generateMesh(GLfloat* vertices, GLint* indices, int Tess_N) {
- int index = 0;
- float sum_x = 0.0f;
- float sum_y = 0.0f;
- float sum_z = 0.0f;
- GLfloat* arr_x = new GLfloat[Tess_N + 1];//координаты x
- GLfloat* arr_z = new GLfloat[Tess_N + 1];//координаты z
- //Заполнение массива с координатами x
- for (int i = 0; i <= Tess_N; i++) {
- arr_x[i] = x0 + i * dx;
- }
- //Заполнение массива с координатами z
- for (int i = 0; i <= Tess_N; i++) {
- arr_z[i] = z0 + i * dz;
- }
- //Заполнение итогового массива с вершинами
- int k = 0;
- for (int j = 0; j <= Tess_N; j++) {
- for (int i = 0; i <= Tess_N; i++) {
- //Координаты
- vertices[k] = arr_x[i];
- k++;
- vertices[k] = arr_z[j];
- k++;
- }
- }
- // Заполняем массив индексов
- k = 0;
- int j = 0;
- while (j < Tess_N) {
- for (int i = 0; i <= Tess_N; i++) {
- indices[k] = getNumVertex(j, i, Tess_N);
- k++;
- indices[k] = getNumVertex(j + 1, i, Tess_N);
- k++;
- }
- if (j < Tess_N - 1) {
- indices[k] = getNumVertex(j + 1, Tess_N, Tess_N);
- k++;
- }
- j++;
- if (j < Tess_N) {
- for (int i = Tess_N; i >= 0; i--) {
- indices[k] = getNumVertex(j, i, Tess_N);
- k++;
- indices[k] = getNumVertex(j + 1, i, Tess_N);
- k++;
- }
- if (j < Tess_N - 1) {
- indices[k] = getNumVertex(j + 1, 0, Tess_N);
- k++;
- }
- j++;
- }
- }
- }
- bool createModel()
- {
- /*GLfloat* vertices = (GLfloat*)malloc(Tess_N * Tess_N * 2 * sizeof(GLfloat));
- GLuint* indices = (GLuint*)malloc(
- (Tess_N - 1) * (Tess_N - 1) * 2 * 3 * sizeof(GLuint)
- );*/
- GLint arr_vertex_size = (Tess_N + 1) * (Tess_N + 1) * 2; //Размерность одномерного массива с вершинами
- GLint arr_index_size = 2 * (Tess_N + 1) * Tess_N + (Tess_N - 1); //Размерность одномерного массива с индексами
- GLfloat* vertices = new GLfloat[arr_vertex_size]; //Создали массив с координатами вершин x, y, z
- GLint* indices = new GLint[arr_index_size]; //Создали массив с индексами обхода
- 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, 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(GLuint), 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);
- /* 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=...
- }
- int max(int a, int b) {
- return a > b ? a : b;
- }
- void draw(/*GLfloat delta_draw*/)
- {
- // Clear color buffer.
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUseProgram(g_shaderProgram);
- glBindVertexArray(g_model.vao);
- float n = 0.01;
- float f = 1000;
- float r = n * tanf(45 / 2);
- float l = -r;
- float t = r;
- float b = -t;
- MyMatrix Projection;
- Projection.Projection(n, r, t, l, b, f);
- ////Проекционная матрица: 45 градусов, соотношение 4:3
- //mat4 Projection = perspective(radians(45.0f), 4.0f / 3.0f, x0, abs(x0));
- MyMatrix T;
- T.translation(x0, 0, z0);
- MyMatrix S;
- int x = x0;
- int z = z0;
- S.scale(1 / max(x, z), 0, 1 / max(x, z));
- MyMatrix R;
- R.xRotation(10);
- MyMatrix MV;
- MV = T * S * R;
- //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));*/
- // R.yRotation(delta_draw);
- // MV = MV * R;
- //}
- //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));*/
- // R.zRotation(delta_draw);
- // MV = MV * R;
- //}
- ////Матрица MV
- //mat4 MV = View * ModelObj;
- //Матрица MVP
- MyMatrix MVP = Projection * MV;
- //Передача данных в шейдер
- glUniformMatrix4fv(g_uMV, 1, GL_FALSE, MV.get());
- glUniformMatrix4fv(g_uMVP, 1, GL_FALSE, MVP.get());
- 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();
- // 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