50087 (Використання OpenGL. Моделювання вогню), страница 4

2016-07-30СтудИзба

Описание файла

Документ из архива "Використання OpenGL. Моделювання вогню", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "50087"

Текст 4 страницы из документа "50087"

очистити_вікно();

намалювати_кадр(i);

поміняти_буфери_місцями() ; }

3.2 Моделювання вогню

Крім того, частота оновлення відеоінформації, що відображається, є постійною величиною, яка може мати деякі несподівані наслідки з точки зору продуктивності. Наприклад, при періоді оновлення інформації, що відображається на моніторі, рівної 1/60 часток секунди і при постійній швидкості передачі кадрів ви можете працювати зі швидкостями 60 fps, 30 fps, 20 fps, 15 fps, 12 fps і т. д. (60/1, 60/2, 60/3, 60/4, 60/5, і т. д.). Це означає, що якщо ви пишете прикладну програму і поступово додаєте до неї нові функціональні можливості (припустимо, що ця програма - імітатор польоту, і ви додаєте наземний пейзаж), то спочатку кожна нова деталь, що додається, не робитиме ніякого ефекту на сумарну продуктивність - ви все одно отримуєте швидкість передачі кадрів, рівну 60 fps. Потім, коли ви додаєте ще одну нову деталь, система вже не може намалювати усе це впродовж 1/60 частки секунди, і анімація різко сповільнюється - з 60 fps до 30 fps, оскільки вона пропускає перший можливий момент зміни буферів. Аналогічна ситуація відбувається, коли час малювання одного кадру стає більше, ніж 1/30 частка секунди - швидкість передачі кадрів анімації стрибком зменшується від 30 fps до 20 fps.

В даному випадку програма для моделювання горіння вогню була написана на основі системи часток. Ці частки моделюють різні шари - "домени" іонізованого повітря і їх випадковий рух в просторі. В ході руху ці шари-частки світяться, поступово втрачаючи яскравість. У цій програмі використовується лінійна інтерполяція загасання яскравості шарів. Напрям і величина початкової швидкості вибирається випадково в деякому діапазоні. Так само випадково вибирається і так звана швидкість гасіння частки - швидкість, з якою задана частка втрачає яскравість свого світіння. Вважається, що початкова величина яскравості частки дорівнює одиниці. Для імітування архімедівської сили, що піднімає шари повітря, використовується "антигравітація", тобто умовно задається середній напрям прискорення руху. Для розрахунку руху часток використовується метод Ейлера в простому своєму варіанті. Цього вистачає, оскільки рух окремої частки в даному випадку неважливий - нам необхідно створити випадковий розподіл руху часток для відтворення хаотичної динаміки досліджуваного явища. Ну і нарешті не менш візуально важливим параметром є колір вогню. Світловий спектр вогню можна вважати схожим із спектром Сонця. У програмі використовується лише чотири кольори з червоної області спектру по черзі змінюючі один-одного. Ось їх значення в системі RGB : (255,128,128) (255,128,64) (255,161,102) (255,128,51). Проте кількість використовуваних кольорів нескладна істотно збільшити.

При запуску програми в пам'яті комп'ютера створюється масив, що містить поточний стан кожної з часток. У нім також міститься така величина, як "прожите життя" частки. При русі окрім яскравості зменшується і життя частки. Коли спочатку рівна одиниці життя обнуляється, частка відроджується в основі полум'я з новими параметрами. Таким чином кількість задіяних часток постійна (у цій програмі їх 2000), а частки проживають усі нові і нові "життя". Як уже згадувалося, поведінка полум'я цілком залежить від того з якими параметрами відроджуються частки. Ось ці параметри: по-перше, початкове положення часток (x, y, z -координат, де z=const=3, а x і y вибираються згідно з розподілом, згідно з яким вірогідність появи частки в центральній частині (квадраті 1х1) квадрата 2х2 з центром в нулі втричі вище чим по околиці), далі початкові швидкості часток(x, y, z -координати вибираються випадково зі змінюваних інтервалів) і швидкість гасіння частки (також в межах заданого інтервалу). Наступна діаграма ілюструє усе вищесказане.

Рис. 3.2 Циклічна схема переміщення часток

Далі приводиться код самої програми:

#include // Заголовочний файл Windows

#include

#include // Заголовочний файл вводу/виводу

#include // Заголовочний файл бібліотеки OpenGL32

#include // Заголовочний файл бібліотеки GLu32

#include // Заголовочний файл бібліотеки The Glaux

#defineMAX_PARTICLES1000

#define MAX_COLORS 4// Кількість кольорів полум’я

