Лабораторная работа №6. Вывод массива объектов модели NaCl Цель: Научиться выводить на экран массивы различных типов объектов и управлять перемещением группы в пространстве Задание: Создать приложение, отображающее модель структуры кристалла поваренной соли NaCl. В качестве моделей атомов использовать сферы, соединенные линиями. Организовать вращение всей системы. Выполнение задания: 1. Подключите библиотеку дополнительных функций GLUT, для чего в приложении подключить заголовочный файл glut.h и glut32.lib, а в системную папку скопировать glut32.dll 2. Создайте новый проект с именем NaCl. 3. Cоздайте процедуру перерисовки окна FormPaint. Для этого необходимо в инспекторе объектов для формы перейти на вкладку Events и щелкнуть на событии OnPaint, В обработчик события записать код: 4. Чтобы при изменении размеров окна прорисованные объекты изменялись пропорционально, нужно для события OnResize формы выбрать событие FormPaint. 5. Настроить формат пикселя - SetDCPixelFormat (hdc : HDC); 6. На событие FormDestroy, которое находится на той же вкладке, необходимо дописать: 7. Создать панель Panel1: TPanel , на которую поместить четыре кнопки со стрелками (вкладка Standard). 8. Написать процедуру перерисовки структуры поваренной соли: Пояснение к заданию Использовать: wglMakeCurrent(Canvas.Handle, hrc); glViewPort (0, 0, ClientWidth, ClientHeight); // область вывода glClear (GL_COLOR_BUFFER_BIT); // очистка буфера цвета SwapBuffers(Canvas.Handle); wglMakeCurrent(0, 0); wglDeleteContext(hrc); // содержимое буфера - на экран Пример листинга приложения. Текст файла описания классов Matrix3D.h: class Matrix3D { int* data; int X; int Y; int Z; public: Matrix3D(); void Resize(int rsizeX, int rsizeY, int rsizeZ); Matrix3D(int sizeX, int sizeY, int sizeZ); ~Matrix3D(){delete[ ] data;} int GetItems(int x,int y,int z); void SetItems(int x,int y,int z, int value); int SizeX(){return X;} int SizeY(){return Y;} int SizeZ(){return Z;} }; Matrix3D::Matrix3D() { data=new int [2]; data[0]=0; data[1]=0; X=1; Y=1; Z=1; } void Matrix3D::Resize(int rsizeX, int rsizeY, int rsizeZ){ delete[ ] data; data=new int [rsizeX*rsizeY*rsizeZ]; for(int i=0;i<rsizeX*rsizeY*rsizeZ;i++){data[i]=0;} X=rsizeX;Y=rsizeY;Z=rsizeZ; } Matrix3D::Matrix3D(int sizeX, int sizeY, int sizeZ){ data=new int [sizeX*sizeY*sizeZ]; for(int i=0;i<sizeX*sizeY*sizeZ;i++){data[i]=0;} X=sizeX;Y=sizeY;Z=sizeZ; } int Matrix3D::GetItems(int x,int y,int z){ return data[X*Y*z+y*X +x]; } void Matrix3D::SetItems(int x,int y,int z, int value){ data[X*Y*z+y*X +x]=value; } Текст файла Main.cpp: #include <iostream.h> #include "Matrix3D.h" void myKeyboard(unsigned char theKey, int mouseX,int mouseY); void display(void); void resize(int width,int height); int X,Y,Z; GLfloat x=0,y=0; void resize(int width,int height) { glViewport(0,0,width,height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); int max; if(X>Y) {if(X>Z){max=X;}else{max=Z;}} else {if(Y>Z){max=Y;}else{max=Z;} } max++; glOrtho(-max,max, -max,max, -max,max); gluLookAt( 0,0,5, 0,0,0, 0,1,0 ); glMatrixMode( GL_MODELVIEW ); } //начало прорисовки void display(void) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); int ind=0,i,j,k; float r;//Na=0.2 Cl=0.4 Matrix3D M(X,Y,Z);// 0-Na 1-Cl for(i=0;i<X;i++){for(j=0;j<Y;j++){for(k=0;k<Z;k++){ if(ind==0){M.SetItems(i,j,k,ind);ind=1;}else{M.SetItems(i,j,k,ind);ind=0;} if(k==Z-1){ if(M.GetItems(i,j,0)==0){ind=1;}else{ind=0;}} } } if(M.GetItems(i,0,0)==0){ind=1;}else{ind=0;} } for(i=0;i<X;i++){for(j=0;j<Y;j++){for(k=0;k<Z;k++){ if(M.GetItems(i,j,k)==0){glColor3d(0.5,0.5,0.5);r=0.2;}else{glColor3d(1,1, 1);r=0.4;} glTranslatef(i,j,k); glutSolidSphere (r, 50, 50);glTranslatef(-i,-j,-k); }}} //конец прорисовки glutSwapBuffers(); } void myKeyboard(unsigned char theKey, int mouseX,int mouseY){ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); if(theKey=='/'){ glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);display();} if(theKey=='*'){glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);display();} if(theKey=='-'){glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);display();} if(theKey=='a' || theKey=='s' || theKey=='w' || theKey=='z'){ if(theKey=='a'){glRotatef (-1, 0.0, 1.0, 0.0);} if(theKey=='s'){glRotatef (1, 0.0, 1.0, 0.0);} if(theKey=='w'){glRotatef (-1, 1.0, 0.0, 0.0);} if(theKey=='z'){glRotatef (1, 1.0, 0.0, 0.0);} display();///перерисовка после поворотов } glutSwapBuffers(); } void main(){ int x,y; float lw,ps; cout<<"height window = "; cin>>x; cout<<endl<<"width window = "; cin>>y; cout<<endl<<"line width = "; cin>>lw; cout<<endl<<"point size = "; cin>>ps; cout<<endl<<"size NaCl X = "; cin>>X; cout<<endl<<"size NaCl Y = "; cin>>Y; cout<<endl<<"size NaCl Z = "; cin>>Z; glutInitWindowPosition(0, 0); glutInitWindowSize(x, y); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); glutCreateWindow("Окно вывода" ); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(myKeyboard); glClearColor (1.0, 1.0, 0.5, 1.0); glLineWidth (lw); glPointSize(ps); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glColor3f (1.0, 0.3, 0.0); glutMainLoop(); } Пример работы приложения показан на рисунке