#include <glfw3.h>
//#include <GL/glu.h>
#include <glaux.h>
#pragma comment(lib, "glaux.lib")
#include <glaux.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <time.h>
//#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<Point> 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 });
}
}