#define BOTTOM-3.0f

HDChDC=NULL;

HGLRChRC=NULL;

HWNDhWnd=NULL;

HINSTANCEhInstance;

boolkeys[256];

boolactive=TRUE;

boolfullscreen=FALSE;

boolrainbow=TRUE;

floatslowdown=6.0f;// Сповільнення часток

floatxspeed;

floatyspeed;

floatzoom=-20.0f;

GLuintloop;// Параметр циклу

GLuintcol;// Поточний колір

GLuintdelay;// Затримка ефекту веселки

GLuinttexture[1];// Пам’ять для текстури часток

GLfloatr;

typedef struct// Оголошення змінних

{

boolactive;

floatlife;

floatfade;

floatr;

floatg;

floatb;

floatx;

floaty;

floatz;

floatxi;

floatyi;

floatzi;

floatxg;

floatyg;

floatzg;

}

particles;// Структура часток

particles particle[MAX_PARTICLES];// Масив часток

static GLfloat colors[MAX_COLORS][4]=// Кольори веселки

{

{1.0f,0.5f,0.5f},{1.0f,0.5f,0.24f},{1.0f,0.63f,0.4f},{1.0f,0.2f,0.5f}

};

LRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

AUX_RGBImageRec *LoadBMP(char *Filename)// Завантаження Bitmap зображення

{

FILE *File=NULL;// Дескриптор файлу

if (!Filename)// Переконатися у наданні імені файлу

{

return NULL;

}

File=fopen(Filename,"r");// Перевірити чи існує файл

if (File)

{

fclose(File);

return auxDIBImageLoad(Filename)

}

return NULL; // Якщо завантаження не вдалося, то повертається NULL

}

int LoadGLTextures()

{

int Status=FALSE;// Індикатор стану

AUX_RGBImageRec *TextureImage[1];// Створити простір пам’яті длятекстур

memset(TextureImage,0,sizeof(void *)*1);// Встановити покажчик на NULL

if (TextureImage[0]=LoadBMP("Data/Particle.bmp"))// Завантажити текстури

{

Status=TRUE;glGenTextures(1, &texture[0]);// Створення однієї текстури

glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

}

if (TextureImage[0])

{

if (TextureImage[0]->data) // Якщо текстури не існує

{

free(TextureImage[0]->data); // Звільнити пам’ять

}

free(TextureImage[0]);

}

return Status;

}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Перевизначити розмір вікна

{

if (height==0)

{

height=1;// Висота рівна одиниці

}

glViewport(0,0,width,height);// Перезавантажити поточну область перегляду

glMatrixMode(GL_PROJECTION);// Вибір матриці проекту

glLoadIdentity();// Перезавантаження матриці проекту

// Обчислити коефіцієнт стискування вікна

gluPerspective(20.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

int InitGL(GLvoid)// Налаштування OpenGL

{

if (!LoadGLTextures())

return FALSE;

srand((DWORD)GetTickCount);

glShadeModel(GL_SMOOTH);

glClearColor(0.0f,0.0f,0.0f,0.0f);// Чорний фон

glClearDepth(1.0f);// Буфер глибини

glDisable(GL_DEPTH_TEST);

glEnable(GL_BLEND);// Змішування

glBlendFunc(GL_SRC_ALPHA,GL_ONE);// Тип змішування

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D,texture[0]);// Вибір текстури

for (loop=0;loop

{

particle[loop].active=TRUE;// Make All The Particles Active

particle[loop].life=1.0f;// Give All The Particles Full Life

particle[loop].fade=float(rand()%100)/100.0f+0.3f;

particle[loop].r=colors[loop*(MAX_COLORS/MAX_PARTICLES)][0];// Вибір червоного кольору

particle[loop].g=colors[loop*(MAX_COLORS/MAX_PARTICLES)][1];// Вибір червоного кольору

particle[loop].b=colors[loop*(MAX_COLORS/MAX_PARTICLES)][2];// Вибір червоного кольору

particle[loop].xi=float((rand()%50)-26.0f)*10.0f;// Випадкова Швидкість На Осі X

particle[loop].yi=float((rand()%100)-25.0f)*10.0f;// Випадкова Швидкість На Осі Y

particle[loop].zi=float((rand()%50)-25.0f)*10.0f;;// Випадкова Швидкість На Осі Z

particle[loop].xg=0.0f;particle[loop].yg=-0.08f; particle[loop].zg=0.0f;

particle[loop].y=BOTTOM;

}

return TRUE;// Ініціалізація

}

int DrawGLScene(GLvoid)// Малювання

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Очищення екрану і буфера глибини

glLoadIdentity();

for (loop=0;loop

{

if (particle[loop].active)// Якщо частки активні

{

float x=particle[loop].x;// Захопити позицію Xfloat y=particle[loop].y;// Захопити позицію Y

float z=particle[loop].z+zoom;// Захопити позицію Z

int coin;

glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life)

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z);

glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z);

glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);

glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z);

