|
Создание компьютерной графики при помощи OpenGL
Создание компьютерной графики при помощи OpenGL
1. Напишите программу вывода графика функции y= tg (x)+5*cos (x), с помощью точек, а затем с помощью линий. 1.1 С помощью точек Решение: #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <gl\glaux.h> #include <math.h> GLint windW, windH; void CALLBACK Reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-15,15,-15,15); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw(void) { glClearColor(1.0,1.0,1.0,1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_LINES); glColor3ub(190,190,190); for (int i=-4; i<=4; i++) { glVertex2f(float(i), -6);//явное преобразование типа glVertex2f(float(i), 15); } for (i=-6; i<=15; i++) { glVertex2f(-4, float(i)); glVertex2f(4, float(i)); } glEnd(); glColor3ub(0,0,0); glBegin(GL_LINES); glVertex2f (-5, 0); glVertex2f(5, 0); glVertex2f(0,16); glVertex2f(0,-7); glEnd(); glPointSize(2); glBegin(GL_POINTS); glColor3ub(0,0,255); int n; double a,b,dx,x,y; a=-1.415; b=1.5; n=20; dx=(b-a)/(n-1); x=a; y=0; for (i=1; i<=n; i++) { y=float(tan(x)+5*cos(x)); glVertex2d (x, y); x=x+dx; } glEnd(); glFinish(); auxSwapBuffers(); } void main(int argc, char **argv) AUX_DOUBLE); auxInitWindow("v11_01_1"); glTranslated(0,-4,0); auxReshapeFunc(Reshape); auxMainLoop(Draw); Результат: 2.2 с помощью линий Решение: #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <gl\glaux.h> #include <math.h> GLint windW, windH; void CALLBACK Reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-15,15,-15,15); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw(void) { glClearColor(1.0,1.0,1.0,1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_LINES); glColor3ub(190,190,190); for (int i=-4; i<=4; i++) { glVertex2f(float(i), -6);//явное преобразование типа glVertex2f(float(i), 15); } for (i=-6; i<=15; i++) { glVertex2f(-4, float(i)); glVertex2f(4, float(i)); } glEnd(); glColor3ub(0,0,0); glBegin(GL_LINES); glVertex2f (-5, 0); glVertex2f(5, 0); glVertex2f(0,16); glVertex2f(0,-7); glEnd(); glBegin(GL_LINE_STRIP); glColor3ub(0,0,255); int n; double a,b,dx,x,y; a=-1.415; b=1.5; n=100; dx=(b-a)/(n-1); x=a; y=0; for (i=1; i<=n; i++) { y=float(tan(x)+5*cos(x)); glVertex2d (x, y); x=x+dx; } glEnd(); glFinish(); auxSwapBuffers(); } void main(int argc, char **argv) AUX_DOUBLE); auxInitWindow("v11_01_1"); glTranslated(0,-4,0); auxReshapeFunc(Reshape); auxMainLoop(Draw); Результат: 2. Нарисуйте каркас призмы, в основании которой лежит правильный 14-угольник Решение: //v11_02 #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include <math.h> void CALLBACK resize (int width, int height) { glViewport (0,0,width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); glOrtho(-15,15,-10,10, -10,20); gluLookAt(1,-1,1, 0,0,0, 0,0,1); glMatrixMode(GL_MODELVIEW); } void CALLBACK display (void) { GLUquadricObj *quadObj; quadObj = gluNewQuadric(); glClearColor(1.0,1.0,1.0,1); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3d(0,0,1); // каркас gluQuadricDrawStyle(quadObj, GLU_SILHOUETTE); //призма в основании которой лежит правильный 14-угольник gluCylinder(quadObj, 2, 2, 5, 14, 14); glBegin(GL_LINES); glColor3ub(0, 0, 0); glVertex2f(6, 0); glVertex2f(-6, 0); glVertex2f(0, 6); glVertex2f(0, -6); glVertex3f(0, 0, 0); glVertex3f(0, 0, 8); for (int i=-5; i<=5; i++) { if (i!=0) { glColor3ub(190,190,190); glVertex2f(float(i), -5); glVertex2f(float(i), 5); } } for (i=-5; i<=5; i++) { if (i!=0) { glColor3ub(190,190,190); glVertex2f(-5, float(i)); glVertex2f(5, float(i)); } } glEnd(); glFinish(); auxSwapBuffers(); } void main () auxInitPosition (100,100,800,600); auxInitDisplayMode (AUX_RGB Результат: 3. Напишите программу вывода графика функции x=2*sin(z)*cos(y)-3*tg(y) используя алгоритм плавающего горизонта. Модифицируйте программу таким образом, чтобы поверхность состояла из четырехугольников Решение: #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <gl\glaux.h> #include <math.h> // запретить вывод предупреждений о преобразовании данных #pragma warning(disable: 4305) // MIPS #pragma warning(disable: 4244) // MIPS GLint windW, windH; void CALLBACK Reshape(int width, int height) { windW = (GLint)width; windH = (GLint)height; } int alpha=0, beta=0; void CALLBACK Key_LEFT(void) { alpha -= 5; } void CALLBACK Key_RIGHT(void) { alpha += 5; } void CALLBACK Key_UP(void) { beta += 5; } void CALLBACK Key_DOWN(void) { beta -= 5; } void CALLBACK InitViewport(int x, int y, int width, int height) { glViewport(x, y, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-windW,windW, -windH,windH, windH/1000,windH*1000); gluLookAt(0,0,windH, 0,0,0, 1,0,0); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw(void) { float x,y,z; float d=10; InitViewport(0,0, windW, windH); glColor3d(0,1,0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for (y=-windH/1.3; y<=windH/1.3; y+=10) {glBegin(GL_QUADS); for (z=-windW/1.3; z<=windW/1.3; z+=10) { x=2*sin(z)*cos(y)-3*tan(y); glVertex3f(x,y,z); glVertex3f(x,y+d,z); x=2*sin(z+d)*cos(y+d)-3*tan(y+d); glVertex3f(x,y+d,z+d); glVertex3f(x,y,z+d); } glEnd(); } glFinish(); } void CALLBACK Turn(void) glClear(GL_COLOR_BUFFER_BIT void main(int argc, char **argv) { windW = 800; windH = 600; auxInitPosition(0, 0, windW, windH); auxInitDisplayMode(AUX_RGB | AUX_DEPTH | AUX_DOUBLE); if(auxInitWindow("v11_03") == GL_FALSE) { auxQuit(); } auxExposeFunc((AUXEXPOSEPROC)Reshape); auxReshapeFunc((AUXRESHAPEPROC)Reshape); auxIdleFunc(Turn); auxKeyFunc(AUX_LEFT, Key_LEFT); auxKeyFunc(AUX_RIGHT, Key_RIGHT); auxKeyFunc(AUX_UP, Key_UP); auxKeyFunc(AUX_DOWN, Key_DOWN); auxMainLoop(Turn); } Результат: 4. Напишите программу вывода вращающего тора относительно своей оси x, с одновременным движением по следующей траектории z=sin(y) Решение: //v11_04 #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include <math.h> int flag=1; void CALLBACK resize (int width, int height) { glViewport (0,0,width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); glOrtho(-15,15,-10,10, -10,20); gluLookAt(1,-1,1, 0,0,0, 0,0,1); glMatrixMode(GL_MODELVIEW); } void CALLBACK display (void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3d(0,1,0); float pos[4]={0,7.5,7.5,1}; static double time=0; float y,z; y=0; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, pos); glPushMatrix(); y=float(time/100); z=float(sin(y)); // float(); преобразование типа //движением по следующей траектории z=sin(y) glTranslated(0,y,z); //вращающего тора относительно оси x glRotated(time,1,0,0); if (y>11 && flag==1) { flag=2; } if (y<-4 && flag==2) { flag=1; } if (flag==2) { time--; } else { time++; } auxSolidTorus(0.15, 0.5); glPopMatrix(); // система координат XYZ glBegin(GL_LINES); glColor3ub(255, 0, 0); glVertex3f(5, 0, 0); glVertex3f(-5, 0, 0); // х красный glColor3ub(0, 255, 0); glVertex3f(0, 11, 0); glVertex3f(0, -4, 0); // y зеленый glColor3ub(0, 0, 255); glVertex3f(0, 0, 0); glVertex3f(0, 0, 5); // z синий glEnd(); glFinish(); auxSwapBuffers(); } void main () AUX_DOUBLE); auxInitWindow ("v11_04"); glScaled(1.5, 1.5, 1.5); glTranslated(0,-3,0); auxIdleFunc (display); auxReshapeFunc(resize); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); auxMainLoop(display); Результат: 5. Напишите программу мерцающего звездного неба Решение: #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include<time.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> int t_sec() // считывание секунд с системных часов { struct tm *newtime; time_t aclock; time(&aclock); newtime = localtime(&aclock); asctime(newtime); int s=newtime->tm_sec; return s; } void CALLBACK resize (int width, int height) { glViewport (0,0,width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-100,100,-100,100); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw (void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); int c, x, y, p; srand(t_sec()); //задание стартовой точки //для генерации случайных чисел for(int i=0; i<1000; i++) { c=rand()%255; //генерация случайных чисел от 0 до 255 x=rand()%200; //генерация случайных чисел от 0 до 200 y=rand()%200; //генерация случайных чисел от 0 до 200 p=rand()%3; glPointSize(p); glBegin(GL_POINTS); glColor3ub(c,c,c); glVertex2d(x,y); glEnd(); } auxSwapBuffers(); } void main () AUX_DEPTH Результат: 6. Изобразите радугу состоящую из полигонов, которая освещается прожектором. Направление света прожектора постоянно меняется и скользит вдоль радуги Решение: #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include<time.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> int flag=1; void CALLBACK resize (int width, int height) { glViewport (0,0,width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); //glOrtho(-20,20,-15,15, -10,25); glOrtho(-6,6,-6,6, -20,20); gluLookAt(1,-1,1, 0,0,0, 0,0,1); //gluLookAt(0,-5,0, 0,0,0, 0,0,1); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw (void) { static double time=0; GLUquadricObj *quadObj; quadObj = gluNewQuadric(); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); float x=time/100-2.2; float z=pow((pow(2.4,2)-pow(x,2)),0.5); if (x>2.2 && flag==1) { flag=2; } if (x<-2.2 && flag==2) { flag=1; } if (flag==2) { time--; } else { time++; } float dir[3]={x,0.1,z}; float pos[4]={0,-1,0,1}; // включение нулевой лампы GLfloat light_diffuse[]={3.0,3.0,3.0,1.0}; glLightfv(GL_LIGHT0,GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90); glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 9); glEnable(GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); glPopMatrix(); glPushMatrix(); glRotated(90,1,0,0); gluQuadricDrawStyle(quadObj, GLU_FILL); // К glColor3ub(255, 0, 0); gluPartialDisk(quadObj, 2, 2.2, 30, 30, -90, 180); // О glColor3ub(255, 125, 0); gluPartialDisk(quadObj, 2.2, 2.4, 30, 30, -90, 180); // Ж glColor3ub(255, 255, 0); gluPartialDisk(quadObj, 2.4, 2.6, 30, 30, -90, 180); // З glColor3ub(0, 255, 0); gluPartialDisk(quadObj, 2.6, 2.8, 30, 30, -90, 180); // Г glColor3ub(0, 255, 255); gluPartialDisk(quadObj, 2.8, 3, 30, 30, -90, 180); // С glColor3ub(0, 0, 255); gluPartialDisk(quadObj, 3, 3.2, 30, 30, -90, 180); // Ф glColor3ub(255, 0, 255); gluPartialDisk(quadObj, 3.2, 3.4, 30, 30, -90, 180); glPopMatrix(); glDisable(GL_LIGHTING); auxSwapBuffers(); } void main () AUX_DOUBLE); auxInitWindow ("v11_06"); glTranslated(3,-3,2); glEnable (GL_COLOR_MATERIAL); // установка свойств материала auxIdleFunc (Draw); auxReshapeFunc (resize); auxMainLoop(Draw); Результат: 7. Напишите программу вывода цилиндра, на котором наложена текстура. Создайте эффект сползания текстуры с цилиндра. Вокруг цилиндра вращается несколько полупрозрачных небольших сфер по спирали Решение #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include<time.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> int flag0=1; int flag1=1; int flag2=1; int flag3=1; unsigned int image1_ID; AUX_RGBImageRec* image1; void CALLBACK resize (int width, int height) { glViewport (0,0,width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); glOrtho(-6,6,-6,6, -20,20); gluLookAt(1,-1,1, 0,0,0, 0,0,1); glMatrixMode(GL_MODELVIEW); } void CALLBACK Draw (void) { static double time0=0; static double time1=0; static double time2=0; static double time3=0; GLUquadricObj *quadObj; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3d(1,1,1); float pos[4]={3,-3,5,1}; glLightfv(GL_LIGHT0, GL_POSITION, pos); glEnable(GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); quadObj = gluNewQuadric(); float s=0.9-(time0/800); if (s<0.01 && flag0==1) {flag0=2;} if (s>0.9 && flag0==2) {flag0=1;} if (flag0==1) {time0++;} else {time0--;} const float p[4]={0,0,s,0}; glPushMatrix(); glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_T,GL_OBJECT_PLANE,p); glRotated(-180,1,0,0); glTranslated(0,0,-3); glColor3d(1,1,0); gluCylinder(quadObj, 1, 1, 3, 50, 50); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_2D); glPopMatrix(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPushMatrix(); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); double z1=time1/300; glRotated(time1,0,0,1); glTranslated(1.3,0,1); glTranslated(0,0,z1); if (z1>2 && flag1==1) {flag1=2;} if (z1<-1 && flag1==2) {flag1=1;} glColor4d(0,1,0, 0.1); auxSolidSphere(0.2); //s1 glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); if (flag1==1) {time1++;} else {time1--;} glPopMatrix(); glPushMatrix(); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); double z2=time2/600; glRotated(time2*2,0,0,15); glTranslated(1.8,0,1); glTranslated(0,0,z2); if (z2>2 && flag2==1) {flag2=2;} if (z2<-1 && flag2==2) {flag2=1;} glColor4d(1,0,0, 0.1); auxSolidSphere(0.2); //s2 glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); if (flag2==1) {time2++;} else {time2--;} glPopMatrix(); glPushMatrix(); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); double z3=time3/400; glRotated(time3*3,0,0,1); glTranslated(2.3,0,1); glTranslated(0,0,z3); if (z3>2 && flag3==1) {flag3=2;} if (z3<-1 && flag3==2) {flag3=1;} glColor4d(0,0,1, 0.2); auxSolidSphere(0.2); //s3 glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); if (flag3==1) {time3++;} else {time3--;} glPopMatrix(); gluDeleteQuadric(quadObj); auxSwapBuffers(); } void main () AUX_DEPTH Результат:
|
|