![]() |
Текстуриране |
![]() |
Първата ми успешна текстура, беше върху един торус и реших да спазя традицията :) В настоящия пример ще видите един текстуриран торус с дървена настилка. Добавил съм и възможност за движение на камерата напред и назад, съответно със стрелка напред и стрелка назад. За да спрете камерата трябва да натиснете някой от специалните бутони, а на-близкия от тях е стрелка наляво / надясно. Използвал съм Mipmap текстура, като съм включил най-качествените филтрации за MAG и MIN филтът. Можете да експериментирате, като смените режима на някой от филтрите. Благодарение на движещата се камера ще видите лесно разликата между билинеарната и трилинеарната филтрация ( при първата се вижда по-отчетливо как едно изображение от Mipmap текстурата се заменя с друго, докато при втората това става изключително плавно ). Ако случайно сте забравили BILINEAR филтрация беше избиране на режим GL_LINEAR_MIPMAP_NEAREST за MIN филтъра, а TRILINEAR - режим GL_LINEAR_MIPMAP_LINEAR.
#include < windows.h > // Хедърният файл на Windows #include < gl/glut.h > // Хедърният файл на GLUT #include < gl/gl.h > // Хедърният файл на OpenGL #include < gl/glu.h > // Хедърният файл на GLU #include < gl/glaux.h > // Хедърният файл на GLAUX void Render( void ); void Resize( int width, int height ); void Menu( int value ); void Lighting( void ); void Mooving( int button, int x, int y ); void TextureLoader( void ); int MenuID; // променлива, в която ще съхраняваме инд. номер на нашето меню // дефинираме променливaтa която ще регулира завъртането на торуса GLfloat Rotation_Angle; GLfloat distance = -10.0;// дефинираме променлива определяща разстоянието между обекта и камерата GLint direction = 0; // дефинираме променлива, от която ще зависи посоката на движение на камерата // дефинираме указател от тип AUX_RGBImageRec, където ще съхраним изображението AUX_RGBImageRec* Image; // дефинираме масива, в който ще съхраним името на нашата текстура GLuint Texture_ID[1]; GLfloat ambient_light[ ] = { 0.2, 0.2, 0.2, 1.0 }; // цвета на AMBIENT светлината GLfloat diffuse_light[ ] = { 0.6, 0.6, 0.6, 1.0 }; // цвета на DIFFUSE светлината GLfloat specular_light[ ] = { 1.0, 1.0, 1.0, 1.0 }; // цвета на SPECULAR светлината 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 ); // определяме функцията, която да се извиква при натискане на някой от SPECIAL бутоните glutSpecialFunc( Mooving ); // извикваме нашата функция Lighting, в която сме определили светлинен източник и материал за обектите Lighting( ); // извикваме функцията TextureLoader, която създава нашата текстура TextureLoader( ); glEnable( GL_DEPTH_TEST ); // включваме проверка за разстоянията // създаваме нашето меню и указваме функция, // която ще се извиква при избиране на елемент от менюто 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( ); // зареждаме първоначалната матрица // преместваме камерата ( сцената ) по z координатата, в зависимост от стойността на distance glTranslatef( 0.0, 0.0, distance ); // в зависимост от стойността на променливата direction намаляваме или увеличаваме разстояниетo до обекта if( direction == 1 ) distance += 0.05; if( direction == -1 ) distance = distance - 0.05; // увеличаваме ъгъла на завъртане Rotation_Angle += 0.05; // завъртаме по x и y glRotatef( Rotation_Angle, 1.0, 0.0, 0.0 ); glRotatef( Rotation_Angle, 0.0, 1.0, 0.0 ); // избираме текстурата, която желаем да използваме, макар че при наличието на една текстура това е ненужно, // но аз да покажа за всеки случай :) glBindTexture( GL_TEXTURE_2D, Texture_ID[0] ); // изрисуваме торус glutSolidTorus( 1.0, 3.0, 50, 50 ); 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_SPECULAR, specular_light ); // определяме SPECULAR излъчване // определяме начина по който обектите поглъщат светлина от тип AMBIENT, DIFFUSE и SPECULAR glMaterialfv( GL_FRONT, GL_AMBIENT, ambient_light ); glMaterialfv( GL_FRONT, GL_DIFFUSE, diffuse_light ); glMaterialfv( GL_FRONT, GL_SPECULAR, specular_light ); // определяме фокуса на светлинното петно glMateriali( GL_FRONT, GL_SHININESS, 128 ); // изискваме цвета на нашите обекти, да се запазва при включване на динамичната светлина glEnable( GL_COLOR_MATERIAL ); // определяме при кои видове светлина, цвета на обекта да участва в получаването // на крайния цвят след осветяването glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); } void Mooving(int button, int x, int y) { // ако е натисната стрелка нагоре или надолу променливата direction получава стойност 1 или -1 // при натискане на някой друг от специалните бутони direction се нулира if( button == GLUT_KEY_UP ) direction = 1; else if( button == GLUT_KEY_DOWN ) direction = -1; else direction = 0; } void TextureLoader( void ) { glEnable(GL_TEXTURE_2D); // разрешаваме текстурирането // определяме режим на наслагване на текстурата glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // зареждаме изображението Image = auxDIBImageLoad("wood.bmp"); // създаваме име за единсвената ни текстурa glGenTextures( 1, &Texture_ID[0] ); // свързваме текстурата, която ще създадем, с генерираното име от масива glBindTexture( GL_TEXTURE_2D, Texture_ID[0] ); // създаваме нашата текстура gluBuild2DMipmaps( GL_TEXTURE_2D, 3, Image->sizeX, Image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, Image->data ); // избираме качествен режим на филтрация за текстурата glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); // TRILINEAR // включваме автоматично изчисляване на координати за текстурата glEnable( GL_TEXTURE_GEN_S ); glEnable( GL_TEXTURE_GEN_T ); // казваме на OpenGL, че искаме нашата текстура просто да се залепи за обекта glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); } Свалете Visual C++ сорс кода на праграмата. |
Автор: Иван Георгиев Иванов [ Nickname: tuschko ]
e-mail: tuschko@abv.bg |
Този сайт е хостван от сървър на Headoff Gaming Intranetwork |
![]() |