на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Використання OpenGL. Моделювання вогню
p align="left">Псевдокод зміненої версії приведеної вище програми, яка відображає плавно анімовану графіку, використовуючи при цьому подвійну буферизацію, міг би виглядати таким чином:

відкрити_вікно_в_режимі_подвійної_буфериэації(); for (i = 0; i < 1000000; i++){

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

намалювати_кадр(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.h>// Заголовочний файл Windows

#include <math.h>

#include <stdio.h>// Заголовочний файл вводу/виводу

#include <gl\gl.h>// Заголовочний файл бібліотеки OpenGL32

#include <gl\glu.h>// Заголовочний файл бібліотеки GLu32

#include <gl\glaux.h>// Заголовочний файл бібліотеки 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<MAX_PARTICLES;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<MAX_PARTICLES;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];// Вибір червоного кольору

Страницы: 1, 2, 3, 4, 5



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.