glEnd();

particle[loop].x+=particle[loop].xi/(slowdown*1000);

particle[loop].y+=particle[loop].yi/(slowdown*1000);

particle[loop].z+=particle[loop].zi/(slowdown*1000);

particle[loop].xi+=particle[loop].xg;

particle[loop].yi+=particle[loop].yg;

particle[loop].zi+=particle[loop].zg;

particle[loop].life-=particle[loop].fade;// Скорочення терміну життя часток

if (particle[loop].life<0.0f)// Якщо частка перегорає

{

particle[loop].life=1.0f;// Дати нове життя

particle[loop].fade=float(rand()%100)/1000.0f+0.01f; // Випадкове значення

particle[loop].y=BOTTOM;

coin=rand();

if (coin<(RAND_MAX/8)) particle[loop].x=float(rand())/(RAND_MAX)-2.0f;

else

if (coin<(RAND_MAX/4)) particle[loop].x=float(rand())/(RAND_MAX)+1.0f;

else particle[loop].x=2*float(rand())/(RAND_MAX)-1.0f;

coin=rand();

if (coin<(RAND_MAX/8)) particle[loop].z=float(rand())/(RAND_MAX)-2.0f;

else

if (coin<(RAND_MAX/4)) particle[loop].z=float(rand())/(RAND_MAX)+1.0f;

else particle[loop].z=2*float(rand())/(RAND_MAX)-1.0f;

particle[loop].xi=xspeed+float((rand()%60)-32.0f);

particle[loop].yi=yspeed+float((rand()%700)-200.0f);

particle[loop].zi=float((rand()%60)-30.0f);

col=rand()*(MAX_COLORS+1)/RAND_MAX;

if (col>3) col=0;

particle[loop].r=colors[col][0];// Вибір червоного кольору

particle[loop].g=colors[col][1];// Вибір зеленого кольору

particle[loop].b=colors[col][2];// Вибір синього кольору

}

if (keys[VK_NUMPAD8] && (particle[loop].yg<1.5f)) particle[loop].yg+=0.01f;

if (keys[VK_NUMPAD2] && (particle[loop].yg>-1.5f)) particle[loop].yg-=0.01f;

if (keys[VK_NUMPAD6] && (particle[loop].xg<1.5f)) particle[loop].xg+=0.01f;

if (keys[VK_NUMPAD4] && (particle[loop].xg>-1.5f)) particle[loop].xg-=0.01f;

}

}

return TRUE;

}

GLvoid KillGLWindow(GLvoid)

{

if (fullscreen)

{

ChangeDisplaySettings(NULL,0);

ShowCursor(TRUE);// Відображення курсора

}

if (hRC)

{

if (!wglMakeCurrent(NULL,NULL)){

MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

}

if (!wglDeleteContext(hRC))

{

MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

}

hRC=NULL;

}

if (hDC && !ReleaseDC(hWnd,hDC))

{

MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

hDC=NULL;

}

if (hWnd && !DestroyWindow(hWnd))// Ми млжемо знищити вікно?

{

MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

hWnd=NULL;// Set hWnd To NULL

}

if (!UnregisterClass("OpenGL",hInstance))// Ми можемо не зареєструвати клас

{

MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

hInstance=NULL;// Set hInstance To NULL

}

}

/*Наступний код створює вікно OpenGL:

*title- заголовок вікна

* width- довжина вікна

*height- висота вікна

*bits- кількість бітів для відображення кольору (8/16/24/32)

*fullscreenflag- використання повноекранного режиму*/

BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)

