#include<windows.h>
#include<stdio.h>
/* Główna bibloteka OpenGL */
#include<GL/gl.h>
/* Biblioteka GLUT */
#include<GL/glut.h>
#include<math.h>
/* Deklaracje funkcji narzędziowych */
void DrawScene(void);
void DrawSceneAxes(void);
void InitOpenGL(void);
void ReshapeWindow(int width, int height);
void drawFractal(GLclampf a,GLclampf x, GLclampf y, GLfloat z,GLshort depth);
void drawTetraedr(GLclampf a, GLclampf x, GLclampf y, GLfloat z, GLclampf r, GLclampf g, GLclampf b);
void MouseFunc(int button, int state, int x, int y);
void MouseMotion(GLsizei x, GLsizei y);
/* Deklaracja globalnych zmiennych */
int x=1,y=1;
float light_pos[]={0.0,0.0,0.0};
GLfloat viewer_pos[] = { 10.0, 0.0, 0.0 };
GLfloat R = 10.0f;
GLfloat thetax = 0.0f;
GLfloat thetay = 0.0f;
GLfloat thetax1 = 0.0f;
GLfloat thetay1 = 0.0f;
GLfloat pixels2angle = 0.0;
GLint lbutton_status = 0;
GLint rbutton_status = 0;
GLint x_last_pos = 0;
GLint y_last_pos = 0;
GLint x_delta = 0;
GLint y_delta = 0;
int mainWindow;
///////////////////////
GLshort Depth = 1.0;///
///////////////////////
struct vertex_coord {
GLfloat x;
GLfloat y;
GLfloat z;
};
struct vertex_coord w1;
struct vertex_coord w2;
struct vertex_coord w3;
struct vertex_coord w4;
void mKeyboard(unsigned char c, int /*x*/,int /*y*/);
/* Funkcja main */
int main(int argc, char **argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1000, 690);
glutInitWindowPosition(370,10);
mainWindow = glutCreateWindow("ZADANIE DO DOMU :)");
if(mainWindow == 0){
puts("Nie mozna stworzyc okna!!!\nWyjscie z programu.\n");
exit(-1);
}
glutSetWindow(mainWindow);
InitOpenGL();
glutDisplayFunc(DrawScene);
glutReshapeFunc(ReshapeWindow);
glutMouseFunc(MouseFunc);
glutMotionFunc(MouseMotion);
glutKeyboardFunc(mKeyboard);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return(0);
}
void DrawScene(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer_pos[0],viewer_pos[1],viewer_pos[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
if(!x)
{
InitOpenGL();
}
DrawSceneAxes();
if(lbutton_status == 1){
if(x){
thetax += x_delta*pixels2angle/50;
thetay += y_delta*pixels2angle/50;
}
else{
thetax1 += x_delta*pixels2angle/50;
thetay1 += y_delta*pixels2angle/50;
}
}
if(rbutton_status == 1){
R+=(y_delta/2);
}
viewer_pos[0] = abs(R)*cos(thetax)*cos(thetay);
viewer_pos[1] = abs(R)*sin(thetay);
viewer_pos[2] = abs(R)*cos(thetay)*sin(thetax);
light_pos[0] = R*cos(thetax1)*cos(thetay1);
light_pos[1] = R*sin(thetay1);
light_pos[2] = R*cos(thetay1)*sin(thetax1);
printf("%lf %lf %lf \n",viewer_pos[0] ,viewer_pos[1] ,viewer_pos[2] );
//printf("[%lf %lf %lf] \n",light_pos[0] ,light_pos[1] ,light_pos[2] );
drawFractal(5.0f,0.0f,3.0f,0.0f,Depth);
//DrawSierp(0,0,0,5, 4);
glFlush();
glutSwapBuffers();
}
void drawTetraedr(GLclampf a, GLclampf x, GLclampf y, GLfloat z, GLclampf r, GLclampf g, GLclampf b) {
GLfloat h = (a * sqrt(3.0f))/2;
GLfloat h1 = h/3;
GLfloat h2 = 2*h1;
glBegin(GL_TRIANGLE_STRIP);
glColor3f(0, 0.9, 1);
w1.x=x;
w1.y=y;
w1.z=z;
w2.x= x + 0.5*a;
w2.y=y-h;
w2.z=z-h1;
w3.x=x - 0.5*a ;
w3.y=y-h;
w3.z=z-h1;
w4.x= x;
w4.y=y - h;
w4.z=z + h2;
glVertex3f(x, y, z);
glVertex3f(x - 0.5*a, y-h, z-h1);
glVertex3f(x + 0.5*a, y-h, z-h1);
glVertex3f(x, y - h, z + h2);
glVertex3f(x, y, z);
glVertex3f(x - 0.5*a, y-h, z-h1);
glEnd();
}
void drawFractal(GLclampf a,GLclampf x, GLclampf y, GLfloat z,GLshort depth){
if(depth == 1) {
drawTetraedr(a, x, y, z, 1.0f , 1.0f, 1.0f);
} else {
GLfloat h = (a * sqrt(3.0f))/2;
GLfloat h1 = h/3;
GLfloat h2 = 2*h1;
GLfloat mh = ((0.5*a) * sqrt(3.0f))/2;
GLfloat mh1 = mh/3;
GLfloat mh2 = (2*mh)/3;
drawFractal(0.5*a,x,y,z,depth-1);
drawFractal(0.5*a,x,y-mh,z+h2-mh2,depth-1);
drawFractal(0.5*a,x-0.25*a,y-mh,z-h1+mh1,depth-1);
drawFractal(0.5*a,x+0.25*a,y-mh,z-h1+mh1,depth-1);
}
}
void MouseFunc(int button, int state, int x, int y){
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
x_last_pos = x;
y_last_pos = y;
lbutton_status = 1;
} else {
lbutton_status = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){
x_last_pos = x;
y_last_pos = y;
rbutton_status = 1;
} else {
rbutton_status = 0;
}
}
void MouseMotion(GLsizei x, GLsizei y){
x_delta = x - x_last_pos;
y_delta = y - y_last_pos;
x_last_pos = x;
y_last_pos = y;
glutPostRedisplay();
}
void DrawSceneAxes(void)
{
// Definiujemy nowy typ jako tablicę 3-elementową
typedef float pt3d[3];
// Początek i koniec osi X
pt3d x_beg = { -10.0f, 0.0f, 0.0f };
pt3d x_end = { 10.0f, 0.0f, 0.0f };
// Poczatek i koniec osi Y
pt3d y_beg = { 0.0f, -10.0f, 0.0f };
pt3d y_end = { 0.0f, 10.0f, 0.0f };
// Początek i koniec osi Z
pt3d z_beg = { 0.0f, 0.0f, -10.0f };
pt3d z_end = { 0.0f, 0.0f, 10.0f };
// Rysujemy osie
glBegin(GL_LINES);
// Czerwony kolor dla osi X
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fv(x_beg);
glVertex3fv(x_end);
// Zielony kolor dla osi Y
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fv(y_beg);
glVertex3fv(y_end);
// Niebieski kolor dla osi Z
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fv(z_beg);
glVertex3fv(z_end);
glEnd();
}
void InitOpenGL(void){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// współczynniki ka =[kar,kag,ka dla światła otoczenia
GLfloat mat_ambient[] = {1.0, 1.0, 1.0, 1.0};
// współczynniki kd =[kdr,kdg,kd światła rozproszonego
GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
// współczynniki ks =[ksr,ksg,ks dla światła odbitego
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
// współczynnik n opisujący połysk powierzchni
GLfloat mat_shininess = {20.0};
//światło 1
// składowe intensywności świecenia źródła światła otoczenia// Ia = [Iar,Iag,Iab
GLfloat light_ambient1[] = {2.0, 0.0, 0.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie dyfuzyjne Id = [Idr,Idg,Id
GLfloat light_diffuse1[] = {2.0, 0.0, 0.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie kierunkowe Is = [Isr,Isg,Is
GLfloat light_specular1[] = {2.0, 0.0, 0.0, 1.0};
//światło 2
// składowe intensywności świecenia źródła światła otoczenia// Ia = [Iar,Iag,Iab
GLfloat light_ambient2[] = {0.0, 0.1, 0.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie dyfuzyjne Id = [Idr,Idg,Id
GLfloat light_diffuse2[] = {0.0, 2.0, 0.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie kierunkowe Is = [Isr,Isg,Is
GLfloat light_specular2[] = {0.0, 2.0, 0.0, 1.0};
//światło 3
// składowe intensywności świecenia źródła światła otoczenia// Ia = [Iar,Iag,Iab
GLfloat light_ambient3[] = {0.0, 0.0, 0.1, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie dyfuzyjne Id = [Idr,Idg,Id
GLfloat light_diffuse3[] = {0.0, 0.0, 2.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie kierunkowe Is = [Isr,Isg,Is
GLfloat light_specular3[] = {0.0, 0.0, 2.0, 1.0};
//światło 4
// składowe intensywności świecenia źródła światła otoczenia// Ia = [Iar,Iag,Iab
GLfloat light_ambient4[] = {0.0, 0.1, 0.1, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie dyfuzyjne Id = [Idr,Idg,Id
GLfloat light_diffuse4[] = {0.0, 1.0, 1.0, 1.0};
// składowe intensywności świecenia źródła światła powodującego// odbicie kierunkowe Is = [Isr,Isg,Is
GLfloat light_specular4[] = {0.0, 1.0, 1.0, 1.0};
GLfloat light_position1[] = {0.0 + light_pos[0],10.0 + light_pos[1],0.0 + light_pos[2], 0.0};
GLfloat light_position2[] = {0.0 + light_pos[0],3.0 + light_pos[1],-9.0 + light_pos[2], 0.0};
GLfloat light_position3[] = {8.3 + light_pos[0],3.0 + light_pos[1],4.5 + light_pos[2], 0.0};
GLfloat light_position4[] = {-7.8 +light_pos[0],4.5 + light_pos[1],4.3 + light_pos[2], 0.0};
// składowa stała ds dla modelu zmian oświetlenia w funkcji // odległości od źródła
GLfloat att_constant = {1.0};
// składowa liniowa dl dla modelu zmian oświetlenia w funkcji // odległości od źródła
GLfloat att_linear = {0.05};
// składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji// odległości od źródła
GLfloat att_quadratic = {0.001};
// Ustawienie parametrów materiału i źródła światła
// Ustawienie patrametrów materiału
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
// Ustawienie parametrów źródła
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient1);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse1);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position1);
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse2);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular2);
glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
glLightfv(GL_LIGHT2, GL_AMBIENT, light_ambient3);
glLightfv(GL_LIGHT2, GL_DIFFUSE, light_diffuse3);
glLightfv(GL_LIGHT2, GL_SPECULAR, light_specular3);
glLightfv(GL_LIGHT2, GL_POSITION, light_position3);
glLightfv(GL_LIGHT3, GL_AMBIENT, light_ambient4);
glLightfv(GL_LIGHT3, GL_DIFFUSE, light_diffuse4);
glLightfv(GL_LIGHT3, GL_SPECULAR, light_specular4);
glLightfv(GL_LIGHT3, GL_POSITION, light_position4);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, att_constant);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, att_linear);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, att_quadratic);
glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, att_constant);
glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, att_linear);
glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, att_quadratic);
glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, att_constant);
glLightf(GL_LIGHT3, GL_LINEAR_ATTENUATION, att_linear);
glLightf(GL_LIGHT3, GL_QUADRATIC_ATTENUATION, att_quadratic);
// Ustawienie opcji systemu oświetlania sceny
glShadeModel(GL_SMOOTH); // właczenie łagodnego cieniowania
glEnable(GL_LIGHTING); // właczenie systemu oświetlenia sceny
glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3);
glEnable(GL_DEPTH_TEST); // włączenie mechanizmu z-bufora
}
void ReshapeWindow(int width, int height){
pixels2angle = 360.0f/(float)width;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, 1.0, 1.0, 40.0);
if(width <= height)
glViewport(0, (height - width)/2, width, width);
else
glViewport((width - height)/2, 0, height, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mKeyboard(unsigned char c, int /*x*/,int /*y*/)
{
switch(c)
{
case 45:
if(Depth > 1)
Depth--;
DrawScene();
printf("%d",Depth);
break;
case 43:
if(Depth < 10)
Depth++;
DrawScene();
printf("%d",Depth);
break;
case 49:
if(x)x=0;
else
x=1;DrawScene();
break;
case 50://?
if(y)
{ glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3);
y=0;
}
else
{
glDisable(GL_LIGHT0); // włączenie źródła o numerze 0
glDisable(GL_LIGHT1);
glDisable(GL_LIGHT2);
glDisable(GL_LIGHT3);
y=1;
}
DrawScene();
break;
case 27:
printf("wyjscie z programu");
exit(-1);
default:
printf("%d - %c\n",c,c);
}
}
Pytanie brzmi, dlaczego jak ruszam obserwatorem wzdłuż osi Y ( przy przejściu na 2gą stronę czworościanu) tworzy się nagle przeskok , i jak to naprawić ? Proszę o pomoc