#include //#include #include #pragma comment(lib, "glaux.lib") #include #include #include #include #include #include #include #include #include //#include "SOIL.h" using namespace std; static void error_callback(int error, const char* description) { fputs(description, stderr); } struct Point { double x; double y; double z; }; vector arr; bool flag = true; bool flag_light0 = true; bool flag_light1 = true; bool flag_texture = false; float x_pos = 0; float y_pos = 0; float z_pos = 0; float r_cub = 0.65; float model_x = 0; float model_y = 0; float model_z = 0; float model1_x = 0; float model1_y = 0; float model1_z = 0; GLfloat arg1 = 0; GLfloat arg2 = 0; GLfloat arg3 = 0; float tx = 0.2; float ty = -0.9; float tz = -0.3; GLfloat rx_1 = 0.1; GLfloat ry_1 = 0; GLfloat rz_1_ = 0; GLfloat rx_2 = 0; GLfloat ry_2 = 0.1; GLfloat rz_2 = 0; GLfloat rx_3 = 0; GLfloat ry_3 = 0; GLfloat rz_3 = 0.1; float speed = 0.0003; bool flag_1 = true; int N = 0; float fps = 0; float fps_global_time = 0; GLfloat *vertex; GLfloat *tex; GLuint texture[1]; float pi = 3.1415926535; struct Sphere { float R = 0.15; int m = 10; int n = 15; float ***points; }s, sphere1; void sphere(Sphere *s); void draw_Sphere(Sphere *s); void draw(); void animation(); void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); void scrollCallback(GLFWwindow *window, double xoffset, double yoffset); void Texture(); void load(); void init() { glClearColor(1, 1, 1, 1.0); glEnable(GL_LIGHTING); //glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glEnable(GL_NORMALIZE); } void init_l() { //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); float ambient0[4] = { model_x, model_y, model_z, 1 }; float ambient1[4] = { model1_x, model1_y, model1_z, 1 }; float light0[] = { 1, 0, 1, 0 }; float light0_pos[] = { 0, 1, 0, 0 }; float light1[] = { 1, 0,9, 0,1, 0 }; float light1_pos1[] = { 1, 0, 1, 0 }; GLfloat front_color[] = { 0.5, 0.1, 0.6, 1 }; GLfloat back_color[] = { 0.2, 0.8, 0, 1 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glEnable(GL_LIGHTING); if (flag_light0) { glEnable(GL_LIGHT0); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient0); glMaterialfv(GL_FRONT, GL_AMBIENT, front_color); glLightfv(GL_LIGHT0, GL_AMBIENT, light0); glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); } else glDisable(GL_LIGHT0); if (flag_light1) { glEnable(GL_LIGHT1); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient1); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, back_color); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1); glLightfv(GL_LIGHT1, GL_POSITION, light1_pos1); } else glDisable(GL_LIGHT1); } int main(void) { vertex = new GLfloat[(s.m * s.n + 1) * 3]; tex = new GLfloat[(s.m * s.n + 1) * 2]; GLFWwindow* window; glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, key_callback); glfwSetScrollCallback(window, scrollCallback); sphere(&s); sphere(&sphere1); Texture(); while (!glfwWindowShouldClose(window)) { int screenWidth, screenHeight; glfwGetFramebufferSize(window, &screenWidth, &screenHeight); float ratio = screenWidth / (float)screenHeight; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); init(); init_l(); glViewport(0.0f, 0.0f, screenWidth, screenHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-ratio, ratio, -1.f, 1.f, 1.f * 3, -1.f * 3); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (flag) { animation(); } //glGenTextures(1, &id); if (flag_texture) glEnable(GL_TEXTURE_2D); else glDisable(GL_TEXTURE_2D); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glPushMatrix(); glTranslated(x_pos, y_pos, z_pos); glRotated(arg1, rx_1, ry_1, rz_1_); glRotated(arg2, rx_2, ry_2, rz_2); glRotated(arg3, rx_3, ry_3, rz_3); glEnableClientState(GL_VERTEX_ARRAY); //glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, N/3); glVertexPointer(3, GL_FLOAT, 0, vertex); glTexCoordPointer(2, GL_FLOAT, 0, tex); glDisableClientState(GL_VERTEX_ARRAY); //glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); draw_Sphere(&s); glPopMatrix(); glRotated(arg1, rx_1, ry_1, rz_1_); glRotated(arg2, rx_2, ry_2, rz_2); glRotated(arg3, rx_3, ry_3, rz_3); draw(); glfwSwapBuffers(window); glfwPollEvents(); //FPS fps++; clock_t fps_time = clock(); double time = ((double)fps_time) / CLOCKS_PER_SEC - ((double)fps_global_time) / CLOCKS_PER_SEC; if (time >= 1) { cout << "fps : " << fps << endl; fps_global_time = fps_time; fps = 0; } } glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); } void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS || action == GLFW_REPEAT) { switch (key) { case GLFW_KEY_SPACE: if (flag) { //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); flag = false; } else { flag = true; //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } break; case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, GL_TRUE); break; case GLFW_KEY_ENTER: if (flag_1) flag_1 = false; else { flag_1 = true; } case GLFW_KEY_UP: arg1 -= 10; break; case GLFW_KEY_DOWN: arg1 += 10; break; case GLFW_KEY_LEFT: arg2 += 10; break; case GLFW_KEY_RIGHT: arg2 -= 10; break; case GLFW_KEY_KP_ADD: s.n += 1; break; case GLFW_KEY_KP_SUBTRACT: if (s.n > 1) { s.n -= 1; } break; case GLFW_KEY_MINUS: if (s.m > 1) { s.m -= 1; } break; case GLFW_KEY_EQUAL: s.m += 1; break; case GLFW_KEY_Q: arg3 += 10; break; case GLFW_KEY_E: arg3 -= 10; break; case GLFW_KEY_P: if (speed < 0.005) speed += 0.0001; break; case GLFW_KEY_O: if (speed > 0.0001) speed -= 0.0001; break; case GLFW_KEY_Z: if (flag_light0) { model_x += 0.1; model_y += 0.1; model_z += 0.1; } break; case GLFW_KEY_X: if (flag_light0) { model_x -= 0.1; model_y -= 0.1; model_z -= 0.1; } break; case GLFW_KEY_M: if (flag_light1) { model1_x += 0.1; model1_y += 0.1; model1_z += 0.1; } break; case GLFW_KEY_N: if (flag_light1) { model1_x -= 0.1; model1_y -= 0.1; model1_z -= 0.1; } break; case GLFW_KEY_1: if (flag_light1) { flag_light1 = false; } else flag_light1 = true; break; case GLFW_KEY_0: if (flag_light0) { flag_light0 = false; } else flag_light0 = true; break; case GLFW_KEY_T: if (flag_texture) flag_texture = false; else flag_texture = true; break; case GLFW_KEY_C: ofstream fout; fout.open("./description.txt"); if (fout.is_open()) { fout << x_pos << endl << y_pos << endl << z_pos << endl << tx << endl << ty << endl << tz << endl << model_x << endl << model_y << endl << model_z << endl << model1_x << endl << model1_y << endl << model1_z << endl << s.R << endl << s.m << endl << s.n << endl << speed << endl << r_cub << endl << flag_light0 << endl << flag_light1 << endl << flag_texture << endl << flag_1 << endl << flag; } fout.close(); break; } switch (key) { case GLFW_KEY_L: load(); break; } } sphere(&s); } void scrollCallback(GLFWwindow *window, double xoffset, double yoffset) { if (yoffset > 0) { s.R -= 0.001; r_cub -= 0.001; } if (yoffset < 0) { s.R += 0.001; r_cub += 0.001; } sphere(&s); } void load() { ifstream file("./description.txt"); file >> x_pos >> y_pos >> z_pos; file >> tx >> ty >> tz; file >> model_x >> model_y >> model_z; file >> model1_x >> model1_y >> model1_z; file >> s.R >> s.m >> s.n >> speed >> r_cub; file >> flag_light0 >> flag_light1 >> flag_texture >> flag_1 >> flag; file.close(); } void Texture() { AUX_RGBImageRec *texture1; texture1 = auxDIBImageLoad("C:/Users/Анастасия/Downloads/Paver300.bmp"); glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1->data); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } void sphere(Sphere *s) { //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); s->points = new float**[s->m]; for (int i = 0; i < s->m; i++) { s->points[i] = new float*[s->n]; for (int j = 0; j < s->n; j++) { s->points[i][j] = new float[3]; } } float dy = 0; float dr = 0; float teta = ((pi) / (s->m - 1)); for (int i = 0; i < s->m; i++) { dy = s->R*cos(teta*i); dr = s->R*sin(teta*i); for (int j = 0; j < s->n; ++j) { GLfloat fi = ((2 * pi) / s->n)*j; GLfloat x = dr * cos(fi); GLfloat z = dr * sin(fi); GLfloat y = dy; s->points[i][j][0] = x; s->points[i][j][1] = y; s->points[i][j][2] = z; } } int ind = 0; int ind_t = 0; for (int i = 0; i < s->m - 1; ++i) { for (int j = 0; j < s->n; ++j) { vertex[ind] = s->points[i][j][0]; tex[ind] = s->points[i][j][0]; ind_t++; ind++; vertex[ind] = s->points[i][j][1]; tex[ind] = s->points[i][j][1]; ind++; ind_t++; vertex[ind] = s->points[i][j][2]; ind++; vertex[ind] = s->points[i][(j + 1) % s->n][0]; tex[ind] = s->points[i][(j + 1) % s->n][0]; ind++; ind_t++; vertex[ind] = s->points[i][(j + 1) % s->n][1]; tex[ind] = s->points[i][(j + 1) % s->n][1]; ind++; vertex[ind] = s->points[i][(j + 1) % s->n][2]; ind++; vertex[ind] = s->points[i + 1][j][0]; tex[ind] = s->points[i + 1][j][0]; ind++; ind_t++; vertex[ind] = s->points[i + 1][j][1]; tex[ind] = s->points[i + 1][j][1]; ind_t++; ind++; vertex[ind] = s->points[i + 1][j][2]; ind++; vertex[ind] = s->points[i + 1][(j + 1) % s->n][0]; tex[ind] = s->points[i + 1][(j + 1) % s->n][0]; ind++; ind_t++; vertex[ind] = s->points[i + 1][(j + 1) % s->n][1]; tex[ind] = s->points[i + 1][(j + 1) % s->n][1]; ind_t++; ind++; vertex[ind] = s->points[i + 1][(j + 1) % s->n][2]; ind++; } } N = ind; } void draw_Sphere(Sphere *s) { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); for (int i = 0; i < s->m - 1; ++i) { int k = 0; for (int j = 0; j < s->n; ++j) { glBegin(GL_POLYGON); //glColor3f(abs(10000 * (float(k) / s->n - 1)) / 10000.0, float(i) / s->m, 0.5); k++; glNormal3f(s->points[i][j][0], s->points[i][j][1], s->points[i][j][2]); //glTexCoord2f(s->points[i][j][0], s->points[i][j][1]); //glVertex3f(s->points[i][j][0], s->points[i][j][1], s->points[i][j][2]); glNormal3f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1], s->points[i][(j + 1) % s->n][2]); //glTexCoord2f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1]); //glVertex3f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1], s->points[i][(j + 1) % s->n][2]); glNormal3f(s->points[i + 1][j][0], s->points[i + 1][j][1], s->points[i + 1][j][2]); ////glTexCoord2f(s->points[i + 1][j][0], s->points[i + 1][j][1]); //glVertex3f(s->points[i + 1][j][0], s->points[i + 1][j][1], s->points[i + 1][j][2]); glEnd(); glBegin(GL_POLYGON); //glColor3f(abs(10000 * (float(k) / s->n - 1)) / 10000.0, float(i) / s->m, 0.5); k++; glNormal3f(s->points[i + 1][j][0], s->points[i + 1][j][1], s->points[i + 1][j][2]); //glTexCoord2f(s->points[i + 1][j][0], s->points[i + 1][j][1]); //glVertex3f(s->points[i + 1][j][0], s->points[i + 1][j][1], s->points[i + 1][j][2]); glNormal3f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1], s->points[i][(j + 1) % s->n][2]); //glTexCoord2f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1]); //glVertex3f(s->points[i][(j + 1) % s->n][0], s->points[i][(j + 1) % s->n][1], s->points[i][(j + 1) % s->n][2]); glNormal3f(s->points[i + 1][(j + 1) % s->n][0], s->points[i + 1][(j + 1) % s->n][1], s->points[i + 1][(j + 1) % s->n][2]); //glTexCoord2f(s->points[i + 1][(j + 1) % s->n][0], s->points[i + 1][(j + 1) % s->n][1]); //glVertex3f(s->points[i + 1][(j + 1) % s->n][0], s->points[i + 1][(j + 1) % s->n][1], s->points[i + 1][(j + 1) % s->n][2]); glEnd(); } } return; } void draw() { glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, r_cub, r_cub); glVertex3f(r_cub, r_cub, r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, r_cub, r_cub); glVertex3f(r_cub, -r_cub, r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, -r_cub, r_cub); glVertex3f(-r_cub, -r_cub, r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, -r_cub, r_cub); glVertex3f(-r_cub, r_cub, r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, r_cub, -r_cub); glVertex3f(r_cub, r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, r_cub, -r_cub); glVertex3f(r_cub, -r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, -r_cub, -r_cub); glVertex3f(-r_cub, -r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, -r_cub, -r_cub); glVertex3f(-r_cub, r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, r_cub, r_cub); glVertex3f(r_cub, r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(r_cub, -r_cub, r_cub); glVertex3f(r_cub, -r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, r_cub, r_cub); glVertex3f(-r_cub, r_cub, -r_cub); glEnd(); glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(-r_cub, -r_cub, r_cub); glVertex3f(-r_cub, -r_cub, -r_cub); glEnd(); } void animation() { if ((x_pos + tx * speed >= -r_cub + s.R && x_pos + tx * speed <= r_cub - s.R) && (y_pos + ty * speed >= -r_cub + s.R && y_pos + ty * speed <= r_cub - s.R) && (z_pos + tz * speed >= -r_cub + s.R && z_pos + tz * speed <= r_cub - s.R)) { x_pos += tx * speed; y_pos += ty * speed; z_pos += tz * speed; arr.push_back({ x_pos, y_pos, z_pos }); } else { float nx = 0, ny = 0, nz = 0; if (x_pos <= -r_cub + s.R) { nx = -1; } else if (x_pos >= r_cub - s.R) { nx = 1; } else if (y_pos <= -r_cub + s.R) { ny = -1; } else if (y_pos >= r_cub - s.R) { ny = 1; } else if (z_pos <= -r_cub + s.R) { nz = -1; } else { nz = 1; } tx = tx - 2 * (tx*nx + ny * ty + nz * tz)*nx; ty = ty - 2 * (tx*nx + ny * ty + nz * tz)*ny; tz = tz - 2 * (tx*nx + ny * ty + nz * tz)*nz; x_pos += tx * speed; y_pos += ty * speed; z_pos += tz * speed; arr.push_back({ x_pos, y_pos, z_pos }); } }