{

GLuintPixelFormat;// Уртимання результату після пошуку відповідності

WNDCLASSwc;// Клас структури вікна

DWORDdwExStyle;// Розширений Стиль вікна

DWORDdwStyle;// Стиль вікна

RECTWindowRect;

WindowRect.left=(long)0;

WindowRect.right=(long)width;

WindowRect.top=(long)0;

WindowRect.bottom=(long)height;

fullscreen=fullscreenflag;// Повноекранний режим

hInstance= GetModuleHandle(NULL);

wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Перемалювання вікна

wc.lpfnWndProc= (WNDPROC) WndProc;

wc.cbClsExtra= 0;// Жодних додаткових вікон

wc.cbWndExtra= 0;// Жодних додаткових вікон

wc.hInstance= hInstance;// Встановтти зразок

wc.hIcon= LoadIcon(NULL, IDI_WINLOGO); // Завантаження стандартного значка

wc.hCursor= LoadCursor(NULL, IDC_ARROW); // Завантаження координит курсора

wc.hbrBackground= NULL;wc.lpszMenuName= NULL;wc.lpszClassName= "OpenGL";// Вказання ім’я класу

if (!RegisterClass(&wc))// Зареєструвати клас вікна

{

MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;}

if (fullscreen)

{

DEVMODE dmScreenSettings;// Режим пристрою

memset(&dmScreenSettings,0,sizeof(dmScreenSettings));// Перевірка очищення пам’яті

dmScreenSettings.dmSize=sizeof(dmScreenSettings);

dmScreenSettings.dmPelsWidth= width;// Довжина вікна

dmScreenSettings.dmPelsHeight= height;// Висота вікна

dmScreenSettings.dmBitsPerPel= bits;// Кількість бітів

dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)

{

// При збої

if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)

{

fullscreen=FALSE;// Присвоїти повноекранному режиму значення = FALSE

}

else

{

// Виштовхнути дані зі стека.

MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);

return FALSE;

}

}

}

if (fullscreen)

{

dwExStyle=WS_EX_APPWINDOW;dwStyle=WS_POPUP;ShowCursor(FALSE);}

else

{

dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;

dwStyle=WS_OVERLAPPEDWINDOW;

}

AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);

// Створення вікна

if (!(hWnd=CreateWindowEx(dwExStyle,"OpenGL",// Ім’я класу

title,// Заголовок вікна

dwStyle |// Певний стиль вікна

WS_CLIPSIBLINGS |// Необхідний стиль вікна

WS_CLIPCHILDREN,// Необхідний стиль вікна

0, 0,// Позиція вікна

WindowRect.right-WindowRect.left,// Розрахунок довжини

WindowRect.bottom-WindowRect.top,// Розрахунок висоти

NULL,

NULL,// Без меню

hInstance,// Зразок

NULL)))// Не передавати нічого для WM_CREATE

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

staticPIXELFORMATDESCRIPTOR pfd=

{

sizeof(PIXELFORMATDESCRIPTOR), // Розмір пікселів

1,// Номер версії

PFD_DRAW_TO_WINDOW |// Вікно повинно підтримувати формат

PFD_SUPPORT_OPENGL |// OpenGL повинен підтримувати формат

PFD_DOUBLEBUFFER,// Підтримка буферу

PFD_TYPE_RGBA,// Підтримка формату RGBA

bits,// Глибина кольору

0, 0, 0, 0, 0, 0,

0,

0,

0,

0, 0, 0, 0,

16,// 16-бітний Z-буфер

0,

0,

PFD_MAIN_PLANE,

0,

0, 0, 0// Проігнорувати маски слою

};

if (!(hDC=GetDC(hWnd)))

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

if(!SetPixelFormat(hDC,PixelFormat,&pfd))

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

if (!(hRC=wglCreateContext(hDC)))

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

if(!wglMakeCurrent(hDC,hRC))

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

ShowWindow(hWnd,SW_SHOW);// Показ вікна

SetForegroundWindow(hWnd);

SetFocus(hWnd);

ReSizeGLScene(width, height);

if (!InitGL())// Ініціалізація вікна

{

KillGLWindow();// Оновлення екрану

MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

return TRUE;

}

LRESULT CALLBACK WndProc(HWNDhWnd,// обробка вікна

UINTuMsg, // Повідлмлення вікна

WPARAMwParam,LPARAMlParam){

switch (uMsg)// Перевірка повідомлень

{

case WM_ACTIVATE:// Спостерігати за повідомленнями

{

if (!HIWORD(wParam))

{

active=TRUE;// Програма активна

}

else// Або

{

active=FALSE;// Програма більше не активна

}

return 0;// Повернення до циклу повідомлень

}

case WM_SYSCOMMAND:// Перевірка системних команд

{

switch (wParam)// Перевірка системних викликів

{

case SC_SCREENSAVE:

case SC_MONITORPOWER:

return 0;

}

break;// Вихід

}

case WM_CLOSE:// Чи отримали повідомлення?

{

PostQuitMessage(0);// Відправити повідомлення

return 0;

}

case WM_KEYDOWN: // Чи натиснена клавіша?

{

keys[wParam] = TRUE;

return 0;

}

case WM_KEYUP:// Чи клавіша відпущена?

{

keys[wParam] = FALSE;

return 0;

}

case WM_SIZE:// Зміна розміра вікна OpenGL

{

ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height

return 0;

}

}

return DefWindowProc(hWnd,uMsg,wParam,lParam);

}

int WINAPI WinMain(HINSTANCEhInstance, // Зразок

HINSTANCEhPrevInstance,// Попередній Instance

LPSTRlpCmdLine, // Командний рядок Parameters

intnCmdShow) // Вікно стану

{

MSGmsg;// Структури повідомлень вікна

BOOLdone=FALSE;// Вихід з циклу

// Створення вікна OpenGL

if (!CreateGLWindow("Fire Simulation Based On Particles",640,480,16,fullscreen))

{

return 0;// Вихід, якщо вікно не вдалося створити

}

while(!done)// Цикл працює поки=FALSE

{

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))//

{

if (msg.message==WM_QUIT) // Чи є нові повідомлення?

{

done=TRUE;

}

else

{

TranslateMessage(&msg);// Перекласти повідомлення

DispatchMessage(&msg);// Відіслати повідомлення

}

}

else// Немає повідомлень

{

// Малювання сцени DrawGLScene()

if ((active && !DrawGLScene()) || keys[VK_ESCAPE]){

done=TRUE;// ESC для виходу

}

else

{

SwapBuffers(hDC);// Зміна буфера

if (keys[VK_ADD] && (slowdown>0.0f)) slowdown-=0.1f;// Швидкість руху часток вверх

if (keys[VK_SUBTRACT] && (slowdown<50.0f)) slowdown+=0.1f;// Швидкість руху часток вниз

if (keys[VK_PRIOR])zoom+=0.1f;// Приближення

if (keys[VK_NEXT])zoom-=0.1f;// Віддалення

if (keys[VK_UP] && (yspeed<2000)) yspeed+=1.0f;

if (keys[VK_DOWN] && (yspeed>-2000)) yspeed-=1.0f;

if (keys[VK_RIGHT] && (xspeed<2000)) xspeed+=1.0f;

if (keys[VK_LEFT] && (xspeed>-2000)) xspeed-=1.0f;

delay++; // Збільшити кольри

if (keys[VK_F1])// Якщо натиснено F1?

{

keys[VK_F1]=FALSE;

KillGLWindow();// Знащити поточне вікно

fullscreen=!fullscreen;// Відновлення вікна

if (!CreateGLWindow("Fire Simulation Based On Particles",1024,768,16,fullscreen))

{

return 0;// Quit If Window Was Not Created

}

}

}

}

}

// Вимикання

KillGLWindow();// Знищення вікна

return (msg.wParam);// Вихід з програми

}

Таким чином, ґрунтуючись на нескладній моделі поведінки вогню, мені вдалося ефективно реалізувати реалістичну імітацію оптичних процесів що виникають при горінні в повітряній атмосфері.

ВИСНОВКИ

В процесі написання курсової роботи була розглянута графічна бібліотека OpenGL з метою використання її в комп'ютерному моделюванні. Був розглянутий синтаксис команд та програмний код команд, а також бібліотеки, що відносяться до OpenGL.

Основним завданням цієї курсової роботи було максимально реалістично змоделювання горіння вогню.

Для вирішення завдання була написана програма на мові С з використанням технології OpenGL. Вона реалізує поставлене завдання на основі системи часток. Це найбільш простий і ефективний підхід, що показує непоганий результат і високу продуктивність, не накладаючи високі вимоги на відеоадаптер.

ЛІТЕРАТУРА

  1. Эйнджел Э. Интерактивная компьютерная графика. Вводний курс на базе OpenGL / Э. Эйнджел. 2001. – 590 с.

  2. Тихомиров Ю. Программирование трехмерной графики. Серия '' Мастер''. – СПб.: BHV-Санкт-Петербург. 2000. – 256 с.

  3. Майер Р. В. Компьютерное моделирование физических явлений / Р. В. Майер. – Глазов: ГГПИ, 2009. – 111 с.

  4. Мейсон Ву. OpenGL. Официальное руководство программиста / Ву Мейсон, Нейдер Д., Девис Т., Шрайнер Д. 2002. – 592 с.

  5. Роджерс Д. Алгоритмические основы машинной графики / Д. Роджерс. М.: Мир. 1989. – 512 с.

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Нет! Мы не выполняем работы на заказ, однако Вы можете попросить что-то выложить в наших социальных сетях.
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
4121
Авторов
на СтудИзбе
667
Средний доход
с одного платного файла
Обучение Подробнее