Рефераты. Використання OpenGL. Моделювання вогню

В даному випадку програма для моделювання горіння вогню була написана на основі системи часток. Ці частки моделюють різні шари - "домени" іонізованого повітря і їх випадковий рух в просторі. В ході руху ці шари-частки світяться, поступово втрачаючи яскравість. У цій програмі використовується лінійна інтерполяція загасання яскравості шарів. Напрям і величина початкової швидкості вибирається випадково в деякому діапазоні. Так само випадково вибирається і так звана швидкість гасіння частки - швидкість, з якою задана частка втрачає яскравість свого світіння. Вважається, що початкова величина яскравості частки дорівнює одиниці. Для імітування архімедівської сили, що піднімає шари повітря, використовується "антигравітація", тобто умовно задається середній напрям прискорення руху. Для розрахунку руху часток використовується метод Ейлера в простому своєму варіанті. Цього вистачає, оскільки рух окремої частки в даному випадку неважливий - нам необхідно створити випадковий розподіл руху часток для відтворення хаотичної динаміки досліджуваного явища. Ну і нарешті не менш візуально важливим параметром є колір вогню. Світловий спектр вогню можна вважати схожим із спектром Сонця. У програмі використовується лише чотири кольори з червоної області спектру по черзі змінюючі один-одного. Ось їх значення в системі 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;

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



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.