Lucrare de licență [306961]
Facultatea de Matematică și Informatică
Lucrare de licență
Dezvoltarea unui joc 3D
Coordonator: Student: [anonimizat] 2016
Cuprins
Capitolul 1. Introducere…………………………………………………………………………..pag
1.1. Ideea proiectului……………………………………………………………………pag
1.3. Structura lucrării………………………………………………………………………pag
Capitolul 2. Tehnologii folosite………….……………………………………………………pag
1.1. Despre ………..…………………………………………………………………….pag
1.2. Despre OpenGL………………………………………………………………….pag
Capitolul 3. Descrierea aplicatiei………………………………………………………………pag
Concluzii…………………………………………………………………………………………….[anonimizat]……………………………………………………..pag
Introducere:
De ce tema?
[anonimizat] e? Ce face?
Printscreen-uri cu descriere
Capitolul 1.
[anonimizat].
Deși, [anonimizat], [anonimizat], devenind o parte a culturii si civilizației tehnologiei moderne. [anonimizat](1):
[anonimizat], în special în predarea materiilor științifice: matematică, fizică, biologie, chimie etc.
[anonimizat] a [anonimizat], [anonimizat].
Inginerie – Reprezentarea grafică a unei idei sau a [anonimizat], [anonimizat], diagrame, [anonimizat] a cheltuiellor, previziuni și analiză.
[anonimizat], meteorologie, prospectarea resurselor etc.
Artă – [anonimizat] a permis inserarea acestora în tot mai multe producții cinematografice. [anonimizat] a compozitorilor muzicali.
Comerț – [anonimizat]. [anonimizat]: ambalaj, reclame.
Medicină – Grafica digitală și aplicațiile multimedia își fac tot mai des loc printre procedurile medicale: ecografii, tomografii, [anonimizat].
1.1. Ideea proiectului
Lucrarea de față a fost făcută în scopul susținerii dezvoltării prin joc. [anonimizat] o atenție sporită la detalii.
La vârste fragede, copiii dobândesc abilitățile și cunostințele pe baza a ceea ce văd în jurul lor. Astfel, jocurile se reflectă, în mare parte, în dezvoltarea lor și îi ajută să se integreze atât în mediul înconjurător, cât și în cel social. (5)
În zilele noastre, dezvoltarea tehnologiei a făcut ca, în rândul copiiilor, să dispară așa-zisele jocuri ale copilăriei. Încet, încet, au devenit tot mai populare jocurile virtuale, care pot duce la stagnarea nivelului de socializare al copiilor. Acest lucru le scade nivelul de socializare și îi predispune la tulburări comportamentale pe viitor. Pe lângă acestea, violența promovată în multe dintre jocurile video populare cresc riscul de agresivitate în rândul tinerilor.
Din rezultatele unui studiu realizat de cercetătorii de la Darmouth College din New Hampshire s-a constatat că aceste jocuri sunt asociate cu o paletă largă de comportamente riscante în rândul tinerilor. Potrivit acestora, se observă schimbări de personalitate și de atitudine, care îi fac pe tineri să devină mai impulsivi și să își asume mai multe riscuri, crescând astfel numărul de accidente rutiere și acte de violență. Printre factorii examinați s-a constatat legătura între acestea și frecvența cu care tinerii jucau jocuri de tipul Grand Theft Auto, Manhunt și Spiderman. (6)(7)
1.3. Structura lucrării
Lucrarea de față este structurată pe trei capitole:
Introducere
Tehnologii folosite
Despre aplicație
Capitolul 2.
Tehnologii folosite
Aplicația a fost creată în mediul de programare Java, folosind librăria OpenGL – Lightweight Java Game Library (LWJGL), iar implementarea acesteia a fost făcută în Eclipse.
2.1. Despre OpenGL
În ultimii ani, OpenGL (Open Graphics Library) a devenit un standard pentru programarea grafică 3D foarte utilizat în grafica asistată de calculator, realitate virtuală, vizualizare științifică, simulări de zboruri sau jocuri pe calculator. Acest ultim domeniu este în strânsă competiție cu tehnologia DirectX de la Microsoft. (2)
OpenGL își are originea în sistemul GL(“Graphics Library”) inventat de Silicon Graphics Inc. ca mod de programare pentru stațiile lor de lucru performante, specializate în grafică. În timp, interesul pentru portarea GL și pe alte tipuri de mașini a adus, în 1992, la crearea unei variații a GL-ului, numită OpenGL. Spre deosebire de GL, aceasta a fost proiectată să fie independentă de platformă, putând fi astfel, folosită pe diferite tipuri de hardware, nu doar pe mașinăriile Silicon Graphics.
OpenGL este o specificație standard care definește un API (Application Programming Interface) pentru programarea componentelor grafice și a programelor de calculator. Cu alte cuvinte, OpenGL definește un set de funcții folosite pentru realizarea programelor grafice.
Câteva dintre caracteristicile pe care OpenGL le oferă sunt următoarele:
Primitivele folosite în desenarea scenelor complexe: puncte, liinii, triunghiuri, poligoane;
Transformări de modelare și funcții de vizualizare pentru crearea scenelor 3D, folosind ideea de cameră virtuală;
Suportă randarea scenelor la o calitate superioară, prin eliminarea suprafețelor care nu se văd și prin includerea diferitelor tipuri de lumini, materiale, texturi, transparență, ceață.
Suportă manipularea imaginilor până la nivelul pixelilor, activând efecte cum ar fi anti-aliasing, neclaritatea cauzată de mișcare, adâncime și umbre.
O caracteristică cheie în proiectarea OpenGL este separarea interacțiunilor (date
de intrare si vizualizarea) de randare.
OpenGL însuși este bazat doar pe randare. Funcțiile sale sunt ușor de recunoscut pentru că numele fiecareia începe cu “gl”.
Cu timpul, au fost dezvoltate două librării care extind funcționalitatea OpenGL: GLU (OpenGL Utility Library) și GLUT (OpenGL Utility Library Toolkit).
GLU oferă funcții pentru desenarea unor primitive mai complexe decât cele din OpenGL, cum ar fi curbe sau planuri. De asemenea, funcții care ajută la specificații de vizualizare a scenelor 3D. Pentru diferențiere, toate încep cu “glu”.
GLUT asigură facilitățile pentru interacțiune care lipsesc în OpenGL. Pe lângă controlul ferestrelor și al acțiunilor mouse-ului și a tastaturii, GLUT oferă și câteva instrumente rudimentare pentru creara interfețelor grafice. Asemănător celorlalte două librării, toate funcțiile sale încep cu “glut”.
2.2. Despre GLSL si shadere
Un shader este o funcționalitate executată de procesorul grafic, la rularea unui joc. Acestea sunt programate folosind OpenGL Shading Language (GLSL), bazat pe sintaxa limbajului de programare C și a fost creat pentru a oferi dezvoltatorilor un mai mare control asupra coductei grafice (graphic pipeline).
Există două tipuri de shadere: Vertex Shader și Fragment Shader, care se apelează consecutiv.
Vertex Shader-ul infuențează atributele vertecșilor din modelele afișate. Acestea pot fi: poziție, culoare, coordonatele texturii.
Fragment Shader-ul este asemanător cu Vertex Shader-ul, dar se folosește pentru fiecare pixel individual. Aici se calculează, în general, culoarea și transparența fiecăruia. (8)
3. Structura aplicației
3.1. Ințializarea ferestrei
Aplicația este structurată într-o fereastră. Crearea acesteia se face în clasa DisplayManager, unde se folosesc elemente ale clasei Display a librăriei LWJGL. Aceasta este cea mai importantă clasa a librăriei LWJGL. Aici se creează și se controlează fereastra nativă în care este randat întreg conținutul grafic.
În acest sens, clasa Display conține trei metode:
create() – pentru crearea ferestrei. Pentru setarea dimensiunii acestuia se folosește metoda Display.setDisplayMode(new DisplayMode(WIDTH,HEIGHT)), unde WIDTH și HEIGHT sunt variabile statice finale, declarate în prealabil.
update() – este folosită repetitiv și are rolul de a actualiza conținutul display-ului la fiecare cadru, pentru menținerea aplicației deschisă. Astfel, se folosește metoda Display.sync(FPS) care permite aplicației să ruleze la un anumit număr de cadre pe secundă (fps – en. frames per second).
destroy() – distruge fereastra și curăță memoria utilizată de aceasta.
Testarea aplicației este făcută în clasa MainGameLoop. Aici este creată fereastra, folosind metoda descrisă mai sus.
Aceasta este urmată de un bloc repetitiv, while care se apelează cât timp fereastra este deschisă – !Display.isCloseRequested(). Aici, metoda prepare() din clasa MasterRenderer îl pregătește înaintea randarii fiecărui nou cadru, se creează obiectele, se actualizează fereastra, prin metoda update(), iar la final se curăță memoria și se închide fereastra.
3.2. Inițializarea modelelor
Realizarea desenelor grafice se face prin utilizarea mai multor primitive de desenare, oferite de OpenGL: puncte, linii, triunghiuri etc.
Un vertex este o reprezentare xyz a unei poziții în spațiul grafic. Dar, în același timp, xyz poate fi reprezentarea unui vector.
Un punct în spațiul grafic este, în egală măsură, și vertex și vector. (3)
Vectorii sunt fundamentali în reprezentările și transformarile geometrice. Combinația celor trei valori, xyz, reprezintă două aspecte importante: direcție și dimensiune.
Un vector reprezintă direcția de la originea sistemului de coordonate spre un punct din scenă.
Dimensiunea unui vector este lungimea acestuia. Normalizarea unui vector se referă la reducerea dimensiunilor coordonatelor acestuia, fără a afecta direcția, astfel încât lungimea sa să fie egală cu unu. Un vector de lungime unu se numește vector unitate sau versor.
VAO (Vertex Array Object) este un obiect care stochează toate informațiile necesare pentru randarea unui model (coordonate, culori, texturi etc.), ca tipuri diferite de date. Fiecare dintre aceste informații sunt stocate în buffere de memorie numite VBO (Vertex Buffer Objects).
Modelele 3D stocate în memorie sunt reprezentate prin obiecte de tipul clasei RawModel. Fiecare dintre acestea conține indicele din lista VAO și numarul de vertecși care il compun.
Pentru încărcarea modelelor în memorie se folosește clasa Loader, prin memorarea detaliilor despre acestea în lista VAO.
Crearea unei astfel de liste se va face prin metoda createVAO(). Funcția glGenVertexArrays() alocă spațiul necesar și returnează adresa acestuia. Fiecare tip de informație din această listă este stocat într-un VBO, prin metoda storeDataInAttributeList(). Aceasta primește ca parametri un întreg reprezentând indicele din VAO și un vector de tip float, reprezentând datele care urmează a fi memorate. Fiecare VBO se stochează în VAO prin apelarea funcției glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long buffer_buffer_offset).
Pentru desenarea unui model, OpenGL primește coordonatele vertecșilor unei mulțimi de triunghiuri care vor fi conectate între ele.
Într-un exemplu simplu, însă, dacă se dorește desenarea unui dreptunghi, în locul celor 4 vertecși, reprezentând vârfurile dreptunghiului, OpenGL va primi 6 – câte 3 pentru fiecare dintre cele două triunghiuri care îl compun.
În imaginea 3.a. se observă că V1 și V3 se repetă. Pentru a evita stocarea multiplă a aceluiași set de date, vom folosi un nou VBO, reprezentând indicii vertecșilor în ordinea de randare. Astfel, setul de date { (0,0,0), (1,1,0), (0,1,0), (0,0,0), (1,0,0), (1,1,0) } poate fi înlocuit cu { (0,0,0), (0,1,0), (1,1,0), (1,0,0) }, utilizați în ordinea { (0, 2, 3), (0, 1, 2) }.
Se observă că, la această reprezentare, ambele variante folosesc același spațiu de memorie. Pentru modelele mai complexe, însă, pe lângă setul de coordonate al vertecșilor, se adaugă cele ale texturilor, specificațiile normalelor etc. Astfel, se ajunge la diferențe de până la 50% între cele două variante, în ceea ce privește resursele folosite.
Definirea manuală a unui obiect este aproape imposibilă pentru modelele
complexe, deoarece implică un consum inutil de timp. Din acest motiv, modelele din scenă, sunt modele create în diferite programe de modelare 3D și importate in aplicație.
În aplicația descrisă modelele sunt fișiere .obj. Fiecare dintre acestea conține o listă a informațiilor necesare pentru randare, diferențiate prin litere la începutul fiecărui linii, reprezentând câte un set de date:
v – pozițille vertecșilor: v 0.158956 -0.263644 -2.882437
vt – coordonatele texturilor : vt 0.021651 0.995841
vn – coordonatele normalelor: vn 0.000000 -0.707083 0.707083
f – indicii de legătură pentru datele de mai sus: f 77/2/1 78/4/8 73/3/15, unde fiecare dintre cele 3 seturi reprezinta ordinea celor 3 tipuri de informatii. De exemplu 77/2/1 înseamna vertexul cu numarul 77, textura a 2-a si coordonatele primei normale.
În clasa OBJLoader se citesc datele din aceste fișiere și se stochează în funcție de descriptorul liniei. Ulterior, pentru fiecare vertex se face asocierea datelor în funcție de indicii citiți și se încarcă modelul în VAO.
Datele de intrare folosite în vertexShader sunt atributele din listele VAO. După prelucrarea acestora, noile rezultate sunt preluate de fragmentShader. Astfel, vor fi calculate datele de ieșire pentru fiecare pixel, în parte.
Însă, modele sunt influențate și de alți factori, diferiți de cei memorați în listele VAO. De exemplu, diferite surse și tipuri de lumină, ceață etc.
De asemenea, modificarea poziției unui obiect, ar însemna modificarea datelor din VAO și recompilarea shaderelor. Pentru depășirea acestor inconveniente, se folosesc variabile uniform, iar acestea pot fi modificate din programul Java in orice moment.
3.3. Texturi
În OpenGL, o textură este un obiect care conține una (texturi 2D) sau mai multe imagini cu același format (texturi de tipul cube map). Acestea sunt folosite pentru a oferi scenelor un aspect cât mai apropiat de realitate.
Procesul de texturare al unui model presupune copierea pixelilor din imaginea texturii pe suprafața modelului, prin asocierea texturii cu modelul, după cum se vede în imaginea …. .
Astfel, pentru fiecare model, se rețin și coordonatele texturii într-un camp VBO nou.
Pentru crearea unui fundal cât mai apropiat de realitate și folosind cât mai puține resurse, se înconjoară scena într-un cub texturat, numit skybox. Acesta conține toate modelele vizibile și depinde de poziția camerei astfel încât, camera rămâne mereu în mijlocul cubului, fără a putea ajunge la vreuna dintre marginile sale.
În acest sens, se folosesc texturile de tip cube map. Acestea sunt combinații de câte 6 texturi, fiecare dintre ele reprezentând una dintre fețele unui cub, dar folosite ca un întreg. Imaginea … este un exemplu al unei astfel de texturi.
Diferența dintre acest tip de textură și o textură simplă 2D este în modul de accesare al pixelilor. Dacă pentru texturile 2D se folosesc coordonate bidimensionale, pentru acestea va fi nevoie și de coordonata z.
În clasa Loader.java este implementată metoda
public int loadCubeMap(String[] textureFiles){
int texID = GL11.glGenTextures();
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texID);
for(int i=0;i<textureFiles.length;i++){
TextureData data = decodeTextureFile("res/" + textureFiles[i] + ".png");
GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL11.GL_RGBA, data.getWidth(), data.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data.getBuffer());
}
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
textures.add(texID);
return texID;
}
Aceasta primește ca parametri un șir de caractere, reprezentând numele celor 6 texturi. Se activează și se validează textura TEXTURE0, ca textură de tip cube map. Ulterior, se citesc și se încarcă fiecare dintre cele 6.
Simularea mișcării norilor se face prin modificarea matricii de vizualizare înainte de încărcarea acesteia în shader, prin rotirea acesteia pe axa y.
3.5. Lumini
Un factor important în reprezentarea modelelor 3D este lumina (sau lipsa ei). O sferă arată ca un simplu cerc plin, dacă nu are lumină și umbre (imaginea … ). Pentru a da imaginii un aspect cât mai realist, trebuie ținut cont de efectele iluminării asupra obiectelor modelate.
În OpenGL, tipurile de lumină folosite pentru redarea unei scene pot fi reduse la următoarele:
Lumina ambientală – este tipul de lumină la care nu i se poate stabili o sursă, apare ca venind din toate direcțiile. În general, este rezultatul unui amestec între raze de lumină provenite de la diferite surse de lumină și/sau reflexii repetate. (4) Acest tip de lumină nu schimbă modul în care sunt văzute obiectele, pentru că felul în care aceasta afectează suprafața lor este aceeași indiferent de orientare.
Lumina difuză – este lumina provenită dintr-o singură direcție și intensitatea sa depinde de cât de aproape este sursa luminoasă de obiect. Odată ajunsă la un obiect,
Lumina speculară – este lumina reflectată din obiecte. Acest efect oferă strălucire obiectelor.
Lumina emisă – este lumina pe care un obiect o emite. Se folosește pentru obiectele incanescente (lămpi, foc, becuri etc.)
În aplicația descrisa, modul în care lumina influențează modelele este calculat în shadere. Pentru acesta, pe lângă poziția luminii, este important de știut care dintre fețele modelului sunt îndreptate spre sursa de lumină și cât de mult. Acest lucru se calculează folosind pozițiile normalelor.
Fiecare vertex al modelului are o normală care indică exact direcția spre care este îndreptat vertexul. Normalele sunt vectori perpendiculari pe suprafața modelului.
Pentru fiecare punct din model se cunosc cei doi vectori: normala și direcția spre sursa de lumină. Intensitatea acesteia asupra modelului depinde de cât de apropiați sunt aceștia. Astfel, un punct de intensitate maximă va avea ambii vectori îndreptați în aceeași direcție, pe când un punct de intensitate minima va avea cei doi vectori îndreptați în direcții opuse. În acest sens, se calculează produsul scalar al celor doi, cu mențiunea că aceștia trebuie să fie normalizați. Dacă vectorii sunt îndreptați în aceeași direcție, produsul lor scalar este egal cu 1, dacă sunt perpendiculari 0, iar dacă sunt îndreptați în direcții opuse, -1. Oricare altă valoare se va încadra în intervalul [-1,1].
3.6. Modelele din scenă
Fiecare model din scena este definit ca un obiect de tip Entity. Acesta este, de fapt, o instanță a unui obiect de tip TexturedModel, pentru un mai bun management al memoriei.
Un obiect TexturedModel, o dată încarcat în memorie, poate fi randat de mai multe ori, folosind tranformări ale modelelor. Acestea sunt rezultatele unor transformări geometrice combinate: translație, rotație și scalare.
Aceste transformări sunt făcute în clasa Maths, unde este implementată metoda:
public static Matrix4f createTransformationMatrix(Vector3f translation, float rx, float ry, float rz, float scale) {
Matrix4f matrix = new Matrix4f();
matrix.setIdentity();
Matrix4f.translate(translation, matrix, matrix);
Matrix4f.rotate((float) Math.toRadians(rx), new Vector3f(1,0,0), matrix, matrix);
Matrix4f.rotate((float) Math.toRadians(ry), new Vector3f(0,1,0), matrix, matrix);
Matrix4f.rotate((float) Math.toRadians(rz), new Vector3f(0,0,1), matrix, matrix);
Matrix4f.scale(new Vector3f(scale,scale,scale), matrix, matrix);
return matrix;
}
Aceasta va primi ca parametri un vector cu valorile de translație, unghiul de rotație pentru fiecare dintre cele 3 axe și factorul de scalare.
3.7. Camera virtuală
Pentru imagini tridimensionale, se folosește matricea de proiecție. Aceasta funcționează precum o cameră de luat vederi. Cu cât se află mai departe de cameră, obiectele apar mai mici.
În schema … se observă forma matematică a matricei de proiecție, unde a=raportul înălțimea/lățimea display-ului; fov=unghiul câmpului vizual; znear=planul apropiat; zfar=planul îndepărtat.
Pe lângă aceste matrici, un alt factor care influențează locul în care se randează obiectele este poziția din care utilizatorul vede scena.
Pentru că nu există o cameră propriu-zisă, se creează iluzia uneia, prin mutarea întregii scene în direcția opusă. În acest sens, în clasa Maths este implementată metoda createViewMatrix().
În imaginile … se observă diferite ipostaze ale aceeași scenă, din perspective diferite.
3.8. Optimizarea randării
La vizualizarea unei scene, fără alte setari, fiecare model va fi randat în întregime, inclusiv parțile care nu se văd. Acest lucru încarcă inutil memoria. Pentru oprimizare, se setează glEnable(GL11.GL_CULL_FACE) și glCullFace(GL11.GL_BACK) astfel încât fețele care nu sunt îndreptate spre cameră să nu fie desenate.
3.9. Crearea terenului
Crearea unui teren în scenă se poate face relativ simplu, din cod, fără a fi nevoie de importarea acestuia din alte programe de modelare 3D, datorită faptului că se bazează pe o schemă precisă de desenare a vertecșilor. Imaginea … este o reprezentare a modului în care sunt așezați aceștia, la distanțe egale, pe cele două axe (x și z).
Din cauza dimensiunii mari a terenului, întinderea unei texturi pe întreaga suprafață îi oferă un aspect nerealist. Din acest motiv, una dintre soluții este folosirea aceleiași texturi, în mod repetat (en. tile), prin creșterea dimensiunilor coordonatelor texturii.
Această modalitate, însă, se poate folosi doar pentru o textură unifomă. În cazul în care se dorește un drum, de exemplu, desenarea lui în textură nu ar reda rezultatul dorit. Ca răspuns la acest inconvenient, folosirea multi-texturării implică utilizarea unui șablon, care să indice unde și cum vor fi randate fiecare textură.
Imaginea … reprezintă șablonul folosit pentru terenul din aplicația descrisă. Fiecare culoare indică o textură, iar modul în care acestea influețează imaginea finală a terenului este implementat în shaderele terrainVertexShader și terrainFragmentShader.
În terrainFragmentShader, texturile sunt accesate prin variabile de tip uniform sampler 2D.
Pentru generarea unui teren denivelat, cât mai realistic, aplicația folosește o hartă de înălțimi. Aceasta este o imagine alb-negru (…) folosită ca șablon pentru crearea înălțimilor, direct proporțional cu intensitatea culorii, astfel: punctele de culoare închisă reprezintă o altitudine mică, iar cele de culoare deschisă, altitudini mari.
În clasa Terrain.java se setează culoarea și înălțimea maximă pe care un punct poate să le aibă. În funcție de aceste informații, se calculează înălțimea fiecărui pixel, în parte.
După crearea altitudinii, însă, normalele vertecșilor care compun terenul trebuie recalculate. O modalitate simplă, folosită în acest scop este de a aproxima normala unui vertex, prin calcularea înălțimilor a 4 vertecși care îl înconjoară. Rezultatul este memorat într-o variabilă de tip Vector3f normal, care va avea următoarele coordonate: heightL-heightR, 3, heightD-heightU, unde heightL = înălțimea vertexului stâng, heightR = înălțimea vertexului drept, heightD = înălțimea vertexului de dedesubt, heightU = înălțimea vertexului de deasupra. Valoarea coordonatei y influențează intensitatea cu care se observă diferențele de altitudine.
pt y=1.
pt y=3.
În imaginea … se pot observa atât efectele multi-texturării, cât și cele ale adăugării înălțmilor terenului.
3.10. Ceața
Ceața poate fi simulată într-o scenă prin modificarea graduală a culorii obiectelor, pe măsura ce acestea se îndepărtează de cameră, prin crearea unui amestec între culoarea obiectului și culoarea fundalului.
Una dintre metodele de calcul ale culorii este printr-o ecuație liniară. Considerăm variabila viz care, în funcțe de distanța obiectului față de cameră poate lua valori între [0,1]. Astfel, se setează o distanță până la care obiectele nu sunt afectate de ceață, unde vizibilitatea=1, o distanță după care sunt afectate în totalitate de ceață, unde vizibilitatea=0, iar între cele două, vizibilitatea scade liniar, direct proporțional cu distanța de la cameră (imaginea ….).
Deși aceasta este cea mai ușoară metodă, rezultatul final nu oferă un aspect real. În schimb, dacă vizibilitatea scade exponențial, după cum se vede în graficul din figura …, imaginea finală va fi mai apropiată de reaitate.
Pentru această metodă, ecuația de calcul este vizibilitatea = e ^ -(distance*density(densitatea ceții)) ^ gradient(cât de repede scade vizibilitatea, odată cu distanța).
Acest calcul se efectuează în vertexShader, care va transmite ulterior rezultatul fragmentShader-ului.
3.11. Crearea elementelor grafice 2D
În aplicația descrisă există și modele 2D randate. Acestea sunt, de fapt, simple dreptunghiuri texturate. Modelarea lor se face în clasa GuiTexture.java, iar pentru crearea și memorarea lor se folosește o metodă similară, dar simplificată a celei de încărcare a modelelor 3D. Aici, fiecare obiect de tipul clasei, primește ca parametru o textură, o poziție bidimensonală și un vector bidimensional care conține factori de scalare.
Poziția reprezintă centrul dreptunghiului, iar fiecare dintre cei doi factori de scalare reprezintă dimensiunile acestuia pe axele x și y, în relație cu dimensiunea ferestrei.
Pentru aceasta, se încarcă un singur dreptunghi, de dimensiunea ferestrei, care poate fi folosit ca bază pentru diferitele texturi folosite în crearea mai multor elemente 2D.
Coordonatele texturilor se calculează direct în guiVertexShader, fără a mai fi nevoie de stocarea acestora ca atribute în listele VAO, astfel:
textureCoords = vec2((position.x+1.0)/2.0, 1 – (position.y+1.0)/2.0), considerând imaginea … , unde coordonatele texturii sunt trecute cu roșu.
Pentru randarea acestora, obiectele de tip GuiTexture se transmit ca listă metodei render(List<GuiTexture> guis), implementată în clasa GuiRenderer.java
3.12. Interacțiunea folosind mouse-ul
Concluzii
Acest proiect a fost făcut pentru lucrarea de licență și certifică aptitudinile de creare a unei aplicații funcționale în mediul de programare Java.
Având în vedere evoluția tehnologiei, în special a tehnologiilor gadgeturilor portabile, următorul și cel mai necesar pas în dezvoltarea aplicației este extinderea acesteia pe diferite platforme mobile.
Bibliografie
https://ro.wikipedia.org/wiki/OpenGL
http://ninjacave.com/tutorials
https://www.opengl.org/wiki
D. Petcu, L. Cucu, Computer Graphics Principles (in Romanian), Ed. Excelsior, 1995
http://mec.upt.ro/dolga/
https://ro.wikipedia.org/wiki/Shader
http://sse.tongji.edu.cn/linzhang/ACG12/opengl.pdf An Introduction to Graphics Programming with Tutorial and Reference Manual Toby Howard School of Computer Science University of Manchester
OpenGL SUPERBIBLE Fifth Edition – Richard S. Wright Jr., Nicholas Haemel, Graham Sellers, Benjamin Lipchak, Ed. Addison-Wesley
References
D. Petcu, L. Cucu, Computer Graphics Principles, Ed. Excelsior, 1995
https://ro.wikipedia.org/wiki/OpenGL
OpenGL SUPERBIBLE Fifth Edition – Richard S. Wright Jr., Nicholas Haemel, Graham Sellers, Benjamin Lipchak, Ed. Addison-Wesley
http://432x.ncss.ro/Anul%20III/PG/Laborator8TI_2015.pdf
http://www.mariposakids.ro/educatia-prin-joc-poveste-si-arta.html
STUDIU: Jocurile video violente, asociate cu riscul de delincvenţă şi abuzul de alcool
http://now.dartmouth.edu/2014/08/new-study-video-games-and-teens-behavior
https://ro.wikipedia.org/wiki/Shader
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Lucrare de licență [306961] (ID: 306961)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
