![]() |
Замъглявания |
![]() |
Както може би сте забелязали отново използваме кода с планетите, като този път добавяме и мъгла. Освен това можем да контролираме плътността на замъгляването с функцията FogControl( ), чиято дефиниция е най-накрая. При натискане на бутон ' А ' от клавиатурата се увеличава разстоянието до крайната отрязваща равнина на мъглата и нейната плътност намалява. При натискане на бутон ' S ' от клавиатурата се случва точно обратното - крайната отрязваща равнина се приближава и мъглата става по-гъста.
#include < windows.h > // Хедърният файл на Windows #include < gl/glut.h > // Хедърният файл на GLUT #include < gl/gl.h > // Хедърният файл на OpenGL void Render( void ); void Resize( int width, int height ); void Menu( int value ); void Lighting( void ); void FogControl( unsigned char key, int x, int y ); int MenuID; // променлива, в която ще съхраняваме инд. номер на нашето меню // дефинираме променливите които ще регулират завъртането на планетите float Planet1_Angle; float Planet2_Angle; float Moon_Angle; GLfloat ambient_light[ ] = { 0.4, 0.4, 0.4, 1.0 }; // цвета на AMBIENT светлината GLfloat diffuse_light[ ] = { 0.8, 0.8, 0.8, 1.0 }; // цвета на DIFFUSE светлината GLfloat light_position[ ] = { 0.0, 0.0, 0.0, 1.0 }; // позицията на светлинния източник GLfloat emission[ ] = { 0.8, 0.8, 0.8, 1.0 }; // цвета на EMISSION излъчването GLfloat emission_none[ ] = { 0.0, 0.0, 0.0, 1.0 }; // черен цвят, нужен за изключване на EMISSION излъчването GLfloat fog_color[ ] = { 0.2, 0.0, 0.0, 1.0 }; // цвета на мъглата GLfloat fog_end = 100.0; // край на мъглата int main( int argc, char* argv[ ] ) { glutInit( &argc, argv ); // инициализираме библиотеката GLUT glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA ); // определяме режим на рендериране glutInitWindowSize( 600, 600 ); // определяма големина на прозореца glutInitWindowPosition( 100, 100 ); // определяма позиция на прозореца glutCreateWindow( "Created with GLUT ( OpenGL Utility Toolkit )" ); // създаваме прозореца glutDisplayFunc( Render ); // определяме рендериращата ни функцуя // определяме нашата оразмеряваща функция, която се извиква при промяна размерите на прозореца glutReshapeFunc( Resize ); // извикваме нашата функция Lighting, в която сме определили светлинен източник и материал за обектите Lighting( ); glEnable( GL_DEPTH_TEST ); // включваме проверка за разстоянията // определяме фунцкията която ще се извиква при натискане на бутон от клавиатурата glutKeyboardFunc( FogControl ); glEnable( GL_FOG ); // разрешаваме използването на мъгла glFogf( GL_FOG_MODE, GL_LINEAR ); // определяме тип на мъглата glFogfv( GL_FOG_COLOR, fog_color ); // определяме цвят на мъглата glFogf( GL_FOG_START, 5.0 ); // начало на мъглата glFogf( GL_FOG_END, fog_end ); // край на мъглата // създаваме нашето меню и указваме функция, // която ще се извиква при избиране на елемент от менюто MenuID = glutCreateMenu( Menu ); glutSetMenu( MenuID ); // определямо менюто като текущо меню glutAddMenuEntry( "About", 1 ); // първи елемент от менюто glutAddMenuEntry( "EXIT", 2 ); // втори елемент от менюто glutAttachMenu( GLUT_RIGHT_BUTTON ); // определяме бутона, чието натискане активира менюто glMatrixMode( GL_PROJECTION ); gluPerspective( 45, 1, 1, 200 ); // определяме 3D изгледа glMatrixMode( GL_MODELVIEW ); // превключваме обратно на MODELVIEW матрица glutMainLoop( ); return 0; } void Render( ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // изчистваме буферите glLoadIdentity( ); // зареждаме първоначалната матрица // запълваме цветовия буфер с цвета на мъглата glClearColor( 0.2, 0.0, 0.0, 1.0 ); // увеличаваме ъгъла на завъртване Planet1_Angle += 0.5; Planet2_Angle += 0.3; Moon_Angle += 0.5; // определяме позиция на камерата gluLookAt( 0.0, 10.0, -50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); // подновяваме позиията на светлинния източник ( махнете този ред за да видите какво ще стане ;) glLightfv( GL_LIGHT0, GL_POSITION, light_position ); glMaterialfv( GL_FRONT, GL_EMISSION, emission ); // определяме EMISSION излъчването glColor3f( 1.0, 1.0, 0.0 ); glutSolidSphere( 4.0, 20, 20 ); // създаваме слънцето :) // изключваме EMISSION излъчването, защото не искаме да се отрази на останалите обекти glMaterialfv( GL_FRONT, GL_EMISSION, emission_none ); glPushMatrix( ); // поставяме матрица в стека glRotatef( Planet1_Angle, 0.0, 1.0, 0.0 ); // завъртаме сцената glTranslatef( 10.0, 0.0, 0.0 ); // преместваме сцената с 10 единици glColor3f( 1.0, 0.0, 0.0 ); glutSolidSphere( 1.5, 20, 20 ); // изрисуваме първата планета glPopMatrix( ); // изваждаме матрицата от стека // за изрисуване на втората планета повтаряме същата процедура glPushMatrix( ); glRotatef( Planet2_Angle, 0.0, 1.0, 0.0 ); glTranslatef( -20.0, 0.0, 0.0 ); glColor3f( 0.0, 1.0, 0.0 ); glutSolidSphere( 2.0, 20, 20 ); // сега идва ред на луната, която трябва да обикаля около планетата glRotatef( Moon_Angle, 0.0, 1.0, 0.0 ); glTranslatef( 5.0, 0.0, 0.0 ); glColor3f( 0.0, 0.0, 1.0 ); glutSolidSphere( 1.0, 20, 20 ); glPopMatrix(); /* Забележете че изрисуваме луната в матрицата на втората планета, защото искаме първите две транформации, преди изрисуване на втората планета, да се отразят и на луната. Само така ще постигнем желания резултат - планета въртяща се около слънцето и луна въртяща се около планетата. */ glutSwapBuffers( ); // разменяме буферите glutPostRedisplay( ); // изискваме следващо извикване на рендериращата ни функция } void Resize( int width, int height ) { if(height==0) height=1; // проверяваме стойността на height, за да избегнем деление на 0 // указваме на OpenGL, че искаме изрисуване върху целия прозорец glViewport( 0, 0, width, height ); glMatrixMode( GL_PROJECTION ); // включваме PROJECTION матрицата glLoadIdentity( ); // зареждаме първоначалната PROJECTION матрица gluPerspective( 45, (GLdouble)width/height, 1, 200 ); // определяме новия 3D изглед glMatrixMode( GL_MODELVIEW ); // превключваме отново към MODELVIEW матрица glLoadIdentity( ); } void Menu( int value ) { int result; // обработваме подаденото на нашата функция съобщение (номера на избрания елемент от менюто) switch( value ) { // ако е избран първия елемент от менюто се показва прозорец със съобщение case 1: MessageBox( NULL, "Created with GLUT ( OpenGL Utility Toolkit )", "About", MB_OK ); break; // ако е избран втория елемент от менюто ( EXIT ) се показва прозорец с въпрос, // дали искаме да затворим програмата case 2: result = MessageBox( NULL, "Do you really want to quit?", "Quit?", MB_YESNO ); if( result == IDYES ) exit( 0 ); break; } } void Lighting( void ) { glEnable( GL_LIGHTING ); // включваме динамичната светлина // определяма глобална AMBIENT светлина glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient_light ); glEnable( GL_LIGHT0 ); // включваме светлинен източник glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse_light ); // определяме DIFFUSE излъчване glLightfv( GL_LIGHT0, GL_POSITION, light_position ); // определяме позиция на източника // определяме начина по който обектите поглъщат светлина от тип AMBIENT и DIFFUSE glMaterialfv( GL_FRONT, GL_AMBIENT, ambient_light ); glMaterialfv( GL_FRONT, GL_DIFFUSE, diffuse_light ); // изискваме цвета на нашите обекти, да се запазва при включване на динамичната светлина glEnable( GL_COLOR_MATERIAL ); // определяме при кои видове светлина, цвета на обекта да участва в получаването // на крайния цвят след осветяването glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); } void FogControl( unsigned char key, int x, int y ) { // при натискане на бутон ' A ' увеличаваме крайната отрязваща равнина на мъглата if( key=='a' ) fog_end = fog_end + 2.0; // при натискане на бутон ' S ' намаляваме крайната отрязваща равнина на мъглата else if( key=='s' ) fog_end = fog_end - 2.0; // определяме граници за крайната отрязващата равнина if( fog_end < 50.0 ) fog_end = 50.0; if( fog_end > 200.0 ) fog_end = 200.0; // подновяваме позицията на крайната отрязваща равнина на мъглата glFogf( GL_FOG_END, fog_end ); } Свалете Visual C++ сорс кода на праграмата. |
Автор: Иван Георгиев Иванов [ Nickname: tuschko ]
e-mail: tuschko@abv.bg |
Този сайт е хостван от сървър на Headoff Gaming Intranetwork |
![]() |