Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define GL_SILENCE_DEPRECATION //Убираем предупреждения
- #define _USE_MATH_DEFINES
- #include "GLFW/glfw3.h"
- #include <stdlib.h>
- #include <math.h>
- #include <iostream>
- #include <cstring>
- #include <vector>
- #include <ctime>
- #include <sstream>
- #include <fstream>
- #include <time.h>
- #define SQUARE(a) a * a
- #define MODULE_FRICTION_FORCE 10.f
- #define MODULE_PULLING_FORCE 10.5f
- #define WALL_POS_1 15.f
- #define WALL_POS_2 -10.f
- GLint w, h;
- class Point
- {
- public:
- long double x;
- long double y;
- long double z;
- Point( long double pX , long double pY, long double pZ ){
- x = pX;
- y = pY;
- z = pZ;
- }
- friend bool operator == (const Point & c1,
- const Point & c2) {
- return c1.x == c2.x && c1.y == c2.y && c1.z == c2.z;
- }
- };
- class vertex {
- public:
- Point coord = Point(0,0,0);
- Point norm_vector = Point(0,0,0);
- };
- double sqr(double x) {return x * x; }
- class Poly
- {
- public:
- std::vector <vertex> points;
- Point poly_normal = Point(0,0,0);
- Poly(Point p1 , Point p2, Point p3){
- vertex x, y, z;
- x.coord = p1;
- y.coord = p2;
- z.coord = p3;
- points.push_back(x); points.push_back(y); points.push_back(z);
- }
- void CalcNormals()
- {
- Point a = points[0].coord;
- Point b = points[1].coord;
- Point c = points[2].coord;
- long double wrki;
- Point v1 = Point(a.x - b.x, a.y - b.y, a.z - b.z);
- Point v2 = Point(b.x - c.x, b.y - c.y, b.z - c.z);
- wrki = sqrt(sqr(v1.y*v2.z - v1.z * v2.y) + sqr(v1.z * v2.x - v1.x * v2.z) + sqr(v1.x * v2.y - v1.y * v2.x));
- poly_normal = Point((v1.y * v2.z - v1.z * v2.y) / wrki, (v1.z * v2.x - v1.x * v2.z) / wrki, (v1.x * v2.y - v1.y * v2.x) / wrki);
- }
- bool has_vertex(vertex p){
- for (int i = 0; i < points.size(); i++){
- if (points[i].coord == p.coord){
- return true;
- }
- }
- return false;
- }
- };
- using namespace std;
- enum asics{X, Y, Z};
- bool light_on = false;
- bool normal_flag = false;
- bool animation = false;
- float move_X = 0.0f;
- float move_Y = 0.0f;
- float move_Z = 0.0f;
- float rot_X = 0.0f;
- float rot_Y = 0.0f;
- float rot_Z = 0.0f;
- GLuint box;
- GLuint fig;
- GLuint norm;
- int current_asic = X;
- int change_height = 100;
- int num_poly = 6;
- float mode = GL_LINE_LOOP;
- vector < vector <Point> > figure;
- vector < Poly > poly_fig;
- void resize_callback(GLFWwindow *window, int new_w, int new_h) {
- w = new_w, h = new_h;
- }
- void drawcube(){
- glBegin(GL_QUADS);
- glColor3f(0.0,1.0,0.0);
- glVertex3f( 1.0, 1.0,-1.0);
- glVertex3f(-1.0, 1.0,-1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glVertex3f( 1.0, 1.0, 1.0);
- glEnd();
- glBegin(GL_QUADS);
- glColor3f(1.0,0.5,0.0);
- glVertex3f( 1.0,-1.0, 1.0);
- glVertex3f(-1.0,-1.0, 1.0);
- glVertex3f(-1.0,-1.0,-1.0);
- glVertex3f( 1.0,-1.0,-1.0);
- glEnd();
- glBegin(GL_QUADS);
- glColor3f(1.0,0.0,0.0);
- glVertex3f( 1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glVertex3f(-1.0,-1.0, 1.0);
- glVertex3f( 1.0,-1.0, 1.0);
- glEnd();
- glBegin(GL_QUADS);
- glColor3f(1.0,1.0,0.0);
- glVertex3f( 1.0,-1.0,-1.0);
- glVertex3f(-1.0,-1.0,-1.0);
- glVertex3f(-1.0, 1.0,-1.0);
- glVertex3f( 1.0, 1.0,-1.0);
- glEnd();
- glBegin(GL_QUADS);
- glColor3f(0.0,0.0,1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0,-1.0);
- glVertex3f(-1.0,-1.0,-1.0);
- glVertex3f(-1.0,-1.0, 1.0);
- glEnd();
- glBegin(GL_QUADS);
- glColor3f(1.0,0.0,1.0);
- glVertex3f( 1.0, 1.0,-1.0);
- glVertex3f( 1.0, 1.0, 1.0);
- glVertex3f( 1.0,-1.0, 1.0);
- glVertex3f( 1.0,-1.0,-1.0);
- glEnd();
- }
- void create_list_box(){ //Оптимизация 3 дисплейный список
- box = glGenLists(1);
- glNewList( box, GL_COMPILE );
- drawcube();
- glEndList();
- }
- void connect_Poly(vector <Point> cir1, vector <Point> cir2){
- for (int j = 0; j < cir1.size(); j+=num_poly ){
- float near = j + num_poly;
- if (j + num_poly >= cir1.size()){ near = 0; }
- Poly tr1 = Poly(cir1[j], cir2[j], cir2[near]);
- tr1.CalcNormals();
- if (!isnan(tr1.poly_normal.x)) poly_fig.push_back(tr1);
- Poly tr2 = Poly(cir1[near], cir1[j], cir2[near]);
- tr2.CalcNormals();
- if (!isnan(tr2.poly_normal.x)) poly_fig.push_back(tr2);
- }
- }
- void draw_normals(){
- for (int j = 0; j < poly_fig.size(); j++){
- Poly trinagle = poly_fig[j];
- for (int i = 0; i < trinagle.points.size(); i++){
- vertex triangle_vert = trinagle.points[i];
- glColor3f(1,1,1);
- glBegin(GL_LINES);
- glVertex3f(triangle_vert.coord.x, triangle_vert.coord.y, triangle_vert.coord.z);
- glVertex3f(triangle_vert.coord.x + triangle_vert.norm_vector.x, triangle_vert.coord.y + triangle_vert.norm_vector.y, triangle_vert.coord.z + triangle_vert.norm_vector.z);
- glEnd();
- }
- }
- }
- void draw_poly(){
- for (int j = 0; j < poly_fig.size(); j++){
- Poly triangle = poly_fig[j];
- glColor3f(0,1,0);
- glBegin(mode);
- for (int v = 0; v < triangle.points.size(); v++){
- glNormal3f(triangle.points[v].norm_vector.x, triangle.points[v].norm_vector.y, triangle.points[v].norm_vector.z);
- glVertex3f(triangle.points[v].coord.x, triangle.points[v].coord.y, triangle.points[v].coord.z);
- }
- glEnd();
- }
- }
- void countNormal(vertex &x){
- vector < Poly > all_poly_with_cur_vert;
- long double x_normal = 0.f;
- long double y_normal = 0.f;
- long double z_normal = 0.f;
- for (int i = 0; i < poly_fig.size(); i++){
- Poly triangle = poly_fig[i];
- if (triangle.has_vertex(x)){
- all_poly_with_cur_vert.push_back(triangle);
- }
- }
- for (int i = 0; i < all_poly_with_cur_vert.size(); i++){
- Poly tmp = all_poly_with_cur_vert[i];
- x_normal += tmp.poly_normal.x;
- y_normal += tmp.poly_normal.y;
- z_normal += tmp.poly_normal.z;
- }
- x_normal = x_normal / double(all_poly_with_cur_vert.size());
- y_normal = y_normal / double(all_poly_with_cur_vert.size());
- z_normal = z_normal / double(all_poly_with_cur_vert.size());
- x.norm_vector.x = x_normal;
- x.norm_vector.y = y_normal;
- x.norm_vector.z = z_normal;
- }
- void rebuild(){
- poly_fig.clear();
- int i = 0;
- for (; i < figure.size() - change_height; i+= change_height){
- connect_Poly(figure[i], figure[i+change_height]);
- }
- connect_Poly(figure[i], figure[figure.size() - 1]);
- for (int i = 0; i < poly_fig.size(); i++){
- countNormal(poly_fig[i].points[0]);
- countNormal(poly_fig[i].points[1]);
- countNormal(poly_fig[i].points[2]);
- }
- }
- void create_list_fig(){
- glDeleteLists(fig, 1);
- fig = glGenLists(1);
- rebuild();
- glNewList( fig , GL_COMPILE );
- draw_poly();
- glEndList();
- glDeleteLists(norm, 1);
- norm = glGenLists(1);
- glNewList( norm , GL_COMPILE );
- draw_normals();
- glEndList();
- }
- void create_circles(float a, float b, float c, float height){
- vector <Point> circle;
- float level = 1 + ( SQUARE(height) / SQUARE(c) );
- for(float i = 0; i <= 2* M_PI; i+=0.1f ) {
- float high_part_drob = (a*a) * (b*b) * level;
- float low_part_drob = ((b*b) * (cosf(i) * cosf(i))) + ((a*a) * (sinf(i) * sinf(i))) ;
- float r = sqrtf( high_part_drob / low_part_drob );
- circle.push_back(Point(cosf( i ) * r, height, sinf( i ) * r));
- }
- figure.push_back(circle);
- }
- void create_fig(float a, float b, float c, float height_low, float height_high){
- float h = height_low;
- while (h <= height_high){
- create_circles(a, b, c, h);
- h+=0.008f;
- }
- create_circles(a, b, c, h);
- }
- float begin_s = 0.0f;
- bool pos = true;
- bool move_1(float result_force_module){
- if (begin_s <= WALL_POS_1){
- move_X -= result_force_module;
- begin_s += result_force_module;
- return true;
- }
- return false;
- }
- bool move_2(float result_force_module){
- if (begin_s >= WALL_POS_2){
- move_X += result_force_module;
- begin_s -= result_force_module;
- return false;
- }
- return true;
- }
- void move_fig_to_wall(){
- float result_force_module = MODULE_PULLING_FORCE - MODULE_FRICTION_FORCE;
- if (result_force_module <= 0){
- glCallList(fig);
- }
- else {
- if (pos) pos = move_1(result_force_module);
- else pos = move_2(result_force_module);
- }
- glCallList(fig);
- }
- void renderScene(void) {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- glTranslated(-5.0f, 0.0f,-6.0f);
- glCallList(box);
- glLoadIdentity();
- glTranslated(0.0f, 0.0f, -2.0f);
- glTranslated(move_X, move_Y, move_Z);
- glRotatef(rot_Z, 0, 0, 1);
- glRotatef(rot_X, 1, 0, 0);
- glRotatef(rot_Y, 0, 1, 0);
- if (animation) move_fig_to_wall();
- if (!animation) glCallList(fig);
- if(normal_flag) glCallList(norm);
- glLoadIdentity();
- }
- void Save_scene(){
- std::ofstream st("scene.txt");
- st << rot_X << endl;
- st << rot_Y << endl;
- st << rot_Z << endl;
- st << move_X << endl;
- st.close();
- }
- void load_scene(){
- std::ifstream st("scene.txt");
- float p;
- int pos = 0;
- while(st){
- st >> p;
- if (pos == 0){rot_X = p;}
- if (pos == 1){rot_Y = p;}
- if (pos == 2){rot_Z = p;}
- if (pos == 3){move_X = p;}
- pos++;
- }
- cout << rot_X << rot_Y << animation << light_on;
- st.close();
- }
- void light_enable()
- {
- glShadeModel(GL_SMOOTH);
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); //Оптимизация 2 Отключение двухстороннего освещения
- GLfloat amb[] = {.8f, .8f, .8f, 1.f};
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
- GLfloat lightPos[] = {0.f, 0, 0.f, -10.f};
- glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
- GLfloat light_amb[] = {.75f, .75f, .75f, 1.f};
- glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb);
- GLfloat light_diff[] = {.75f, .75f, .75f, 1.f};
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff);
- GLfloat light_spec[] = {7.5f, 7.5f, 7.5f, 1.f};
- glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec);
- glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5f);
- glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, .5f);
- glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, .01f);
- }
- void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
- if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
- glfwSetWindowShouldClose(window, GL_TRUE);
- }
- else if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (num_poly == 16) {}
- else{ num_poly++; create_list_fig(); }
- }
- else if (key == GLFW_KEY_N && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if(normal_flag) { normal_flag = false; }
- else { normal_flag = true; };
- }
- else if (key == GLFW_KEY_X && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- current_asic = X;
- }
- else if (key == GLFW_KEY_Y && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- current_asic = Y;
- }
- else if (key == GLFW_KEY_Z && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- current_asic = Z;
- }
- else if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (change_height == 1) {}
- else { change_height = change_height - 1; create_list_fig();}
- }
- else if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- change_height = change_height + 1; create_list_fig();
- }
- else if (key == GLFW_KEY_M && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (mode == GL_TRIANGLES){ mode = GL_LINE_LOOP; create_list_fig();}
- else { mode = GL_TRIANGLES; create_list_fig();}
- }
- else if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (light_on){
- glDisable(GL_LIGHTING);
- glDisable(GL_LIGHT0);
- light_on = false;
- }
- else {
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- light_enable();
- light_on = true;
- }
- }
- else if (key == GLFW_KEY_F && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (animation) { animation = false; }
- else { animation = true; }
- }
- else if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (num_poly == 1) {}
- else {num_poly--; create_list_fig();}
- }
- else if (key == GLFW_KEY_LEFT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (current_asic == Z) { move_Z-= 0.1f; }
- if (current_asic == X) { move_X-= 0.1f; }
- if (current_asic == Y) { move_Y-= 0.1f; }
- }
- else if (key == GLFW_KEY_RIGHT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (current_asic == Z) { move_Z+= 0.1f; }
- if (current_asic == X) { move_X+= 0.1f; }
- if (current_asic == Y) { move_Y+= 0.1f; }
- }
- else if (key == GLFW_KEY_UP && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (current_asic == Z) { rot_Z+= 0.4f; }
- if (current_asic == X) { rot_X+= 0.4f; }
- if (current_asic == Y) { rot_Y+= 0.4f; }
- }
- else if (key == GLFW_KEY_DOWN && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (current_asic == Z) { rot_Z-= 0.4f; }
- if (current_asic == X) { rot_X-= 0.4f; }
- if (current_asic == Y) { rot_Y-= 0.4f; }
- }
- else if (key == GLFW_KEY_P && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- if (current_asic == Z) { rot_Z-= 0.4f; }
- if (current_asic == X) { rot_X-= 0.4f; }
- if (current_asic == Y) { rot_Y-= 0.4f; }
- }
- else if (key == GLFW_KEY_G && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- Save_scene();
- }
- else if (key == GLFW_KEY_B && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
- load_scene();
- }
- }
- void projection(GLint width, GLint height) {
- GLfloat k = 0.07;
- GLfloat project[] = {
- 1.f, 0.f, 0.f, 0.0f,
- 0.f, 1.f, 0.f, 0.f,
- 0.f, 0.f, 1.f, 0.0f,
- 0.f, 0.f, 0.f, 1.f};
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMultMatrixf(project);
- glOrtho(-w * k / 2, w * k / 2, -h * k / 2,
- h * k / 2, -(w * k + h * k) / 4, (w * k + h * k) / 4);
- }
- int main(int argc, char **argv) {
- float a = 3.0f;
- float b = 2.0f;
- float c = 0.1f;
- float z_low = -5.0f;
- float z_high = 5.0f;
- if (!glfwInit()) {
- fprintf(stderr, "Failed to initialize GLFW\n");
- exit(EXIT_FAILURE);
- }
- GLFWwindow
- *window = glfwCreateWindow(800, 800, "Lab6", nullptr, nullptr);
- if (!window) {
- fprintf(stderr, "Failed to open GLFW window.\n");
- glfwTerminate();
- exit(EXIT_FAILURE);
- }
- glfwMakeContextCurrent(window);
- glfwSetKeyCallback(window, key_callback);
- glfwSetWindowSizeCallback(window, resize_callback);
- glfwGetFramebufferSize(window, &w, &h);
- create_fig(a, b, c, z_low, z_high);
- create_list_box();
- create_list_fig();
- glEnable(GL_DEPTH_TEST); // Оптимизация 1 отключение теста глубины
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_NORMALIZE);
- //glEnable(GL_CULL_FACE); //Оптимизация 4 отброс невидимых граней
- while (!glfwWindowShouldClose(window)) {
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- glClear(GL_DEPTH_BUFFER_BIT);
- glViewport(0, 0, w, h);
- projection(w, h);
- glMatrixMode(GL_MODELVIEW);
- renderScene();
- glfwPollEvents();
- glfwSwapBuffers(window);
- }
- glfwDestroyWindow(window);
- glfwTerminate();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement