Simulator grafic 3D integrabil în aplicații grafice multiple [608506]

Universitatea POLITEHNICA din București
Facultatea de Automatică și Calculatoare
Departamentul Automatică și Informatică Industrială
LUCRARE DE LICENȚĂ
Simulator grafic 3D integrabil în aplicații grafice multiple
Îndrumător: Absolvent: [anonimizat].dr.ing. Ștefan Mocanu Stanciu Daniel
Consultant Tehnic:
ing. Romeo Cojocaru
București
2018

Cuprins
1 Introducere 1
1.1 Scopul lucrării . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Organizarea lucrării . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Stadiul actual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 OpenGL vs DirectX . . . . . . . . . . . . . . . . . . . . . . 3
1.3.2 Motorul grafic Unity . . . . . . . . . . . . . . . . . . . . . . 6
2 Prezentarea generală a lucrării 9
3 Dezvoltarea aplicațiilor 3D folosind DirectX 11 11
3.1 Spații de coordonate . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Arhitectura Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3 Fluxul de lucru Direct3D11(D3D11) . . . . . . . . . . . . . . . . . . 16
3.4 Resurse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5 Arhitectura software de grafică a sistemului de operare Windows . . . 25
4 Arhitectura bibliotecii Tungsten 28
4.1 Tungsten3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.2 Tungsten2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.3 Tungsten Osmosis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.4 Tungsten Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.5 Locatorul de servicii Tungsten . . . . . . . . . . . . . . . . . . . . . 35
5 Implementarea bibliotecii Tungsten 37
5.1 Implementarea motorului grafic . . . . . . . . . . . . . . . . . . . . 38
5.2 Încărcarea modelelor . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.3 Integrarea Tungsten în aplicațiile de tip Win32 . . . . . . . . . . . . . 44
5.3.1 Bucla interactivă . . . . . . . . . . . . . . . . . . . . . . . . 45
i

CUPRINS ii
5.3.2 TungstenUI . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.4 Integrare WPF folosind fereastră compusă . . . . . . . . . . . . . . . 51
5.5 Integrare WPF folosind fereastră secundară . . . . . . . . . . . . . . 53
5.6 Integrare WPF folosind HWNDHost . . . . . . . . . . . . . . . . . . 55
5.7 Integrare WPF folosind imagine editabilă . . . . . . . . . . . . . . . 56
6 Concluzii și dezvoltări ulterioare 60

Listă de figuri
1.1 Proiect ELF[4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Imagine generată de Pixie Graphics . . . . . . . . . . . . . . . . . . 4
3.1 Spațiul UV în DirectX(stânga) față de OpenGL(dreapta) . . . . . . . 12
3.2 Înmulțirea vector-matrice, în sistemul DirectX . . . . . . . . . . . . . 12
3.3 CPU fără arhitectură Pipeline . . . . . . . . . . . . . . . . . . . . . . 13
3.4 CPU cu Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 Ramuri condiționale în arhitectură WARP . . . . . . . . . . . . . . . 15
3.6 Stagii de procesare Direct3D11 . . . . . . . . . . . . . . . . . . . . . 17
3.7 Exemplu de interpolare a triunghiului . . . . . . . . . . . . . . . . . 19
3.8 Texturi volumetrice (jos), și texturi cubice (sus) . . . . . . . . . . . . 23
3.9 Mipmapping pentru texturi 2D . . . . . . . . . . . . . . . . . . . . . 23
3.10 Mipmapping pentru vectori 1D . . . . . . . . . . . . . . . . . . . . . 24
3.11 Filtrarea anizotropică pentru o imagine 2D . . . . . . . . . . . . . . . 24
3.12 Arhitectura ATI Catalyst© în model XPDM[5] . . . . . . . . . . . . 26
3.13 Arhitectura ATI Catalyst© în model VDDM [5] . . . . . . . . . . . . 27
4.1 Arhitectura Tungsten3D . . . . . . . . . . . . . . . . . . . . . . . . 32
5.1 Valuri sinusoidale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.2 Valuri Gerstner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.3 Scena de test pentru comparația timpului de încăracre a fișierelor OBJ
vsBMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.4 Ineficiența unei bucle libere . . . . . . . . . . . . . . . . . . . . . . . 47
5.5 Ineficiența unei bucle rapide, sincronizată . . . . . . . . . . . . . . . 47
5.6 Ineficiența unei bucle încete, sincronizată . . . . . . . . . . . . . . . 47
5.7 Buclă adaptivă . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.8 Suprasolicitarea co-procesorului grafic . . . . . . . . . . . . . . . . . 50
iii

LISTĂ DE FIGURI iv
5.9 Înfometarea co-procesorului grafic . . . . . . . . . . . . . . . . . . . 50
5.10 Implementarea Tungsten folosind fereastră secundară . . . . . . . . . 54
5.11 Aranjare în memorie a unei texturi bidimensionale . . . . . . . . . . 58

Listă de tabele
5.1 Compararea timpului de încărcare pentru fișiere OBJșiBMD . . . . . . 44
v

Capitolul 1
Introducere
1.1 Scopul lucrării
Scopul principal al acestui proiect este de a propune un mod de lucru în
dezvoltarea aplicațiilor cu conținut 3D. Un motor grafic (denumit Tungsten) va fi
implementat folosind tehnici curente în dezvoltarea acestor aplicații, după care acesta
va fi transpus într-o bibliotecă (TungstenOsmosis) ce poate fi integrată într-un sistem
de dezvoltare al aplicațiilor cu interfață grafică. Motorul grafic va genera imaginile
simulate folosind accelerare hardware în timp ce elementele de control vor fi
dezvoltate într-un mediu specializat în acest sens.
Se propune o implementare ce folosește mai multe limbaje de programare
(C++ și C#). Prin folosirea unei platforme comune aceste limbaje vor implementa
componente diferite ale aplicației. Limbajele prezintă avantaje fie prin trăsăturile lor
intrinseci (control manual sau automat al memoriei, interoperabilitatea cu alte limbaje
etc.), fie prin bibliotecile implementate în fiecare dintre aceste limbaje. Se dorește
evidențierea faptului că efortul de implementare este redus atunci când se valorifică
avantajele fiecărui limbaj.
Se va dezvolta o aplicație pe baza acestei biblioteci. Aplicația va avea atât parte
de simulare tridimensională accelerată hardware dar și o interfață grafică cu utilizatorul
complexă ce permită controlul facil al parametrilor de simulare.
1

CAPITOLUL 1. INTRODUCERE 2
1.2 Organizarea lucrării
Primul capitol al lucrării introduce domeniul graficii în informatică și prezintă
o implementare deja existentă asemănătoare cu proiectul prezentat. În acest capitol
se vor prezenta cele două biblioteci consacrate de grafică tridimensională, OpenGL și
DirectX, istoria care a dus la impunerea fiecăreia într-un segment de piață și modul în
care acestea au fost în conflict.
Al doilea capitol constă într-o prezentare pe scurt a lucrării, obiectivelor sale și
modul în care acestea au fost îndeplinite. Rolul acestuia este de a prezenta o imagine de
ansamblu a întregului proiect urmând ca capitolele ce urmează să detalieze conceptele
sau domeniile prezentate.
Al treilea capitol constă într-o prezentare generală a bibliotecii de grafică
utilizată în acest proiect. Se vor prezenta diversele concepte cu care lucrează acesta,
motivele pentru care e structurată în acest mod dar și rolul și poziționarea acesteia în
sistemul de operare Windows.
Al patrulea capitol prezintă arhitectura sistemului Tungsten. Deciziile
arhitecturale și motivațiile acestora sunt separate în funcție de componenta asupra
căreia se aplică acestea. Componentele reprezintă grupări de clase și concepte care se
pot evidenția și în codul sursă al proiectului.
Capitolul 5 prezintă detalii de implementare considerate importante și
problemele ce au apărut la integrarea Tungsten în alte sisteme de creare a aplicațiilor.
Se dau detalii despre implementarea motorului grafic după care se prezintă mai multe
tentative de implementare și rezultatele acestora.
Ultimul capitol prezintă concluziile acestui proiect și posibilitatea dezvoltării
ulterioare. Se vor compara diversele implementări prezentate în capitolul precedent și
se vor evidenția cele considerate utile. Prin această analiză se vor identifica lipsurile
dar și potențialele căi de extindere și îmbunătățire ale proiectului.
1.3 Stadiul actual
Apariția acceleratoarelor 3D pentru consumatorii obișnuiți a fost fructificată de
industria divertismentului. Aceasta a exploatat noua sursă de putere computațională,

CAPITOLUL 1. INTRODUCERE 3
aducând în piață experiențe interactive de o foarte mare fidelitate în forma jocurilor
video.
Comunitatea științifică face pași timizi în adoptarea noilor tehnologii doar de
câțiva ani. Tehnicile de grafică 3D nu au avut parte de atenție în comunitățile științifice
datorită utilității reduse a acestor tehnologii, dezvoltate cu preponderență în scopuri
comerciale, accentuată de rata foarte rapidă de dezvoltare a co-procesoarelor grafice
ce duceau la o instabilitate a mijloacelor de dezvoltare a aplicațiilor 3D (biblioteci,
compilatoare etc.). Din aceste cauze pentru o perioada îndelungată de timp aplicațiile
3D accelerate hardware nu au fost văzute ca o parte integrală a simulării științifice.
Primele Unități de Procesare Grafică cu Scop General (en. General Purpose
Graphical Processing Unit – GPGPU-uri ) au reprezentat o revoluție în materie de
operațiuni matematice de complexitate mare. Capacitatea ridicată de calcul paralel a
adus co-procesoarele grafice în prim plan într-o arie foarte diversă a științei, cum ar fi
in chimie [ 19], economie [ 6] sau biologie [ 21].
În ciuda influenței majore pe care o au diversele studii științifice, acestea nu
au devenit foarte vizibile pentru publicul larg. Totuși au fost și proiecte științifice ce
au atras atenția unei comunități mai largi precum ”FoldIt”. Acesta s-a bucurat de
interesul public deoarece era prezentat sub forma unui joc 3D interactiv, dar care era
totuși construit pe ultimele informații din domeniul chimiei computaționale.
Odată cu apariția tehnologiilor de Realitate Virtuală se întrevede o nouă
revoluție în domeniul graficii 3D. Astfel domenii precum psihologia [ 14] vor avea
nevoie de aplicații 3D de fidelitate și eficiență ridicate.
Cu toate acestea, dezvoltarea aplicațiilor 3D continuă să fie dificilă, fiind
necesare cunoștințe specializate. Cele mai populare biblioteci, sau medii integrate de
dezvoltare ce ar putea simplifica dezvoltarea acestor aplicații sunt de natură
comercială, ceea ce le face incompatibile datorită prețului ridicat sau considerentelor
de natura legală (licențe, drepturi de autor, etc.).
1.3.1 OpenGL vs DirectX
Primele cipuri grafice dezvoltate erau primitive și simple neputând fi
considerate drept ”acceleratoare grafice” sau ”co-procesoare grafice”. Majoritatea nu
erau nimic altceva decât shift-ere grafice. Procesorul central construia imaginea

CAPITOLUL 1. INTRODUCERE 4
grafica, după care era trimisă către cip care apoi transfera câte un octet către ieșirea
grafică.
Un asemenea dispozitiv este CDP 1861 LSI, lansat în anii ’70. Acesta avea
256 octeți de memorie și interfața direct cu un procesor 1802. Ieșirea avea o rezoluție
de 128×64 pixeli monocrom. Prin adăugarea unui circuit 1861 generator de culoare
ieșirea putea fi color. Prin reducerea rezoluției, aceeași memorie tampon putea conține
mai mult de 1bit / pixel, permițând astfel informații ce țineau de culoarea finală a pixel-
ului rezultat [ 1].
Figura 1.1: Proiect ELF[ 4]
Figura 1.2: Imagine generată de Pixie
Graphics
În 1978, Motorola lansează acceleratorul de adrese video MC6845. Acesta a
devenit cel mai folosit generator video al calculatoarelor personale din prima generație.
A fost folosit pentru calculatorul personal Apple II și Tandy TRS-80, printre altele.
Acesta nu genera pixelii, dar crea semnalul de sincronizare necesar pentru a transpune
o zona de memorie în semnal de ieșire video. A devenit consacrat în rândul comunității
demo-scene deoarece valorile ceasului pot fi manipulate în mod direct. Astfel, prin
controlul acelor valori se poate controla cu finețe zona de ecran ce va fi modificata.
Cipul începe un nou cadru atunci când registrul de ceas ajunge la o valoare de depășire
a capacității de stocare (en. overflow ). Astfel, prin setarea externa a acestei valori
circuitul va începe să afișeze următorul cadru, lăsând zone din ecran nemodificate.
Această tehnică poate fi folosită pentru separa imaginea în zone statice și dinamice
[16].
În august 1985 compania Array Technology Incorporated a fost fondată. În mai
puțin de un an aceasta a primit deja consacratul nume ATI Inc. Primul produs lansat
OEM Color Emulation Card avea 16kB de memorie și producea un semnal monocrom
verde, portocaliu, sau alb pe un fundal negru. A fost un mare succes comercial în
principal datorită contractului de 7000 de dispozitive pe săptămână către Commodore
Computers [ 24].
În ianuarie 1992 a fost lansată versiunea 1.0 a bibliotecii OpenGL. Compania
deținătoare, Silicon Graphics Incorporated, a decis să-și deschidă API-ul proprietar, în

CAPITOLUL 1. INTRODUCERE 5
special către piața de sisteme UNIX. Datorită ușurinței în folosire, a fost repede adoptat
de către dezvoltatorii acelui deceniu.
O nouă eră a jocurile pe calculator a apărut. Lansarea jocului Doom în 1993 a
reprezentat unul dintre primele și cel mai faimos joc 3D din acea perioadă. Conform
lui Gabe Newell ”a devenit unul dintre cele mai folosite programe în Statele
Unite”[ 7]. Acest fenomen a împins Microsoft să creeze propria bibliotecă 3D pentru
Windows. Ținta principală erau aplicațiile profesionale (CAD, modelare 3D), dar
datorită succesului jocului Doom și mai târziu Quake, Microsoft a portat DOOM pe
Windows 95, folosind propria bibliotecă numită Direct3D.
Direct3D a fost apoi inclus într-o bibliotecă de dezvoltare de jocuri mai
cuprinzătoare numită DirectX. Microsoft încerca să atragă dezvoltatorii cu o soluție
integrată ce oferea suport pentru dispozitive de intrare (mouse, tastatură, joystick),
sunet, grafică 2D și 3D, într-un singur pachet [ 8].
Comisia de revizie a arhitecturii OpenGL (OpenGL Arhitecture Review
Board) este organizația însărcinată sa mențină și să extindă standardul OpenGL.
NVIDIA deține o poziție influentă în această comisie. Folosindu-și poziția NVIDIA
introduce în standard extensia GL_ARB_multitexture pentru cipul TNT1.
Multitexturarea este o tehnică ce permite unui model 3D sa eșantioneze mai multe
texturi în același timp. Deși nu este o tehnică imposibil de emulat folosind alte
co-procesoare, suportul hardware permitea dispozitivului de la NVIDIA sa facă
asemenea operațiuni într-un mod mai eficient. La lansarea DirectX 5, în 1997,
acestuia îi lipsea această funcționalitate, ceea ce reprezenta un dezavantaj major față
de competiție [ 24].
Următoarea inovație majora în domeniul graficii computerizate a fost
reprezentată de Hardware T&L (Transform & Lighting). Aceasta permitea
accelerarea calculelor de transformare 3D (translație, scalare, rotație) și a algoritmilor
de iluminare de tip Blin-Phong. Prima placa grafică capabilă de Hardware T&L a fost
NVIDIA GeForce 256, în 1999. DirectX nu a avut suport pentru aceasta
funcționalitate până la apariția versiunii 7, în anul 2000.
Versiunea 9 a bibliotecii DirectX a fost lansată în parteneriat cu NVIDIA. Cipul
GeForce 3 a fost lansat cu o funcționalitate revoluționară numita ”shader programabil”
[2] (shader – program special, rulat pe cipul grafic). Asta permitea dezvoltatorului sa
încarce cod scris către stagiile din lanțul de procesoare (”pipeline”). Înainte de aceasta
funcționalitate, programatorul putea doar parametriza o serie de algoritmi predefiniți

CAPITOLUL 1. INTRODUCERE 6
(”fixed pipeline”). Pentru a programa aceste stagii a fost dezvoltat un limbaj nou, numit
HLSL (High Level Shading Language). După separarea dintre NVIDIA și Microsoft,
producătorul de cipuri grafice a redenumit dialectul propriu de HLSL cu numele Cg(C
pentru Grafică – en. C for Graphics ).
Versiunea 1.1 a HLSL a fost lansată în parteneriat cu ATI, aducând cele două
companii producătoare de plăci video într-o noua epocă a competiției. Deoarece
Microsoft a blocat cei doi producători pe platforma DirectX, OpenGL a pierdut din
popularitate, menținându-se doar pe sisteme de tip UNIX sau în cazul dezvoltării
aplicațiilor multi-platformă.
Datorită dezavantajului major în domeniul shaderelor programabile, 3D Labs
încearcă sa dezvolte OpenGL 2.0, care trebuie să aibă suport pentru pentru shadere.
Numit ”Limajul de shadere GL” (en. GL Shader Language – GLSLS), acesta a fost
un eșec major. Un dezavantaj major față de DirectX era faptul că compilarea se făcea
într-un singur pas, din reprezentare textuală, în cod nativ. DirectX conținea și un stagiu
intermediar în care reprezentarea textuală a programului era mai întâi tradusă într-un
limbaj de asamblare specific. Deoarece nu exista acest pas intermediar programatorul
nu putea inspecta manuala codul de asamblare, pentru a evita erori de compilare sau
pentru a optimiza rutine. Această decizie, combinată cu lipsa de experientă a 3D Labs
în dezvoltarea compilatoarelor a făcut ca GLSL sa fie un limbaj instabil și ne-portabil
între platforme.
Ultima tentativă a fost reprezentată de proiectul ”Longs Peak”(un vârf muntos
din Munții Stâncoși), pornit de către Comisia de Revizie a Arhitecturii OpenGL
(OpenGL ARB). Datorită amânărilor multiple proiectul întârzie. Până la publicarea
noului API OpenGL domeniul graficii pe calculator este dominat de DirectX,
considerat deja implementarea de referință pe Windows, cel mai popular sistem de
operare.
1.3.2 Motorul grafic Unity
Singurul proiect public care satisface aceeași nevoie ca Tungsten este Unity,
dezvoltat de către Unity Technologies. Acesta permite scrierea aplicațiilor 3D
interactive folosind limbajul de programare C#. Motorul grafic propriu-zis este apelat
din codul-utilizator care folosește o interfață abstractizate a nucleului, scris în
limbajul C++.

CAPITOLUL 1. INTRODUCERE 7
Unity este folosit pentru dezvoltarea aplicațiilor grafice interactive atât
comerciale (jocuri[ 25] și vizualizări arhitecturale[ 27]) cât și științifice [ 28] [10].
Suita de unelte ce vin integrate în această aplicație au adus Unity la o cotă de
piață foarte ridicată.Aproximativ 4,2 miliarde de download-uri au adunat cele 220 de
mii aplicațiile mobile ce folosesc Unity, până la începutul anului 2016[ 25]. Costul
redus este un factor foarte important pentru companiile, de obicei de dimensiuni mici,
ce funcționează pe această piață.
Prima versiune a fost lansată în 2005 de către David Helgason, Joachim Ante
și Nicholas Francis. Scopul acestora a fost să ”democratizeze industria de dezvoltare
a jocurilor” [ 23]. La început Unity a fost lansat doar pentru MacOS, dar în prezent
funcționează pe 27 de platforme, printre care iOS, Windows, Android, WebGL,
Playstation 4 și altele.
Versiunea 1.1 a adăugat suport pentru Windows, dar mai ales pentru web.
Plugin-ul Unity a apărut într-o perioadă de creștere a jocurilor web astfel că a devenit
un competitor pentru tehnologia Flash, de la Adobe. În prezent plugin-ul web nu mai
este oferit de către Unity, fiind înlocuit de o implementare ce folosește WebGL.
Doi ani mai târziu apare versiunea 2.0, aceasta adaugă suport pentru DirectX,
și îmbunătățește compatibilitatea componentei web cu mai multe platforme.
Implementarea DirectX a dus la o îmbunătățire a performanței pe Windows de 30%
[3].
Odată cu creșterea numărului de utilizatori se accentuează dependența
framework-ului de sistemul de operare MacOS [ 11] (editorul Unity funcționa doar pe
acest sistem de operare). Astfel se adaugă suport pentru editorul Unity și pe platforma
Windows. Totuși dezvoltatorii preferau un editor mai complex și mai stabil, ducând la
dezvoltarea pluginului UnityVS pentru Visual Studio.
Versiunea 4 aduce noi îmbunătățiri prin componenta de UI și a capabilităților
2D. Până în acel moment dezvoltatorii emulau grafica 2D proiectând imaginile pe un
cadrilater(formă geometrică cu 4 colțuri, produsă prin alăturarea a două triunghiuri –
en. quad ). Totuși sistemul de UI nu era ușor de folosit, astfel ca apar diverse
plugin-uri externe pentru această problemă.În continuare, se observă lipsurile acestei
tehnologii, lipsuri ce sunt acoperite de componente externe. Astfel în versiunea 5 se
aduce integrarea cu Visual Studio, mult așteptată de dezvoltatori și se reface sistemul
de UI.

CAPITOLUL 1. INTRODUCERE 8
În această întreagă istorie se observă viteza mare de răspuns la nevoile
programatorilor, ceea ce reprezintă principalul factor pentru care Unity a devenit
foarte popular. În urma unui studiu făcut al clienților Unity se observă ca o treime
dintre aceștia nu foloseau Unity pentru a face jocuri [ 11].

Capitolul 2
Prezentarea generală a lucrării
Datorită dezvoltării masive a graficii de calculator în ultimii ani acest domeniu
a devenit foarte interesant pentru domeniul științific. Cu toate acestea o problemă care
încă persistă în cazul aplicațiilor 3D accelerate grafic este lipsa unei modalități de a
adăuga o interfață grafică interactivă foarte ușor. Pentru a rezolva această problemă
proiectul propune folosire unui sistem deja existent de dezvoltare a aplicațiilor și
folosirea sa împreună cu un motor grafic. Deoarece limbajul C++ nu este foarte ușor
de folosit în dezvoltarea unor asemenea aplicații se impune găsirea unui alt limbaj de
nivel mai înalt. Problema apare în momentul în care algoritmul grafic trebuie
implementat folosind limbajul de nivel înalt. O soluție optimă constă în folosirea a
două limbaje de programare, fiecare pentru rolul său și găsirea unui mecanism de
interacțiune între cele două.
O modalitate de refolosire a codului scris într-un limbaj diferit față de aplicația
gazdă este prezentat de mecanismul DLL( Dynamic Link Library – Bibliotecă cu legare
dinamică). Deși acesta este un mecanism consacrat, ce poate fi folosit din mai multe
limbaje folosind mecanismul de P/Invoke( Platform Invoke – Invocare specifică
platformei) acesta nu este ușor de folosit, bazat de multe ori pe biblioteci
implementate de comunitate.
Un mecanism matur de interacțiune a două aplicații scrise în limbaje diferite
se dovedește a fi CLI( Common Language Interface – Interfață comună între limbaje),
parte din platforma .NET de la Microsoft. Din acest considerent se evidențiază
sistemul WPF(Windows Presentation Foundation) de dezvoltare a aplicațiilor grafice
și biblioteca Direct3D pentru partea de grafică accelerată hardware. În dezvoltarea
9

CAPITOLUL 2. PREZENTAREA GENERALĂ A LUCRĂRII 10
aplicațiilor bazate pe tehnologii Microsoft se recomandă folosire uneltelor dezvoltate
de aceeași companie, în principal Microsoft Visual Studio.
Întregul proiect este implementat ca o ”soluție” Visual Studio ce conține mai
multe proiecte dezvoltate în C++ și C#. Un proiect special, denumit Osmosis
implementează partea de interacțiune între cele două limbaje. Acest proiect este
implementat folosind un limbaj proprietar Microsoft denumit C++/CLI( C++ over
CLI – C++ peste CLI). Acest limbaj permite folosirea atât a obiectelor ”native”, cele
implementate în C++, dar și a celor administrate de către mașina virtuală .NET,
denumite managed (administrate). Principala problemă constă în mecanismul diferit
de administrare a memorie, astfel că se vor folosi mecanisme specifice acestui limbaj
pentru interacțiunea obiectelor eterogene.
Motorul grafic implementează câțiva algoritmi de grafică pentru a demonstra
modul în care o asemenea implementare poate fi folosită. Acesta este folosit atât
într-o aplicație grafică clasică, folosind Win32 dar și integrat în aplicații WPF. Se
implementează algoritmi grafici folosind Direct3D, majoritatea implementării
constând în pregătirea datelor pentru trimitere către co-procesorul grafic, și algoritmi
tridimensionali implementați folosind limbajul HLSL(Limbaj de nivel înalt folosit în
dezvoltarea shader -elor, en. High Level Shading Language ).
Aplicațiile gazdă constau în câteva implementări demonstrative folosite
pentru a arăta cum poate fi folosit motorul grafic, denumit Tungsten, în mai multe
moduri. Implementările WPF prezintă mai multe metode de interacțiune precum și
avantajele și dezavantajele acestora. În această lucrare se vor prezenta diversele
probleme ce apar, dar și potențiale soluții pentru acestea. Potențialele soluții ce s-au
dovedit a fi incomplete au fost și ele prezentate împreună cu problemele ce rezultă din
acestea pentru a acoperi mai multe direcții de atac asupra problemei care par în mod
teoretic că ar rezolva problemele prezente în respectiva implementare, dar care se
dovedesc a fi insuficiente sau neimplementabile.

Capitolul 3
Dezvoltarea aplicațiilor 3D folosind
DirectX 11
3.1 Spații de coordonate
Arhitecții DirectX au optat pentru un sistem de coordonate mai puțin ortodox.
Spațiul UV (2D) plasează originea (0,0) în colțul stânga sus, în timp ce
API-ul(Interfață de Programare a Aplicațiilor – en. Application Programming
Interface ) OpenGL folosește același sistem de coordonate întâlnit în matematică, cu
originea plasată în colțul stânga jos 3.1. Această decizie a fost luată deoarece un
asemenea sistem de ordonare respectă convențiile întâlnite în programare.
Interpretând o imagine de tip bitmap în C++ primul element va avea coordonatele
(0,0), și va fi plasat în colțul stânga sus, conform ordinii de scriere în alfabetul latin.
Spațiul 3D a fost și el modificat sa respecte o orientare folosind regula mâinii
stângi. Astfel axa Z trece prin suprafața vizualizată, în timp ce axa Y reprezintă
înălțimea. Acesta reprezintă o reinterpretare ”intuitiva” în care obiectele mai
depărtate au coordonata Z mai mare, față de obiectele mai apropiate de centrul
perspectivei.
Toate acestea pot fi modificate, prin o serie de parametri, ceea ce permite lucrul
cu date generate în sistemul OpenGL, altfel ar putea apărea multe probleme subtile
atunci când se proiectează modele 3D generate într-un sistem de coordonate a mâinii
drepte.
11

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 12
O altă caracteristică diferită a DirectX-ului este faptul că vectorii sunt
considerați ca fiind vectori linie, astfel înmulțirea unui vector cu o matrice este
inversată, după cum se poate observa în Figura 3.2.
0 50 100 150 200 2500
50
100
150
200
250
0 50 100 150 200 250050100150200250
Figura 3.1: Spațiul UV în DirectX(stânga) față de OpenGL(dreapta)
[
x y z w]2
664m1m2m3m4
m5m6m7m8
m9m10m11m12
m13m14m15m163
775=2
664xm 1+ym 5+zm 9+wm 13
xm 2+ym 6+zm 10+wm 14
xm 3+ym 7+zm 11 +wm 12
xm 4+ym 8+zm 12+ym 163
775
Figura 3.2: Înmulțirea vector-matrice, în sistemul DirectX
3.2 Arhitectura Pipeline
Co-procesoarele grafice funcționează conform modelului ”flux de lucru” (en.
pipeline ). Acest model constă în diferite stagii de procesare succesive într-o ordine
predefinită. Astfel, fluxul de date este unidirecțional, cea ce permite prelucrarea
diverselor pachete de date în același timp.
Aceasta model este deja implementat pe noile arhitecturi de procesare. Se poate
observa în 3.4cum cele 4 instrucțiuni (codificate cu cele 4 culori) sunt procesate în
paralel. După cum se poate observa, o arhitectură clasică, prezentată în 3.3, are nevoie
de mai multe cicluri de ceas pentru a procesa instrucțiunile.
O arhitectură de tip pipeline nu reprezintă un avantaj în toate situațiile.
Exemplele prezentate pornesc de la premiza că cele patru instrucțiuni(codificate în

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 13
0 1 2 3 4 5 6 7 8 9 10Cicluri de ceas
Instrucțiuni
în așteptareExecuțieFetch
Decode
Execute
Write-back
Instrucțiuni
finalizate
Figura 3.3: CPU fără arhitectură Pipeline
cele 4 culori) sunt complet independente, astfel că evaluarea uneia nu este dependentă
de rezultatul celeilalte.
O altă problemă prezentă în cazul unei asemenea arhitecturi sunt ramurile
condiționale. În acest caz există două posibilități. Fie se așteaptă instrucțiunile
dependente, blocând pipeline-ul, fie se presupune una din ramuri ca fiind corectă
(mecanism de tip predicție a ramurii executate – en. branch prediction ).Cea de-a doua
situație, în cazul pozitiv,în care divergența a fost presupusă corect, execuția are
aceeași performanță ca o serie de instrucțiuni necondiționale. În cazul negativ
instrucțiunile deja procesate sunt eliminate din pipeline și înlocuite cu cele de pe
ramura corectă (mecanism de tip resetare a fluxului – en. pipeline flushing ).
Astfel, co-procesoarele grafice prezintă anumite condiții pentru performanță

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 14
0 1 2 3 4 5 6 7 8Cicluri de ceas
Instrucțiuni
în așteptarePipelineFetch
Decode
Execute
Write-back
Instrucțiuni
finalizate
Figura 3.4: CPU cu Pipeline
optimă. Deși în aplicațiile reale acestea nu pot fi îndeplinite în mod absolut, ele totuși
reprezintă în linii mari o serie de principii de bună practică ce trebuiesc respectate.
În cazul procesării pe GPU unitățile logice (instrucțiuni, sub-rutine, programe)
trebuie sa fie independente. Astfel, se poate introduce un grad mare de paralelism.
Aplicațiile grafice prezintă, prin natura lor un foarte mare grad de paralelizare.
Trebuiesc evitate pe cât posibil ramurile condiționale, fiind preferate artificiile
matematice ce conduc la același rezultat. Acestea sunt foarte utile, deoarece pe lângă
problemele deja prezentate, co-procesoarele grafice prezintă și o arhitectură de tip O
Singură Instrucțiune Mai Multe Fire de Execuție(en. Single Instruction Multiple
Threads – SIMT).
Arhitectura SIMT, cunoscută și sub numele WARP , în special în terminologie

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 15
NVidia reprezintă o serie de nuclee ce evaluează aceeași instrucțiune simultan, dar pe
seturi diferite de date. Toate aceste fire de execuție sunt grupate în blocuri ce nu pot
rula instrucțiuni disjuncte.
Un astfel de circuit împarte o singură unitate de aducere a datelor(en. fetch )
pentru mai multe unități aritmetico-logice. Astfel, singura soluție este calcularea
datelor invalide și ignorarea lor, în compunerea rezultatului.
Pentru exemplificare, considerăm că 4 nuclee de tip WARP, fiecare cu câte 4
fire de execuție paralelă rulează următorul pseudo-cod.
if(X)
result=blue;
else
result=green;
Unde X=8
<
:1; p= 75 %
0; p= 25 %. Pentru a evalua acest algoritm este nevoie de
calcularea ambelor ramuri ale sale pentru fiecare punct.
Predicția 1
Albastru
Predicția 2
Verde
Figura 3.5: Ramuri condiționale în arhitectură WARP
Au fost propuse soluții pentru evitarea acestui fenomen, precum gruparea
dinamică a firelor de execuție în funcție de evaluarea condiției de divergență .
Arhitecturile recente au implementat unele dintre aceste mecanisme, totuși acestea nu
au cost zero, astfel că ramificarea trebuie evitată pe cât posibil [ 15].

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 16
3.3 Fluxul de lucru Direct3D11(D3D11)
Pentru a permite un control cât mai direct al resurselor hardware, arhitectura
software a D3D11 înglobează multe trăsături ale arhitecturii hardware. Astfel,din
punctul de vedere al software-ului avem de-a face tot cu un pipeline.
Acesta este compus din mai multe stagii succesive de procesare, a căror ordine
nu poate fi schimbată. Aceste stagii de procesare reprezintă transformării dintr-un
concept în altul, începând cu vertecși.
Odată cu introducerea conceptelor de GPGPU a apărut și o ieșire alternativă a
pipeline-ului în forma datelor structurate cu rol general, acestea din urmă fiind
transferate către memoria generală a calculatorului. Apariția acestei funcționalități a
influențat și algoritmii grafici, ducând la dezvoltarea unor algoritmi micști, în care
datele sunt procesate în regim general (GPGPU) și apoi sunt folosite într-un algoritm
grafic, în special în simularea fluidelor [ 20].
Aceste stagii sunt denumite de obicei după tipul datelor rezultate ( Pixel
Shading ), ceea ce conduce la o forma prescurtată (PS) folosită mai ales în publicațiile
tehnice. Stagiile ce conțin în denumire ”shader”( program de mici dimensiuni, folosit
în contexte speciale) sunt programabile, în timp ce celelalte sunt doar parametrizate,
algoritmul de bază fiind fix.

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 17
Intrare flux de lucru
Assamblarea
datelor
de intrare
Shadere
de vertex
Shader de
convexitate
Mozaicator
Shader de
domeniu
Geometry
Shader
Ieșire
în fluxMemoria sistemului
Rasterizator
Shader
de pixel
Combinare
a ieșirii
Dispozitiv de afișare
Figura 3.6: Stagii de procesare Direct3D11

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 18
Punctul de intrare al pipeline-ului este stagiul de asamblare a intrărilor (en.
Input Assembler ). Acesta compune figuri geometrice primitive (puncte,linii,
triunghiuri) dintr-un buffer de indecși și unul de vertecși. Co-procesoarele grafice
moderne permit manipularea mai multor asemenea buffere în același timp. Acest
stagiu permite și tehnica instanțierii (en. instancing ) care generează vertecși într-un
mod programatic, pornind de la o figură de bază și datele diferențiatoare pentru
fiecare instanță. Această tehnică permite generarea unui număr foarte mare de figuri,
bucurându-se de puterea paralelă de calcul a GPU-ului. Tehnica de instanțiere
accelerată grafic se supune condițiilor de paralelizare, mai precis, instanțele sunt total
independente, parametrii uneia fiind de sine stătători, ordinea instanțierii nefiind
garantată.
Nivelul următor, shaderul de vertex (en. vertex shader ) preia datele generate
de primul stagiu. Acesta este primul shader programabil și este stagiul unde
majoritatea procesării algoritmice are loc. Cel mai comun algoritm implementat la
acest nivel este algoritmul Blinn-Phong [ 9]. Acesta era implementat la nivel hardware
în epoca pipeline-ului fix, neprogramabil.
Următoarele stagii sunt folosite împreună în tehnica mozaicării (en.
tesselation ). Procesul shader de concavitate (en. hull shader ) primește o figură
primitivă și calculează factorii de mozaicare. Acești factori sunt folosiți de către
nivelul de mozaicare propriu-zis în generarea mai multor triunghiuri. Primul proces
generează și punctele de control ce vor fi folosite de către shaderul de domeniu (en.
domain shader ) pentru calcularea vertecșilor suplimentari.
Stagiul shader-ului de geometrie(en. geometry shader ) funcționează la un
nivel geometric. Acesta poate crea mai multe forme geometrice, să transforme din
una în alta(de exemplu puncte în triunghiuri, să multiplice numărul de triunghiuri, și
altele). Acest stagiu este foarte folositor în algoritmii de generare de particule. La
finalul acestei procesări se trece printr-un algoritm de decimare (en. culling ) care va
elimina anumite triunghiuri, conform regulilor alese(normala la suprafață, tăiere de
frustrum etc.).
După eliminarea triunghiurilor, cele rămase trec printr-un proces de rasterizare.
În urma acestui proces rezultă fragmente, ce reprezintă o grupare de date ce pot deveni
un pixel al imaginii generate.
Fragmentele trec prin procesul shader-ului de pixel(en. pixel shader ) ,mai
corect denumit shader de fragment(en. fragment shader ). Acesta aplică un algoritm

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 19
programabil ce va genera informații despre culoarea și adâncimea unui candidat spre
afișare. Datele de intrare ale acestui algoritm sunt generate prin interpolarea liniară a
setului de date ce reprezintă fiecare vertex al triunghiului, după cum se poate observa
în figura următoare.Cele trei colțuri conțin cele trei culori primare RGB, toate
celelalte puncte sunt generate prin interpolare.
Figura 3.7: Exemplu de interpolare a triunghiului
Ultima etapă este denumită output merger (OM). În această etapă sunt rulate
diverse teste, cum ar fi eliminarea de adâncime, șablonarea.Dacă candidatul trece de
aceste teste atunci el va fi combinat cu culoarea deja existentă pe suprafața de lucru
folosind algoritmul alpha blending . Acest stagiu nu este programabi,l dar poate fi
modificat prin parametri cum ar fi tipul de operație (aditivă, multiplicativă,
substractivă) de combinare sau diverse operații pentru fiecare parametru (inversarea).
Stagiul shader-ului de computație (en. compute shader -CS) nu face parte din
pipeline. Este rulat o singură dată, poate evalua operații arbitrare și datele rezultate
sunt trimise către memoria sistemului. Spre deosebire de celelalte stagii, aici apare și
conceptul de Memorie Partajată de Grup(en. Group Shared Memory ), permițând mai
multor fire de execuție să utilizeze memorie comună, ceva ce era imposibil în vechea
arhitectură. Acest shader este folosit în aplicațiile de GPGPU și reprezintă componenta
principală a framework-urilor precum C++ AMP. Înainte de standardizare astfel de
algoritmi puteau fi evaluați doar folosind funcționalități specifice fiecărui producător,
precum CUDA de la NVidia.

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 20
3.4 Resurse
Pipeline-ul de randare și computații prezentat în secțiunea 3.3. reprezintă
diferite metode de a lucra cu date. Datele, în arhitectura Direct3D sunt structurate sub
formă de resurse. Există mai multe tipuri de resurse, dar acestea pot fi clasificate în
mare ca texturi și buffere. Fiecare tip de resursă are utilizări diferite, datorită
funcționalității predefinite pentru fiecare dintre acestea. În general, sunt două metode
de interacțiune cu aceste resurse. Una este prin limbajul C/C++, din perspectiva
procesorului principal și cealaltă este prin HLSL, din perspectiva co-procesorului
grafic. Relația este, în principal, una de generator și consumator. Datele sunt generate
în aplicație și apoi trimise prin shader-ele HLSL către ieșirea video. Odată cu
introducerea shader-ului de computație, relația a devenit mai complexă. Aceasta
poate duce la o relație de tip sandwich, în care datele sunt generate de de CPU, trimise
către GPU, după care rezultatul este interpretat de către CPU.
În funcție de modul de utilizare, resursele se pot împărți în 4 categorii, astfel:
•D3D11_USAGE_DEFAULT : o resursă ce va fi citită și scrisă de către GPU, cea mai
comună utilizare;
•D3D11_USAGE_IMMUTABLE : o resursă ce va fi doar citită de către co-procesorul
grafic fără a fi accesată în nici un fel de către procesorul general, și nu poate fi
modificată, astfel că resursele de acest tip vor fi inițializată la creare;
•D3D11_USAGE_DYNAMIC : o resursă ce va fi citită de către GPU și scrisă de către
CPU, recomandată pentru seturile de date ce sunt modificate la fiecare generare
a cadrului;
•D3D11_USAGE_STAGING : o resursă ce va fi folosită pentru transferul de date de
la GPU către memoria generală a sistemului;
Resursele trebuie să fie legate la una dintre etapele pipeline-ului pentru a fi
folosite. Deoarece o resursă reprezintă o masă nestructurată de date, aceasta trebuie să
fie însoțită de un adaptor ce reprezintă o perspectivă asupra resursei(en. resource view ).
Această componentă ajută la interpretarea aceluiași set de date în moduri diferite, prin
definirea a două asemenea view-uri la aceeași resursă. De exemplu, aceeași resursă
poate fi folosită atât ca intrare cât și ca ieșire în stagii diferite prin prezentarea a două
perspective separate ale aceluiași set de date.
Perspectivele de resurse pot fi una din următoarele: render target view ,depth

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 21
stencil view ,shader resource view sauunordered access view .
Primele trei reprezintă utilizări clasice ale buffer-elor în aplicații 3D. Astfel,
render target reprezintă suprafața spre care se proiectează imaginea, al doilea tip
reprezintă o suprafață folosită pentru testul de adâncime sau pentru șablonare, în timp
ce al treilea reprezintă o resursă ce va fi folosită de către un shader programabil.
Ultimul tip reprezintă o resursă ce poate fi atât citită cât și scrisă de același
shader, dar poate fi folosită doar în shader-ul de fragment sau cel de computație. Acest
tip de resursă este denumit buffer cu acces neordonat (en. unordered access buffer ).
Un exemplu de resursă cu acces neordonat este reprezentat de buffer-ele de tip
”adaugă și consumă” (en. append and consume ). Acestea permit noi metode de acces
din HLSL ce modelează comportamentul unei stive. Datorită naturii paralele a
procesării acestor seturi de date ordinea în care se face accesul nu este garantată.
Singura stare comună între toate firele de execuție este numărul de elemente (ceea ce
permite evitarea consumării unui buffer gol sau suprascrierea a două valori nou
introduse). Astfel, în implementarea acestei funcționalități se sacrifică ordinea,de
unde și denumirea.
Utilizarea acestui tip de resursă poate fi exemplificată prin implementarea
unui sistem de particule. Se declară două buffere, unul reprezentând starea S[k], unde
keste momentul actual și S[k1], unde k1reprezintă starea cu un moment de
timp înainte. Considerăm că sistemul ce modelează particulele este un sistem de ordin
1, astfel că există un algoritm fpentru care S[k] =f(S[k1]). Algoritmul poate fi
implementat în compute shader , atât timp cât particulele sunt independente, și
evaluarea stării următoare a unei particule nu depinde de starea a mai mult de o
particulă din starea anterioară. Deoarece numărul de elemente din vector este
accesibil din fiecare fir, prin evaluarea algoritmului se pot genera și noi particule.
Texturile reprezintă un alt tip de resursă, mult mai complex în comportament
decât buffer-ele. Termenul ”textură” se referă la un set de date structurat, precum o
imagine. Istoric, texturile reprezentau imagini 2D ce erau proiectate pe suprafețe sau
modele 3D. De la acest concept, texturile au evoluat în timp, astfel că asemănarea cu
o imagine a devenit mult mai abstractă[ 29]. Cel mai important element de
similitudine păstrat este cel de texel, echivalentul pixelului în imagini 2D. Texel-ul
reprezintă unitatea atomică de informație structurată de către o textură.
Deși texturile, precum buffer-ele, reprezintă blocuri de memorie structurate

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 22
pentru folosire într-un shader, acestea pot accesa capabilități hardware care ar fi
prohibitive de implementat în variantă software în cadrul algoritmului.
Cea mai semnificativă funcționalitate este reprezentată de procesul de
eșantionare ( sampling ). Acest mecanism transformă setul de date discrete (pixeli, în
cazul imaginilor 2D), într-o suprafață de valori continue. Astfel, dacă se eșantionează
textura la o coordonată intermediară va fi generată valoarea prin interpolarea liniară a
punctelor discrete ce înconjoară punctul eșantionat.
În arhitectura Direct3D texelii sunt ordonați într-un sistem de coordonate UVW,
normalizate în intervalul [0,1]. Normalizarea permite eșantionarea texturilor folosind
valori precum u= 0;5. Astfel, pentru o textură 1D punctul reprezintă mijlocul texturii,
indiferent de mărimea reală a texturii (256 texeli, 1024 texeli etc.).
Texturile pot fi separate, în funcție de modul de ordonare a texelilor în
următoarele categorii:
•Texturi 1D ( ID3D11Texture1D ) reprezentând un segment liniar de puncte, cu
o singură coordonată u. Mai multe asemenea texturi pot fi grupate într-un un
vector de segmente linare omogene (de aceeași dimensiune și tip), sub acceași
interfață C++ .
•Texturi 2D ( ID3D11Texture2D ) reprezentând un set de texeli, organizați precum
un plan, cu două coordonate ușiv. Mai multe asemenea seturi pot fi structurate
în vectori de texturi 2D, precum cei unidimensionali
•Texturi cubice/CubeMap (vector de 6 texturi 2D) reprezentând fețele unui cub.
•Texturi volumetrice/3D ( ID3D11Texture3D ) ce organizează texelii în 3
coordonate. Aceste texturi nu pot face parte din vectori de texturi
tridimensionale.
Se poate observa că un vector de texturi este similar cu textura de dimensiune
superioară. Pentru a putea înțelege diferența între acestea, trebuie introdus conceptul
demipmapping . Acesta reprezintă o altă funcționalitate specifică doar texturilor, cu
rolul de reducere a spațiului ocupat de o textură, sau de a simplifica accesul la aceasta.
Mipmapping, sau MIP mapping, își are originea numelui în articolul
”Pyramidal Parametrics” [ 26], unde MIP este o prescurtare pentru lat. ”multum in
parvo” (mult într-un spațiu restrâns). În acest articol se aduce la cunoștință problema
”alierii” semnalelor, atunci când acestea sunt eșantionate pentru interpolare, ceea ce

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 23
Figura 3.8: Texturi volumetrice (jos), și texturi cubice (sus)
Figura 3.9: Mipmapping pentru texturi 2D
în grafică conduce la efectul de ”moar”.Soluția [ 26] propune ca pentru fiecare
imagine, să se creeze o imagine filtrată, cu dimensiunile înjumătățite, pentru crearea
unei noi imagini, mai mici, care poate fi eșantionată, fără producerea efectului de
moar. Texelii noii texturi sunt creați prin media texelilor învecinați.

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 24
Figura 3.10: Mipmapping pentru vectori 1D
O textură 2D va genera un texel nou prin media aritmetica a întregului set de
date, a celor 4 puncte înconjurătoare noului punct (figura 3.9). Un vector de texturi
1D va genera un mipmap doar prin medierea a celor două puncte ale texturii
unidimensionale (figura 3.10), procedeu repetat pentru fiecare textură în mod
independent. Acest algoritm poate fi repetat de mai multe ori, pentru generarea
următorului nivel de mipmapping.
Filtrarea anizotropică (figura 3.11) funcționează pe același principiu, doar că
de această dată se scalează cele două dimensiuni, în mod independent,de unde numele
an-izo-tropic (”nu aceeași dimensiune”). Astfel, se creează o imagine mai clară a
suprafețelor aflate la unghiuri ascuțite. Se creează mai multe suprafețe, asemănător
mecanismului de mipmapping cu diverse grade de anizotropie.
Figura 3.11: Filtrarea anizotropică pentru o imagine 2D

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 25
3.5 Arhitectura software de grafică a sistemului de
operare Windows
Primele aplicații grafice pe calculator aveau acces direct către memoria
grafică. Pentru modificarea imaginii afișate se declanșau diverse întreruperi BIOS.
Astfel, procesorul era mai întâi adus în modul grafic folosind întreruperea 0x10 , după
care fiecărui pixel i se atribuia o valoare, folosind aceeași întrerupere. Suprafața de
lucru era mică, conform standardului VGA putând ajunge la maxim 640480pixeli,
sau doar 320200pixeli atunci când se folosesc 256 de culori. În ciuda acestor
limitări viteza de desenare a suprafeței nu era suficientă pentru dezvoltatorii vremii.
Astfel, se prefera scrierea directă în zona de memorie dedicată, evitându-se apelul
costisitor al întreruperilor.
Odată cu trecerea la sistemul de operare Windows 95, aplicațiile nu mai aveau
acces direct la memoria grafică. Acest factor a necesitat dezvoltarea API-ului DirectX,
și o dată cu acesta și apariția driver-elor grafice. Pentru a controla accesul la această
resursă a fost dezvoltat un model de lucru ce va fi denumit mai târziu XPDM (en. XP
Driver Model ), după ultimul sistem de operare ce a implementat această arhitectură.
Driver-ele grafice se împart în două categorii, în funcție de poziția ocupată în
memoria sistemului. Astfel, există driver-ele kernel-space care au acces liber la toate
resursele sistemului, și cele aflate în user-space care au acces limitat, precum în figura
3.12. În modelul sistemului de operare XP, driver-ele grafice aveau majoritatea
componentelor plasate în spațiul kernel , astfel că ”o eroare întâmpinată în driver-ul
grafic ducea la suspendarea sistemului PC” [ 5].
Pentru a mări stabilitatea sistemului, ATI a implementat tehnologia GPU
recover [5] (recuperare GPU), astfel că, atunci când driverul grafic detectează o
eroare, acesta va reinițializa GPU-ul, pentru a nu fi nevoie de repornirea a întregului
sistem.
O altă funcționalitate implementată în modelul XPDM a fost Administrarea
Comenzilor Virtuale și a Memoriei (en. Virtual Command and Memory Management ).
Acest sistem permitea o separare între procesele ce foloseau memoria grafică.
Odată cu introducerea sistemului de operare Vista, un ”sistem de operare
centrat pe GPU” [ 5], s-a dorit o nouă arhitectură. Principala funcționalitate ce trebuia
implementată de noul model era partajarea resurselor între mai multe aplicații.

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 26
Microsoft
Direct 3DOpenGLMicrosoft
GDI (2D)
ATI
OpenGL
Driver
Sistemul de operare Microsoft Windows XP
Driver ATI
Accelerare
VideoDriver ATI
Direct3DDriver
ATI 2D
Hardware ATIDrivere ATI, în kernelSingurul driver ATI, în user-space
kernel-spaceuser-space
Figura 3.12: Arhitectura ATI Catalyst© în model XPDM[ 5]
Noul model, intitulat Vista Display Driver Model (VDDM) a fost cea mai mare
schimbare de la Windows 95. Multe din funcționalitățile implementate de GPU, cum
ar fi administrarea memoriei sau rezolvarea erorilor sunt preluate de către sistemul de
operare [ 5].
După cum se poate observa în figura 3.13, noua arhitectură are două mari
componente: User Mode Driver (UMD) și Kernel Mode Driver (KMD). Driver-ul de
kernel, de această dată nu mai este strâns legat de sistemul de operare, astfel că acesta
poate continua în cazul unei erori la nivelul de kernel. UMD în schimb nu mai este
monolitic, astfel că o copie a acestuia este instanțiată pentru fiecare proces care are
nevoie de accelerare grafică. Astfel, erorile unui proces nu pot afecta celelalte procese
și mai multe procese pot folosi GPU-ul în același timp.
Noua arhitectură permite un lucru mai simplu cu ferestre multiple și suprafețe
multiple. Astfel, prin mecanismul DXGI mai multe procese pot împărtăși aceeași

CAPITOLUL 3. DEZVOLTAREA APLICAȚIILOR 3D FOLOSIND
DIRECTX 11 27
fereastră, sau ferestrele pot fi împărțite în mai multe dispozitive video.
Nu se recomandă compunere imaginii direct pe suprafața de lucru, denumită
render target . Pentru a afișa utilizatorului imagini incomplete se folosește un mecanism
de tip lanț de schimb (en. swap chain ). Acesta este compus din mai multe zone de
memorie ce sunt afișate alternativ. în principal se folosesc 2 sau 3 buffere.
Microsoft
Direct 3DMicrosoft
DXV AOpenGLMicrosoft
GDI (2D)Driver ATI
DXV A
(Video)Driver ATI
Direct3D
ATI
OpenGL
Driver
Sistemul de operare Microsoft Windows Vista
Driver ATI pentru acces direct la hardware
Hardware ATIDriver ATI, în kernelDrivere ATI
multiple în
user-space
kernel-spaceuser-space
Figura 3.13: Arhitectura ATI Catalyst© în model VDDM [ 5]

Capitolul 4
Arhitectura bibliotecii Tungsten
Biblioteca propusă dorește să fie un motor grafic 3D, ușor de folosit și integrat
în cadrul aplicațiilor dezvoltate cu ajutorul limbajului de programare C#, în special
cele ce folosesc WPF (Windows Presentation Foundation) și WindowsForms.
Datorită faptului că platforma Windows nu este o platformă deschisă, majoritatea
motoarelor grafice open-source folosesc OpenGL. Totuși, datorită popularității foarte
mari a platformei, un proiect ce folosește capabilitățile native ale acesteia este foarte
util.
Limbajul de programare C# este bazat pe un standard deschis (ECMA-334) al
cărui principal sponsor este Microsoft. Deși standardul este deschis, majoritatea
utilizatorilor folosesc implementarea comercială, făcându-l de-facto un limbaj
dominat de întregul portofoliu Microsoft, denumit .NET. Această platformă este una
multi-limbaj, astfel că bibliotecile acesteia pot fi folosite în limbajele de programare
C#, Visual Basic .NET, F#, C++ și altele.
Pentru a putea folosi toate aceste limbaje este necesar ca acestea să fie
compatibile în formă binară. În platforma .NET toate limbajele generează cod binar
compatibil cu Mediu de Rulare Comun pentru Limbaje (en. Common Language
Runtime – CLR). Interfața comună permite prezentarea unor interfețe binare de
aplicație ce nu depind de limbajul de implementare, atât timp cât codul sursă este
compilat în acest sens, folosind implementarea Microsoft a compilatorului pentru
aceste limbaje.
Pentru implementarea aplicațiilor grafice interactive se preferă folosirea unor
limbaje de programare de nivel mediu (C/C++) datorită nivelului ridicat de
28

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 29
performanță necesar acestora. Astfel, pe platforma Microsoft Windows majoritatea
aplicațiilor sunt bazate pe API-ul ( Application Programming Interface -Interfață de
Programare a Aplicațiilor) Win32, platforma preferată pentru dezvoltarea aplicațiilor
grafice pe sistemul de operare Windows. Win32 este un sistem de dezvoltare a
aplicațiilor bazat pe limbajul de programare C, și compatibil cu C++.
Dezvoltarea aplicațiilor grafice (cu interfață grafică cu utilizatorul, nu aplicații
3D) este dificilă folosind C++ împreună cu API-ul Win32. Astfel, că în timp a fost
necesară apariția unei platforme și/sau a unui limbaj ce permitea dezvoltarea mult mai
facilă a acestora. Odată cu impunerea limbajului Java în această sferă, dar și în alte
domenii software precum serverele Web, Microsoft creează limbajul C# și platforma
acestuia, .NET. În prezent, majoritatea aplicațiilor de acest gen nu folosesc Win32, o
excepție majoră fiind desigur aplicațiile interactive 3D, care nu folosesc sistemul de
crearea a interfeței implementat de această platformă, folosind doar sistemul de
comenzi și suprafața grafică de lucru (fereastra) ce sunt oferite de către Win32.
Pornind de la aceste considerente, proiectul este compus din mai multe
componente principale. Fiecare componentă este implementată ca un proiect Visual
Studio(VS), legate între ele prin sistemul de soluții al VS. Fiecare componentă
produce la finalizarea procesului de build un binar ce poate fi executabil sau
încorporabil într-o altă componentă.
Prima componentă Tungsten este TungstenLib. Această componentă conține
partea de randare 3D, 2D, încărcare a imaginilor, modelelor și scenelor. Implementarea
este făcută în limbajul C++, generând la final o Bibliotecă cu Legare Dinamică (en.
Dynamic Link Library – DLL) ce va fi folosită de toate celelalte componente.
Următoarea componentă este TungstenNative. Aceasta implementează o
aplicație Win32 folosind limbajul de programare C++ care va implementa mesajele
Windows ale procesului, va porni o buclă interactivă, o mașină de stări și va prezenta
imaginile generate de Tungsten către o fereastră. Rolul acestei componente este de a
reprezenta o implementare referință a bibliotecii Tungsten ce va fi folosită pentru
comparații cu implementarea heterogenă.
TungstenOsmosis reprezintă un strat intermediar între TungstenLib (C++) și
aplicațiile gazdă implementate în limbajul de programare C#. Această componentă este
implementată în limbajul de programare proprietar C++/CLR. Limbajul este derivat din
C++ standard, având funcționalități ce îi permit sa manipuleze obiecte controlate (en.
managed ) din mediul .NET. Prin această componentă obiectele de tip nativ, cu control

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 30
manual al memoriei, sunt încapsulate în obiecte CLR, controlate de către mediul de
rulare. Astfel, se prezintă o interfață binară compatibilă cu toate limbajele din mediul
.NET. În final, rezultă un DLL compatibil .NET.
TungstenPresenter implementează o aplicație construită pe platforma
Fundamentele Prezentării Windows (en. Windows Presentation Foundation – WPF).
Această aplicație prezintă imaginea generată de către Tungsten pe o suprafață WPF,
preia date de la acesta și le prezintă folosind elemente de interfață implementate în
WPF și transmite mesajele de interacțiune către motorul grafic. Această aplicație este
implementată folosind limbajul de programare C#, deci folosește binarele generate de
către TungstenOsmosis.
TungstenForms este o aplicație similară cu TungstenPresenter implementată tot
în C# dar pe platforma Windows Forms (Forme Windows). Rolul acesteia este de fi
comparată cu implementare ce folosește WPF pentru a găsi platforma ce permit cel
mai ușor integrarea unui motor grafic. Datorită limbajului de implementare și această
componentă interacționează cu motorul grafic prin intermediul stratului de osmoză.
4.1 Tungsten3D
Tungsten3D reprezintă componenta principală a bibliotecii Tungsten. Rolul
acesteia este să creeze și să administreze resursele necesare generării scenei 3D.
Codul client poate interacționa cu API-ul DirectX fie folosind tehnicile de randare
deja implementate, sau poate implementa propriile sale metode.
Tehnica, cunoscută și sub numele de efect, reprezintă unitatea logică de bază a
unei bucle de generare a imaginilor. Fiecare asemenea componentă constă într-un
algoritm și datele asociate acestuia. Acestea pot fi mai complexe sau mai simple,
precum desenarea unui obiect 3D în funcție de perspectivă, simularea unei suprafețe
deformabile sau emularea efectului de fum.
Fiecare tehnica, are control total asupra resurselor, astfel că accesul la acestea
este făcut serial. În fiecare etapă se inițializează datele, se setează configurația
pipeline-ului necesar pentru acest efect și imaginea generată este proiectată fie pe
suprafața principală (cea care va va fi apoi afișată pe ecran), fie pe o alta suprafață
secundară, necesară efectelor avansate. Efectele de postprocesare funcționează pe
același principiu, doar că datele de intrare ale acestora sunt reprezentate de suprafață

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 31
principală de lucru. Ordinea efectelor este importantă, dar biblioteca nu poate impune
un lanț de procesare, datorită faptului că se pot implementa efecte noi, ale căror
poziție și funcționare nu pot fi prezise. Astfel, respectarea ordinii în manipularea
resurselor este în responsabilitatea codului client.
Resursele înregistrate în mediul DirectX sunt în responsabilitatea fiecărei
tehnici. O tehnică incorect implementată poate polua spațiul de resurse, ducând la o
rulare încetinită și pentru celelalte efecte aflate în bucla de randare. De aceea fiecare
tehnică trebuie sa încerce să nu abuzeze de resursele ce le controlează în acel moment.
Un aspect important în extensibilitatea bibliotecii este reprezentată de faptul că
efectele adăugate de către codul client au aceleași drepturi ca o tehnică standard
implementată de către Tungsten. Implementarea unui mecanism de tip ”câine de
pază” (en. watchdog ) – rutină ce are dreptul sa închidă alte activități ce blochează
cursul normal prin consum de resurse precum timpul sau memoria ) nu are sens în
această situație.
Tehnica principală folosită de această componentă este Blinn-Phong. Aceasta
este o tehnică foarte uzuală în grafica tridimensională. Conceptul principal este scena,
compusă dintr-un arbore de obiecte, și o serie de parametri globali. Obiectele sunt
plasate în spații omogene, relative față de nodul părinte. Astfel, apare un arbore de
transformări în cascadă în funcție de ierarhia acestor obiecte. Ierarhia în scenă nu este
statică, aceasta putând fi modificată în timpul simulării.
Pentru a evita folosirea neoptimă a memoriei, prin duplicarea imaginilor și a
modelelor 3D se folosește un registru central. Datorită dimensiunii mari și timpului
mare de citire a acestora din memoria persistentă este foarte util ca diferitele tehnici sau
diferitele obiecte ale aceluiași efect (de exemplu obiectele multiple identice din scenă)
să nu duplice informația necesară acestora. Registrul central va trimite fiecărui obiect
ce cere un mijloc de manipulare a resursei(en. handle ), iar în cazul în care aceasta nu
este deja încărcată va încerca să o localizeze și să o aducă în memoria sistemului. Astfel,
se recomandă ca manipularea obiectelor mari sa nu fie făcută în mod independent, ci
prin administratorul oferit de Tungsten, așa cum se exemplifică în următoarea figură.

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 32
Inițializare
DesenareHandle 1Handle 2Efect 1
InițializareHandle 3
DesenareEfect 2
InițializareHandle 4
DesenareEfect 3
Inițializare
DesenareSuprafață Secundară
Inițializare
DesenareEfect 4
Inițializare
DesenareEfect 5Pornire
buclă
graficăResursa 1 Resursa 2 Resursa 3Administrator de resurseSuprafața Principală
Figura 4.1: Arhitectura Tungsten3D

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 33
4.2 Tungsten2D
Tungsten2D reprezintă componenta bibliotecii Tungsten care se ocupă cu
grafica bidimensională. Aceasta este implementată folosind componente din
Tungsten3D, având rolul de a simplifica folosirea acesteia pentru imagini 2D.
Unitatea principală de logică este denumită sprite (imagine 2D independentă). Acesta
este implementat ca un cadrilater, format din 2 triunghiuri, care este manipulat pentru
a i se atribui o imagine, coordonatele de proiecție a imaginii pe suprafață și poziția
acestuia pe ecran.
Pentru a evita conflictele atunci când imaginile sunt suprapuse, se folosesc
indecși Z, cu aceeași interpretare specifică DirectX, în care numerele mai mari
reprezintă o distanță mai mare față de observator. Pentru a respecta aspectul 2D se
folosește un mediu de proiecție de tip ortogonal.
Pentru desenarea acestor forme există trei moduri de interacțiune. Cele 3
moduri diferă în implementare și prezintă atât avantaje cât și dezavantaje, acestea
fiind Immediate (Imediat), Batching (Împachetare) și Instancing (Instanțiere).
Modul Immediate transformă fiecare apel de desenare a unui sprite într-un
apel de desenare DirectX. Pipeline-ul grafic este proiectat pentru operațiuni de debit
mare și latență mare. Apelurile repetate de desenare cu o dimensiune a pachetelor de
comenzi mică duc la o degradare a performanței extrem de mare. Avantajul constă
într-o mai ușoară depanare, datorită legăturii directe între apelul către bibliotecă și
imaginea desenată.
Pentru a rezolva problemele de latență, modul Batching nu transformă apelul
de desenare Tungsten2D nu conduce la un apel DirectX în mod sincron. Imaginile sunt
mai întâi grupate în funcție de textura folosită pentru proiecție și la finalul buclei sau
prin comandă directă se face câte un apel pentru fiecare textură ce conține imaginea
propriu-zisă și datele geometrice consolidate pentru aceasta. Astfel, se reduce numărul
de interacțiuni cu co-procesorul grafic, ducând la o performanță ridicată.
Modul Instancing funcționează asemănător cu modul Batching , dar folosește
funcționalitățile intrinseci ale GPU-ului pentru a minimiza cantitatea de memorie
necesară. Se transmite un singur cadrilater, pe post de șablon, apoi acesta este copiat
și modificat în mod automat în funcție de parametrii de instanță. Dezavantajul constă
în implementarea slabă pe anumite platforme, astfel că pot exista cazuri în care modul
Batching să fie preferabil.

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 34
Pe baza acestei componente este implementat și modul de randare a textului.
Se generează o imagine și un fișier auxiliar ce conține pozițiile și dimensiunile fiecărui
glif (simbol folosit în scriere cum ar fi literă,semn de punctuație etc.). Aceste date sunt
apoi folosite pentru a genera câte un sprite pentru fiecare simbol al textului, ce vor
așezate într-o suprafață predefinită. La final, aceste imagini sunt prezentate pe ecran
folosind Tungsten2D.
4.3 Tungsten Osmosis
Osmoza este definită ca mișcarea particulelor printr-o membrană
semi-permeabilă. Tungsten Osmosis (Osmoză) reprezintă un strat intermediar între
implementarea C++ a motorului grafic și aplicația gazdă implementată în unul din
limbajele compatibile CLR. Aceasta permite integrarea Tungsten în orice aplicație
bazată pe WindowsRT sau CLR .NET.
CLR reprezintă o mașină virtuală, componentă a mediului Microsoft .NET. În
mod similar cu Mașina Virtuală Java (en. Java Virtual Machine – JVM), aceasta
traduce codul binar în instrucțiuni de procesor, oferă servicii precum accesul la
memorie, administrarea firelor de execuție, un sistem de fișiere virtualizate și altele.
Aceasta impune și o Interfață Binară de Aplicație (en. Application Binary Interface –
ABI) standard, agnostic de limbaj pentru a permite folosirea componentelor .NET,
indiferent de limbajul de dezvoltare a acesteia.
Principala problemă ce trebuie rezolvată de aceasta componentă este
nepotrivirea de impedanță între mediul managed șiunmanaged . Obiectele cu control
manual al memoriei sunt încapsulate în obiecte ce vor fi administrate de către garbage
collector (colectorul de gunoi – rutină cu rolul de a elibera memoria obiectelor ce nu
mai sunt folosite). Problema este rezolvată prin folosirea referințelor mixte, a căror
viață este controlată de administratorul automat, dar care pot conține referințe native.
Aceste obiecte primesc un mesaj atunci când sunt eliminate din memorie pentru a
permite propagarea acestui eveniment prin ierarhia de obiecte native.
A doua problemă constă în transformarea unei suprafețe de lucru specifică
uneia dintre bibliotecile de dezvoltarea a aplicațiilor grafice într-un format compatibil
cu DirectX. Acest pas duce la folosirea unor mecanisme de implementare diferite
pentru fiecare tip de aplicație client în parte. În cazul aplicațiilor de tip WinForms
arhitectura este asemănătoare cu cea a unei aplicații Win32, astfel că se poate lucra cu

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 35
aceleași concepte (ferestre, și referințe către acestea). În cazul aplicațiilor WPF nu
mai există această arhitectură, astfel că se vor folosi componente auxiliare (ferestre
secundare, suprafețe intermediare). În cazul aplicațiilor de tip Universal Windows
Platform (UWP) interoperabilitatea poate fi făcută prin componente predefinite.
4.4 Tungsten Math
Grafica tridimensională se bazează pe transformări în spații ortogonale.
Aceste concepte matematice sunt implementate în simulările numerice ca
transformări matriceale succesive. Pentru a ușura lucrul cu acestea Tungsten propune
integrarea bibliotecii DirectXMath în procesul de lucru al acesteia.
DirectXMath este o biblioteca dezvoltată de Microsoft pentru a accelera lucrul
cu matrici și vectori ortogonali folosind Instrucțiuni extinse SIMD pentru procesare în
flux (en. Streaming SIMD Extensions – SSE). Biblioteca implementează multe
transformări complexe, precum rotație folosind cuaternioni sau proiecția de
perspectivă.
Totuși, datorită modului greoi de lucru cu acestea (pentru accesarea și
modificarea lor se folosesc instrucțiuni opace), Tungsten propune și o implementare
proprie a acestor structuri de date, cu abilitatea de a trece ușor de la un sistem la
celălalt. Acestea au avantajul unei implementări mai transparente contrabalansată de
lipsa unei accelerări hardware ale operațiilor cu matrici. Prin folosirea combinată a
acestora se pot obține ambele avantaje cu un cost redus de performanță, astfel că
Tungsten folosește în principal structurile proprii de date pentru stocarea stării și
implementarea DirectXMath doar atunci când sunt necesare transformări.
4.5 Locatorul de servicii Tungsten
Deoarece anumite componente Tungsten depind de implementarea ce le
integrează, biblioteca abstractizează aceste componente sub forma unor ”servicii”. Un
serviciu este o componentă software, care implementează o interfață publică și este
prezentă doar o instanță a acesteia(implementează modelul singleton ). Pentru a putea
accesa aceste obiecte se folosește un obiect global, TungstenServiceLocator , care
are rolul de a centraliza toate aceste servicii. Fiecare implementare de Tungsten va

CAPITOLUL 4. ARHITECTURA BIBLIOTECII TUNGSTEN 36
crea serviciile prin metode specifice și apoi va ”înregistra” aceste servicii în locator.
Celelalte componente Tungsten vor folosi apoi serviciile fără a fi afectate de
implementarea exactă a acestora.
Cel mai important serviciu este IGraphicsService . Acesta reprezintă
punctul de plecare pentru orice algoritm grafic. Principalele sale componente sunt
obiectele de tip ID3D11Device șiID3D11DeviceContext . Acest serviciu se ocupă și
de administrarea suprafeței principale de lucru. Aceste obiecte sunt create în funcție
de suprafață finală pe care vor fi proiectate imaginile astfel că această componentă
diferă major în procesul de creație pentru fiecare implementare.
Un serviciu care este obligatoriu doar pentru implementarea Win32 este
InputService . Acesta este folosit înregistrarea evenimentelor de tip input primite ca
mesaje Win32. Acestea sunt aduse într-o formă ce poate detecta acțiuni interactive
complexe precum MouseOver ,Drag ,KeyHold și altele. Aplicațiile care integrează
Tungsten vor folosi propriul sistem de interactivitate astfel că acest serviciu nu este
implementat pentru acestea.
Un alt serviciu important în implementarea de referință este
ConfigurationService . Acesta permite persistarea unor parametri, precum
rezoluția folosită, tipul ferestrei ( Windowed ,Fullscreen sauBorderless ). Deoarece
acești parametri nu sunt controlați de Tungsten în cazul integrării în alt sistem acest
serviciu nu are o utilitate în acele implementări, astfel că serviciul este inexistent în
acel caz.
Pentru afișarea informațiilor de diagnoză pe suprafață de lucru se poate folosi
SpriteLogService implementat folosind SpriteTextEffect . Acesta se
inițializează separat și este un punct central în care se acumulează toate mesajele de
diagnoză ce sunt apoi prezentate pe suprafața principală la finalul ciclului de generare
a imaginii. Acest serviciu are utilitate atât în cazul implementării de referință cât și în
cazul implementărilor integrate.

Capitolul 5
Implementarea bibliotecii Tungsten
Biblioteca Tungsten și componentele anexe sunt implementate sub forma unei
soluții Visual Studio 2017 compusă din mai multe proiecte. Aceste proiecte sunt
legate între ele folosind sistemul de build Visual Studio. Există două proiecte de bază,
TungstenLib și Tungsten Osmosis ce sunt folosite de proiectele finale. Aceste
proiecte finale reprezintă tipurile de aplicație ce pot integra Tungsten.
Întreaga logică de grafică 3D se află în proiectul TungstenLib , în timp ce
partea de interoperabilitate între Tungsten și aplicațiile dezvoltate în C# se află în
proiectul TungstenOsmosis . Proiectul bibliotecă conține toată logica necesară
graficii 3D, dar și a celorlalte servicii Tungsten. Proiectul ”Osmosis” prezintă clase
eterogene, ce conțin resurse native (implementate folosind pointeri standard ai
limbajului de programare C++, marcați cu simbolul ”*”), cât și resurse ce există în
spațiul de memorie controlat de către CRL (ale căror pointeri sunt marcați cu
simbolul ”^”, denumiți pointeri ”căciulă” – en. hat pointers ).
Implementarea Win32 reprezintă o implementare clasică de aplicație 3D, în care
elementele de interfață grafică sunt implementate folosind Tungsten și trecerea de la
o scenă la alta se face folosind o mașină de stări. Acest proiect are acces direct la
codul sursă al TungstenLib , componentele acestuia fiind compilate direct în fișierul
executabil rezultat.
Proiectul TungstenPresenterFullComposite reprezintă o aplicație în care
se încearcă compunerea unei ferestre folosind atât Tungsten cât și Windows
Presentation Foundation . Cele două sisteme vor folosi aceeași suprafață, în același
timp, în mod independent, fără nici un mecanism de sincronizare.
37

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 38
Proiectul TungstenPresenterSecondary reprezintă o aplicație WPF ce
creează o suprafață separată, în forma unei ferestre secundare. În această structură
cele două sisteme vor genera imagini tot în mod independent.
Proiectul TungstenPresenterSurfaceComposite va folosi compatibilitatea
între WPF și Direct3D9, astfel că Tungsten va genera o suprafață Direct3D11 ce va fi
apoi proiectată pe o suprafață intermediară Direct3D9 pentru a fi folosită în compunere
de către motorul grafic WPF.
5.1 Implementarea motorului grafic
Componenta centrală a motorului grafic este reprezentată de ”serviciul” de
grafică. Această componentă reprezintă un punct central de unde pot fi accesate
resursele grafice principale. Acestea sunt o abstractizare a co-procesorului grafic, în
forma unui obiect de tip ID3D11Device și a contextului de parametri activi în acel
moment dat prezentați sub interfața ID3D11DeviceContext . Aceste două
componente sunt create în mod diferite pentru fiecare tip de integrare. Serviciul,
odată creat folosind metoda specifică pentru tipul de aplicație gazdă, este înregistrat
înServiceLocator , de unde va fi accesat de către celelalte componente.
Serviciul de grafică se ocupă și cu administrarea suprafeței de prezentare a
imaginii (fereastră, componentă WPF etc.). Astfel, există o suprafață principală,
globală pe care se va afișa imaginea finală. Aceasta este creată în același timp cu cele
două resurse, deoarece procesul de creare este strâns legat de inițializarea principală și
de tipul suprafeței finale pe care se vor proiecta imagini.
Componentele pot folosi suprafețe intermediare în implementarea lor. Pentru
a putea imprima imagini pe aceste suprafețe de lucru este necesară înregistrarea lor ca
atare, folosind resursa globală de tip ”context”. Astfel, după folosirea unei suprafețe
de desenare proprie este necesară resetarea suprafeței principale folosind acest serviciu
global.
Componentele principale ce implementează logica de desenare sunt denumite
efecte. Efectul reprezintă un algoritm grafic ce generează un anumit tip de imagine.
De exemplu, pentru proiectarea unor imagini 2D se folosesc alte date de intrare și un
algoritm diferit față de desenarea unei suprafețe semi-transparente tridimensionale. Un
efect înglobează aceste informații precum structura datelor de intrare, algoritmul folosit

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 39
în prelucrarea acestora, și modul de îmbinare a rezultatelor. Toate aceste informații
sunt transmise către co-procesorul grafic, pregătind pipeline -ul pentru procesarea în
flux. După această configurare efectul va transmite datele necesare algoritmului de
desenare. În funcție de implementare se poate aștepta prelucrarea lor (dacă se folosesc
suprafețe intermediare) sau se întoarce controlul către apelant.
Efectele deja implementate în biblioteca Tungsten reprezintă un set minimal
de algoritmi folosiți în crearea unei aplicații grafice care demonstrează capacitatea
bibliotecii de integrare. Sunt implementate atât efecte grafice bidimensionale, dar și
tridimensionale. Acestea sunt următoarele: Sprite ,SpriteBatching ,SpriteText ,
SpritePoint ,Mesh ,SkyBox ,Foliage ,SineWave șiGerstnerWave .
EfectulSprite este folosit pentru a proiecta imagini bidimensionale pe
suprafața de lucru. Imaginile sunt compuse din două poligoane primitive
(triunghiuri), formate din patru puncte independente. Imaginile au poziții, coordonate
de proiectare a texturii și colorare diferită. Pentru a obține culoarea finală se
evaluează amestecul multiplicativ valoarea eșantionată din textură și parametrul tint
(nuanță).
EfectulSpriteBatching grupează mai multe apeluri de desenare și execută
aceste grupuri la finalul buclei interactive. Gruparea se face în funcție de textura
eșantionată, fiecare grup fiind evaluat de către co-procesorul grafic separat. Apelurile
de desenare DirectX reutilizează același buffer în care se modifică datele pentru
fiecare grup. Aceasta duce la o performanță scăzută deoarece grupul succesor în
ordinea de desenare nu poate modifica zona de memorie decât după ce apelul DirectX
precedent a fost finalizat. Alternativa, definirea de memorii-tampon pentru fiecare
grup ar duce fie la folosirea ineficientă a memoriei, fie la fragmentarea acesteia. Zona
de memorie comună este refolosită și între cadre, cu excepția cazului în care este
necesară o zonă de memorie mai mare. Dimensiunea memoriei tampon este calculată
folosind următoarea formulă:
bufferSize [k] = 2max t=k5;kceil(log2max inGi[t])
unde kreprezintă momentul curent și Gi[t]este dimensiunea necesară pentru grupul i
la momentul t.
EfectulSpritePoint caută să minimizeze dimensiunea datelor transmise
către co-procesorul grafic folosind funcționalități noi DirectX11. Se transmite un

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 40
singur punct pentru fiecare cadrilater ce conține informațiile necesare. Acest punct
este expandat în forma geometrică necesară folosind stagiul de mozaicare
(tesselation ). Astfel, nu se mai repetă datele între puncte. De exemplu, parametrul de
culoare este copiat de patru ori, pentru fiecare punct al cadrilaterului, în cazul
implementărilor predecesoare. Deoarece sunt necesare funcționalități DirectX11
această implementare are dezavantajul lipsei de compatibilitate cu co-procesoarele
grafice din generații mai vechi.
Componenta SpriteTextRenderer este folosită pentru afișarea textului în
scenele Tungsten. Aceasta este implementată folosind una din cele trei implementări
de desenare a imaginilor bidimensionale. Fiecare glifă este desenată ca un sprite
independent, pe baza unui fișier textură ce conține reprezentările grafice ale acestora
și a unui fișier auxiliar, specific Tungsten, de tip .BFD (Binary Font Data – Date
Binare de tip Font) ce permite găsirea coordonatelor pentru fiecare simbol ASCII.
Această componentă se ocupă și de aranjarea literelor pentru a forma blocuri de text.
EfectulMesh are rolul de a desena obiecte tridimensionale definite de o rețea
(mesh ) de puncte. Acest efect implementează algoritmul Blinn-Phong [ 9]. Se pot
desena obiecte 3D închise, afectate de o sursă de lumină. Deoarece obiectele
tridimensionale nu își modifică forma efectul creează un buffer de date nemodificabil
ce va fi reutilizat pentru fiecare model. Astfel, pentru desenarea mai multor obiecte se
vor folosi mai multe instanțe ale acestui efect. Partea ce se modifică la fiecare cadru
este reprezentată de matricea de transformare locală. Aceasta face parte dintr-un alt
buffer ce va fi modificat pentru fiecare cadru, dacă este nevoie.
Componenta SceneRenderer organizează mai multe componente
tridimensionale într-o ierarhie arborescentă de obiecte. Spațiul de coordonate local va
fi definit relativ față de obiectul părinte, cu excepția obiectului primordial, care va fi
plasat în același sistem de coordonate cu camera. Această componentă se va ocupa și
cu administrarea parametrilor de iluminare a scenei. Datorită implementării unui
sistem de calculare a luminozității locale acești parametri nu vor depinde de obiectele
scenei. Altfel spus, nodurile unei scene nu pot proiecta reflexii sau umbre pe alte
obiecte.
Efectul SkyBox are rolul de a crea iluzia unei plan depărtat în spațiul
tridimensional. După cum spune și numele, acest efect creează un cub ce înglobează
scena. Acesta se află într-un spațiu independent de poziția camerei, astfel ca va părea
că se află la o distanță infinită față de observator. Pentru eșantionarea imaginii nu se

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 41
folosesc coordonate bidimensionale UV , fiind necesar un vector de orientare relativ la
observator.
Foliage reprezintă un efect folosit pentru desenarea geometriei simple, cu
repetabilitate mare, cu aplicabilitate directă în simularea vegetației pe un plan. În
implementare se folosește funcționalitatea instancing (instanțiere), prin care se
creează un obiect prototip ce va fi apoi copiat/instanțiat de mai multeori, instanțele
diferențiindu-se prin parametri individualizați. Dacă obiectul prototip are o
complexitate ridicată se pot desena foarte multe copii ale acestuia cu un cost minimal
de memorie.
Pentru simularea efectelor de apă se oferă două efecte. Ambele funcționează
manipulând un plan tridimensional împărțit într-o rețea de puncte. Pentru o
compatibilitate mai mare planul va fi împărțit de către Tungsten folosind procesorul
principal, pentru evitarea utilizării unei tehnici de mozaicare. Deoarece planul nu va
suferi modificări dese acest procedeu nu ar duce la un câștig substanțial de
performanță.
EfectulSineWave (figura 5.1) inițializează o suprafață de puncte echidistante.
Modificările suprafeței apei, în acest caz valuri, vor fi modelate prin unde sinusoidale.
Prin suprapunerea acestora se obține o undă complexă ce va fi proiectată pe suprafața
plană. Fiecare punct generat va evalua valoarea undei în coordonatele sale și se va
deplasa în plan vertical în funcție de această valoare, după următoarea formulă [ 12]:
H(x; y; t ) =∑
Aisin(Di(x; y)wi+tφi);
unde:
•Lungimea de undă (L) – distanța dintre două maxime ale unei unde
•Amplitudinea (A) – deplasarea verticală a punctului atunci când se află la
maximul funcției
•Viteza (S) – distanța pe care se deplasează unda într-o unitate de timp, exprimată
ca o constantă de fază φ, unde φ=2
L
•Direcția (D) – vector ce reprezintă direcția de deplasare a undei, considerând că
centrul se află la o distanță infinită
EfectulGerstnerWave (figura 5.2) reprezintă o metodă mai complexă de

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 42
simulare a unei suprafețe lichide. Principala diferență constă în faptul că punctele se
deplasează atât pe orizontală cât și pe verticală. Prin această deplasare va crește
frecvența de eșantionare aproape de maximul undei, prin gruparea punctelor pe
creasta valului. Astfel, se creează iluzia unei suprafețe acvatice mult mai violentă,
potrivită pentru o scenă cu temă maritimă, de exemplu.
Figura 5.1: Valuri sinusoidale
Figura 5.2: Valuri Gerstner

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 43
5.2 Încărcarea modelelor
În timp ce forme geometrice simple pot fi descrise cu câteva puncte, imaginile
complexe necesită sute, mii sau chiar milioane de puncte. Astfel apare problema
stocării acestor date într-un mod eficient. Asta a dus la dezvoltarea mai multor
formate de fișiere, prin prisma nevoilor diferite ale fiecărei aplicații. Problema
principală se pune în alegerea dintre un format binar și unul bazat pe text.
Fișierele binare au avantajul unui timp de încărcare mai mic și un consum
minimal de memorie. Deoarece rețeaua de puncte este serializată atunci când este
salvată, consumatorul poate încărca datele așa cum sunt, fără a fi nevoie de o
procesare ulterioară. Dezavantajul unui format binar este dat în schimb de opacitatea
acestuia. Acestea sunt dificil de încărcat în afara aplicației care le-a generat.
Chiar și atunci când se folosește aceeași logică de importare pot apărea
probleme cauzate de detalii tehnice. O altă variantă de compilator poate duce la un
aliniament al structurilor de date diferit. Această problemă este și mai evidentă atunci
când importarea se face într-un limbaj de programare diferit față de cel care a făcut
serializarea. Totuși, acest caracter opac face ca majoritatea formatelor proprietare să
fie binare.
Formatele text (denumite și formate ASCII) sunt mult mai ușor de parcurs și
interpretat. Majoritatea sunt citibile de către om și bine documentate. Asta le face
potrivite pentru proiectele de amatori și open source . Totuși, acestea au consum mult
mai mare de memorie și viteză de procesare și încărcare mult redusă.
Unul dintre cele mai utilizate formate ASCII este .obj . Majoritatea
programelor de modelare tridimensională pot exporta în acest format, deși pot apărea
diferențe subtile între fișierele exportate de diverse aplicații. Datorită permisivității
standardului, același set de date poate fi exprimat în moduri diferite. Punctele pot
avea date suplimentare (precum normala de netezire) definite în fișierul companion
.mtl , care și acesta poate avea forme diverse.
Încărcarea fișierelor OBJ devine solicitantă, în special pentru fișiere mari.
Pentru comparare se propune o scenă 3D simplă, dar cu obiecte cu o rețea de puncte
mare precum în figura 5.3. Aceeași scenă este inițializată cu date în format text și cu
date într-un format serializat de către Tungsten din formatul text ( .BMD ). După cum se
observă în tabelul 5.1, formatul .BMD este mult mai eficient.

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 44
Figura 5.3: Scena de test pentru comparația timpului de încăracre a fișierelor OBJvs
BMD
Denumire
modelDimensiune
(octeți)Timp încărcare
OBJ (ms)Timp încărcare
BMD (ms)
broken 519804 1659 2
plane 539244 1535 2
terrain 216 904 4
soldier 1280988 3837 3
heli_base 2605500 8118 6
Tabelul 5.1: Compararea timpului de încărcare pentru fișiere OBJșiBMD
5.3 Integrarea Tungsten în aplicațiile de tip Win32
Sistemul de operare Windows, derivat din aplicația Windows pentru MS-DOS,
are ca concept central fereastra . Ferestrele reprezintă elemente de interfață grafică cu
comportament și aspect înglobat[ 22]. Implementarea acestora reprezintă o evoluție
continuă de la primele versiuni ale aplicație și mai apoi a sistemului de operare. Acest
sistem de management al interfeței este prezent și în ultimele versiuni ale sistemului
de operare și este folosit în implementarea oricărei aplicații pentru sistemul de operare
Windows, cu excepția notabilă a aplicațiilor pentru platforma UWP.
Windows API este interfață de programare a aplicațiilor consacrată de
longevitatea acesteia. Ultima versiune este denumită în mod oficial Win64, dar

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 45
deoarece este compatibilă la nivel de cod sursă cu versiunea precedentă se continuă
folosirea sintagmei Win32, deși aplicația poate fi compilată și pentru arhitectura
x86-64 . Implementările moderne de sisteme de interfață grafică reprezintă fie o
extensie a arhitecturii Win32, cum este cazul WindowForms sau se folosesc de
aceasta, cel puțin pentru inițializarea suprafeței de lucru, cum este cazul aplicațiilor
WPF.
Orice aplicație este compusă din cel puțin o fereastră , ce poate conține mai
multe ferestre pe suprafața acesteia. În concepția generală, se consideră fereastră o zonă
din interfața grafică ce poate fi repoziționată în mod independent și conține elemente
standard precum bara de instrumente, bara de titlu, și butoanele de control (minimizare,
maximizare și închidere). În arhitectura Win32 orice element grafic este considerat
fereastră , cum ar fi un buton, un meniu cu file sau o bară de deplasare.
Implementările clasice de aplicații accelerate grafice sunt construite pe
arhitectură Win32. Acestea de obicei folosesc o singură fereastră din care generează
suprafața de lucru DirectX. Această arhitectură este preferată datorită costului mic de
performanța și controlului direct asupra mesajelor primite de la dispozitivele de
intrare.
Pentru generarea suprafeței de lucru se folosește obiectul de manipulare a
ferestrei, implementat de către Win32 ca un HWND (Manipulator al Ferestrei – en.
Handle Window ). Direct3D11 oferă funcția predefinită
D3D11CreateDeviceAndSwapChain ce creează un lanț de schimb pentru afișarea
imaginilor. Aceasta generează suprafața de lucru cu rezoluția și structura cerută ce
acoperă întreaga suprafață logică a ferestrei.
5.3.1 Bucla interactivă
Bucla interactivă (en. game loop ) reprezintă unitatea de bază în aplicații
interactive. Primele programe erau aplicații de tip consolă. Pseudocodul unei
asemenea aplicații este următorul:
while (true)
{
char* command = readCommand();
handleCommand(command);
}

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 46
Principala caracteristică a acestei bucle este faptul ca readCommand() este un
apel blocant. Aplicația pur și simplu așteptă comanda de la utilizator, fiind inactivă în
acest timp. În aplicațiile de tip consolă aceasta nu reprezintă o problemă, dar o
aplicație interactivă modernă trebuie să fie activă chiar și atunci când nu primește
comenzi. Astfel, o buclă interactivă modernă are următoarea structură:
while (true)
{
processInput();
update();
render();
}
În această situație processInput() nu este un apel blocant. Acest mecanism
poate fi implementat foarte ușor într-o aplicație Win32 folosind funcția
PeekMessage() . Dacă nu sunt mesaje în coadă atunci apelul trece la următorul pas.
Timpul necesar evaluării acestei bucle este numit timp de cadru (en. frame time ).
Folosind o simplă ecuație putem calcula viteza de procesare în cadre pe secundă(en.
frames per second ).
fps=1
∆T
Cadre pe secundă nu este o bună metrică deoarece nu este o funcție liniară. De
exemplu, pentru un ∆Tde 10 ms rezultă 100 fps. Dacă algoritmul este de două ori mai
încet, cu un ∆Tde 20ms, obținem doar 50 fps, deci o diferență de 50. Pe de altă parte,
dacă comparăm 50ms față de 70 ms obținem 20 fps și aproximativ 14 fps, o diferență
de doar 6 fps. De aceea cea mai bună metrică este folosirea directă a valorii ∆T.
Bucla simplă prezentată mai sus, numită free-running (rulare liberă) este utilă
în măsurarea eficienței, dar nu este recomandată pentru o aplicație reală. Principalul
dezavantaj al buclei este reprezentat de faptul că monitoarele au o frecventă de
reîmprospătare de 60 Hz (deși în ultima vreme monitoare cu frecvențe mai mari
144Hz, 120Hz au devenit mai comune). Astfel, multe cadre procesate sunt risipite. O
frecvență de 60Hz duce la un ∆Tde 16 ms.
În figura următoare cadrele risipite sunt marcate cu roșu, în timp ce cele utile
sunt marcate cu negru. Deși utilizatorul nu va observa cadrele risipite, procesarea lor
duce la supraîncălzire, problemă importantă mai ales pentru dispozitivele mobile. Au
existat chiar și unele cazuri în care se presupune ca supraîncălzirea a dus la distrugerea

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 47
unor co-procesoare grafice (datorită unei erori în circuitul de protecție termică) [ 17].
0 16 32 48 64
Figura 5.4: Ineficiența unei bucle libere
Pentru a evita această această problemă, se poate activa VSync (sincronizare
verticală). De fiecare dată când aplicația încearcă să trimită un cadru spre prezentare
acel fir de execuție se blochează și așteaptă sincronizarea cu frecvența monitorului.
Folosind aceeași parametri ca mai sus, o asemenea buclă ar arăta ca în următoarea
figură.
0 16 32 48 6410ms 10ms 10ms 10ms
Figura 5.5: Ineficiența unei bucle rapide, sincronizată
0 16 32 48 6415ms 15ms
Figura 5.6: Ineficiența unei bucle încete, sincronizată
Se poate observa ca o buclă care este prea rapidă (figura 5.5) va risipi mult timp
pe fiecare cadru, timp care poate fi folosit de un algoritm mai costisitor, dar mai precis,
ce conduce la o imagine mai detaliată. Bucla înceată (figura 5.6) în schimb arată cum
depășirea pragului critic de 16ms conduce la o înjumătățire a numărului de cadre pe
secundă.
Dacă oricare dintre aceste bucle ar fi implementată, atunci s-ar lovi de o
problemă majoră, în special dacă frecvența de procesare este foarte variabilă în
funcție de performanța hardware. Deoarece apelul update() este invariant în timp,
asta înseamnă că simularea va rula diferit pe procesoare diferite. Aceeași animație ar
trebuie sa ruleze în același timp real atât pe o mașină înceată cât și pe una rapidă.
Pentru a evita acest lucru trebuie să implementăm evaluarea cu pas variabil.
double startTime=getCurrentTime();
while (true)
{
processInput();
double now=getCurrentTime();

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 48
double lambda=now-startTime;
update(lambda);
render();
startTime=now;
}
Această buclă suferă de aceleași probleme prezentate mai sus, în funcție de
prezența VSync sau lipsa acesteia. Principala problemă este timpul irosit care ar putea
fi folosit pentru o simulare mai precisă. O soluție în acest sens ar fi folosirea timpului
rămas pentru evaluarea unui nou ciclu de update (un ciclu de render ar fi inutil
datorită frecvenței monitorului). Să presupunem ca ciclul de procesare grafică
durează 11 ms și cel de evaluare a simulării durează 2ms. Acest algoritm duce la o
detectare a coliziunilor mai precisă și animația va fi mai fluidă. În următoarea figură
ciclurile de render vor fi marcate cu roșu iar cele de update vor fi marcate cu albastru.
double startTime=getCurrentTime();
while (true)
{
double startFrameTime=getCurrentTime();
processInput();
render();
lambda=getCurrentTime()-startFrameTime;
lastTick=getCurrentTime();
totalFrameTime=lambda;
do
{
update(lambda);
lastTick=getCurrentTime;
totalFrameTime+=getCurrentTime()-lastTick;
}while(totalFrameTime + lastTick < frameTimeTarget)
}
0 16 32 48 64
Figura 5.7: Buclă adaptivă
Bucla interactivă Tungsten este sincronizată cu bucla de mesaje Win32. Se
verifică existența unui mesaj în coadă. Dacă există, acestea sunt interpretate de

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 49
InputService care le transformă într-o structură Tungsten ce înglobează starea
butoanelor de tastatură și parametrii specifici dispozitivelor de tip mouse . În lipsa
unor mesaje bucla interactivă continuă oferind controlul obiectului de tip State ce se
află în vârful ierarhiei. Acesta va porni o iterație a buclei interactive Tungsten cu
etapele proprii – Update șiDraw .
Cele două etape ale evaluării unui pas de simulare au rolul de a separa
componenta logică de proiectarea sa în imagine. Update() are rolul de a interpreta
mesajele de intrare, de a reacționa la acestea și de a modifica datele ce modelează
elementele aplicației. În această etapă se evaluează animațiile, se propagă mesajele de
interacțiune sau se calculează diverși parametri de simulare fizică. Se recomandă ca
în această etapă să nu se ruleze în mod sincron operații complexe sau care depind de
resurse cu o viteză scăzută, precum dispozitivele de stocare deoarece asta ar duce la
blocarea întregii bucle interactive cu o degradare puternică a experienței
utilizatorului. Asemenea operații trebuie evaluate în mod asincron, folosind fire de
execuție paralelă sau alte mecanisme.
EtapaDraw() reprezintă de cele mai multe ori cel mai mare consumator de
resurse. În această etapă au loc multe acțiuni care pot depinde de co-procesorul grafic.
Datorită latenței mari de comunicare și a faptului că apelurile DirectX principale sunt
blocante se poate ajunge ușor în starea de Înfometare a co-Procesorului Grafic (en.
GPU starvig ) [18]. În această stare majoritatea timpului este pierdut în așteptarea
transferului de date între cele două memorii, memoria generală a sistemului și cea
grafică, de aceea o analiză bună de performanță poate evidenția dacă GPU-ul este
suprasolicitat, sau înfometat. În figura 5.8se observă ca pachetele marcate cu hașuri,
cel de tip Present depășesc marginea de sincronizare verticală (marcată prin linii
albastre verticale), deci problema constă în faptul că co-procesorul grafică nu termină
procesarea în timp util. În figura 5.9în partea de sus se observă lipsa mesajelor, în
timp ce jos sunt prezente multe pachete de culoare albastru. În acest caz aplicația era
blocată de faptul ca date ale procesului au fost puse în memoria virtuală.
Pentru analizarea performanței unei aplicații grafice se poate folosi o unealtă
precum GPUView[ 13]. Diagramele prezintă coada de comenzi care se acumulează în
spațiul dedicat co-procesorului grafic, dar și în memoria generală și care este
consumată prin evaluarea acestora. Fiecare comandă este reprezentată printr-un
paralelogram colorat. Cele ce prezintă hașuri sunt pachetele de tip Present . Dacă
coada din memoria generală prezintă goluri atunci problema este cauzată de
algoritmii ce rulează pe procesorul general. Dacă coada de mesaje este mereu plină

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 50
Figura 5.8: Suprasolicitarea co-procesorului grafic
Figura 5.9: Înfometarea co-procesorului grafic
atunci problemele de performanță sunt cauzate de supra-solicitarea co-procesorului
grafic. În cazul în care se observă în diagramă paralelograme lungi, hașurate
sincronizate cu semnalul VSync problema este cauzată de sincronizarea verticală,
astfel că măsurătoarea nu este utilă. Pentru o analiză corectă a performanței grafice se
folosește doar o buclă de tip free-running .
5.3.2 TungstenUI
Pentru implementarea elementelor de interfață grafică se folosesc obiecte din
componenta TungstenUI. Acestea reprezintă elemente de interfață precum butoane
sau imagini statice, implementate folosind Tungsten2D. Astfel se evită folosirea
obiectelor de tip Win32, și elementele de interfață sunt integrate în ciclul de afișare a
imaginii Tungsten. Aceste elemente compun o ierarhie arborescentă în care
evenimentele Update șiDraw sunt transmise de la părinte către copii.
Toate elementele grafice implementează interfața IGUIElement . Toate

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 51
obiectele de interfață au definită o suprafață și un punct de ancorare. Elementele
constituente ale acestuia sunt definite prin coordonate relative la colțul stânga-sus.
Coordonata Z, de adâncime este definită tot prin coordonate relative. Pentru a nu
genera apeluri DirectX, fiecare componentă își calculează coordonatele astfel că, la
desenare, toate obiectele se declară în același sistem de coordonate.
Cel mai simplu element grafic este StaticImage . Acesta înglobează un
Sprite , adăugând elementele necesare pentru a putea fi plasat în arborele de obiecte
de interfață. Pentru desenarea acestuia se folosește GUIContext , care este o clasă de
extindere pentru SpriteRender . Astfel, componentele de UI sunt separate de
implementarea exactă (pe bază de batching , instanțiere sau în mod imediat). Acest
context are și rolul de definire a zonei de adâncime rezervată de UI, astfel că diversele
elemente de interfață să nu fie acoperite de obiecte generate de alte efecte. Obiectul
GUIContext ascunde o stivă de translații, fiecare obiect adăugându-și propriile
transformări înainte de a transmite acest obiect către copii și eliminând transformata
sa din vârful stivei la întoarcerea acestui obiect către părinte.
Obiectele de tip GUIFrame nu conțin elemente vizuale, având rolul de așezare a
obiectelor conținute de acesta. Este singurul astfel de obiect, dar poate fi extins pentru
a permite aranjarea obiectelor în mod automat, dar și redimensionarea lor în funcție de
spațiul posibil.
Cel mai simplu obiect interactiv este reprezentat de Button . Acesta conține
mai multe evenimente. Evenimentele sunt unități de logică apelate atunci când se
îndeplinesc anumite condiții. Astfel, butonul prezintă evenimentele onClick ,
onMouseOver ,onRightClick , care sunt apelate în etapa de Update . Aceste
evenimente sunt inițializate ca eveniment null, dar se pot atribui orice funcții de tipul
potrivit. Acestea vor fi apelate la fiecare ciclu de Update în care se întâlnesc
condițiile necesare activării evenimentului respectiv.
5.4 Integrare WPF folosind fereastră compusă
Window Presentation Foundation (WPF) este un framework folosit pentru
dezvoltarea aplicațiilor grafice pe platforma .NET. Cel mai comun limbaj de
programare folosit este C#, dar se pot folosi și alte limbaje compatibile .NET precum
Visual Basi, sau C++/CLI.

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 52
WPF se distanțează de Win32 prin folosirea motorului propriu de desenare.
Acesta este implementat în DirectX, astfel că elementele componente nu pot fi
considerate ferestre , deoarece acestea nu sunt înregistrate ca atare, și nu pot fi
controlate prin intermediul unor variabile de tip HANDLE . Astfel, întreaga fereastră
este utilizată ca o suprafață DirectX. Alte sisteme de construire a aplicațiilor grafice,
precum WinForms, reprezintă un nivel de abstractizare peste o arhitectură de tip
Win32, astfel că elementele de interfață sunt controlate tot prin intermediul
referințelor de tip HWND (Handle to Window). În acea situație integrarea se face
asemănător cu o aplicație Win32.
Integrarea Tungsten într-o aplicație WPF se face folosind TungstenOsmosis.
Cel mai important pas în integrarea Tungsten este găsirea unei suprafețe de lucru ce
poate fi folosită pentru afișarea imaginilor. Ca orice aplicație Windows există o
fereastră principală ce conține toate elementele grafice WPF. În această implementare
se va folosi fereastra principală.
Se va inițializa un TungstenRenderer folosind HWND preluat de la fereastra
principală. Pentru această suprafața se definește un lanț de schimb, o memorie
tampon pentru calcularea adâncimii și se inițializează cele două obiecte de control
DirectX,ID3D11Device șiID3D11DeviceContext . Acesta este apoi înregistrat ca
serviciu de grafică. Efectele implementate în Tungsten pot fi inițializate din acest
serviciu și mai apoi folosite pentru imprimarea imaginilor.
Prima propunere pentru integrare constă în pornirea unei bucle interactive
paralelă cu implementarea WPF. Aceast constă într-o buclă de tip free-running ce
rulează pe un fir de execuție propriu. Această suferă de probleme datorită faptului că
aplică modificări ferestrei din afara buclei WPF. Accesul simultan duce la
instabilitate, astfel că această implementare se dovedește a fi impractică. Activarea
sincronizării verticale nu aduce nici un beneficiu deoarece WPF nu este sincronizat cu
bucla Tungsten.
Pentru sincronizarea buclei Tungsten cu WPF se poate folosi un
DispatcherTimer . Acesta este conectat la componenta principală de propagare a
evenimentelor WPF, de tip Dispatcher . Acesta permite sincronizarea tuturor
apelurile în cadrul unui singur thread. Se creează un asemenea DispatcherTimer pe
firul de execuție folosit pentru sincronizarea elementelor de interfață grafică. Acest
temporizator este verificat la fiecare ciclu al buclei de interfață, dacă s-a depășit
intervalul atunci se propagă evenimentul său, urmat fie de oprirea sa fie de pornirea

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 53
unui nou ciclu de temporizare dacă s-a cerut aceasta. Sincronizarea nu garantează o
durată egală între cicluri, singura garanție fiind că evenimentele au cel puțin intervalul
setat între ele. Un eveniment de interfața blocant, costisitor sau inițierea procesului de
garbage collection (curățare automată a memoriei de obiectele ce nu mai sunt
referențiate) putând duce la o variabilitate ridicată a timpului de cadru.
Împărtășirea aceleași ferestre între WPF și Tungsten, chiar și atunci când
buclele interactive sunt sincronizate nu se dovedește a fi o soluție practică.
Elementele de interfață grafică sunt acoperite de imaginea generată de Tungsten, fiind
vizibile doar în anumite condiții și atunci pentru o perioada scurtă de timp, sau cu
efect de tip clipire. Se observă ca elementele grafice WPF sunt vizibile doar atunci
când se aplică modificări asupra acestora, cum ar fi la evenimente de tip Click ,
OnHover sau cand acestora li se modifică poziția. Deoarece WPF este un framework
ce funcționează în retained mode (mod reținut). Acest model constă în construirea
interfeței în mod declarativ, urmată de desenarea acesteia doar atunci când se
modifică scena proiectată. La polul opus, Tungsten funcționează în mod ”imediat”,
astfel că la fiecare cadru scena este reinițializată și toate elementele sunt desenate în
starea curentă chiar dacă nu și-au modificat starea față de cadrul precedent. Datorită
acestei diferențe în modul de lucru se dovedește că Tungsten și WPF nu pot împărți
aceeași suprafață fără a prezenta artefacte(erori) vizuale.
Această implementară se dovedește a fi imposibilă, astfel că este necesar să se
caute alte metode de integrare. Deoarece cele două motoare grafice nu pot împărtăși
aceeași suprafață de lucru trebuie găsită o metodă de separare între cele două, dar în
cadrul aceluiași proces WPF. Astfel se poate împărtăși date și logică între elementele
de interfață grafică și motorul grafic tridimensional accelerat hardware .
5.5 Integrare WPF folosind fereastră secundară
Implementarea Tungsten de referință, cea care folosește API-ul Win32 își
construiește suprafață de lucru preluând controlul asupra unui ferestre folosindu-se de
handle -ul acesteia. Astfel, cea mai simplă metodă de separare constă în folosirea unei
ferestre secundare inițializată de același proces. Se vor separa cele două motoare
grafice în două ferestre distincte, una rezervată pentru ierarhia de obiecte WPF și a
doua asupra căreia Tungsten are control deplin, după cum se exemplifică în figura
5.10.

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 54
Asemănător cu implementarea prezentată înainte Tungsten preia referința de
tip HWND a ferestrei secundare, creează un motor grafic Tungsten printr-un mecanism
asemănător cu cel folosit pentru integrarea în aplicații Win32 și îl înregistrează pe acesta
în locatorul de servicii. Pentru a nu ajunge la probleme de sincronizare atunci când
se transmit date între elementele WPF și Tungsten bucla interactivă este sincronizată
folosind un temporizator de tip DispatcherTimer .
Figura 5.10: Implementarea Tungsten folosind fereastră secundară
Deoarece nu există elemente WPF pe aceeași suprafață grafică se evită
problema acoperirii lor de către imaginea generată de Tungsten, dar nu se poate
impune această condiție în framework -ul WPF. Deoarece elementul este de tip
Window acesta poate conține alte elemente care vor fi acoperite de imaginea Tungsten.
Deși se pot implementa soluții complexe prin ascunderea( shadowing ) elementelor de
tipDependencyProperty , adnotarea cu atribute de proprietate din clasa
EditorBrowsableAttribute sau prin diverse alte trucuri ce abuzează de
mecanismul de reflexie al limbajului C# acestea nu sunt suficiente sau stabile.
Contractul ce impune lipsa componentelor pe suprafața Tungsten poate fi făcut doar
informal, prin prezentarea condiției în documentație.
O altă problemă apare atunci când fereastra este redimensionată. Prin
redimensionarea apare o diferența între imaginea proiectată de Tungsten și cea
prezentată de ecran. Prin modificarea raportului între înălțime și lățime imaginea
finală va fi deformată deoarece Tungsten va proiecta imaginile la același raport de
aspect ca fereastră originală. Pentru a evita deformările se poate modifica raportul
matricei de proiecție sau a mecanismului analog implementat de efecte.
Redimensionarea reprezintă totuși o modificare efectuată asupra unui element grafic
WPF, astfel că se manifestă o altă problemă vizuală. În timpul redimensionării

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 55
ambele motoare grafice încearcă să deseneze aceeași suprafață, ducând la același efect
de tip ”clipire” în care se prezintă într-o ordine pseudo-aleatoare fie imaginea generată
de Tungsten fie fundalul definit pentru fereastra WPF. Această problemă poate fi
evitată prin forțarea unei dimensiuni fixe pentru fereastra controlată de Tungsten.
Același efect apare și atunci când fereastra secundara este mutată. Deoarece se
aplică modificări asupra stării sale, arhitectura de tip retained a WPF impune
redesenarea tuturor elementelor, inclusiv fundalul ferestrei. Deși se poate forța poziția
suprafeței prin modificarea comportamentului se încalcă așteptările utilizatorului în
ceea ce privește modul de funcționare a ferestrei.
În această implementare se poate crea o aplicație funcțională în care apar atât
elemente grafice WPF, cât și o scenă tridimensională accelerată grafică. Totuși, pot
apărea diferite probleme grafice minore care afectează experiența utilizatorului și nu
oferă aspectul unui produs final. În plus, lucrul cu două ferestre este greoi, și neintuitiv
pentru un utilizator. Prin prisma acestor argumente această soluție nu îndeplinește toate
condițiile impuse inițial.
5.6 Integrare WPF folosind HWNDHost
Deoarece biblioteca DirectX funcționează foarte bine cu obiecte de tip HWND o
soluție ar fi aducerea unor asemenea obiecte în sistemul WPF. Aceste obiecte trebuie
să asigure o suprafață grafică și să fie sincronizate cu bucla interactivă a
framework -ului. Odată integrate Tungsten trebuie să preia controlul absolut asupra
acestuia și să imprime imaginea sa folosind același sistem ca atunci când este integrat
prin mecanismul de fereastră secundară.
Un candidat ideal pentru această implementare îl reprezintă HWNDHost . Clasa
abstractă face legătura între arhitectura WPF și Win32. Obiectul va conține un HWND
ce va face referință la o fereastră definită printr-un WindowClass . Pentru a funcționa
ca un obiect Win32 se importă user32.dll în aplicația WPF, după care se imită
structurile specifice folosind structuri de date definite în limbajul C# cărora li se
impune atributul [StructLayout(LayoutKind.Sequential)] . Deoarece limbajul
C# nu permite accesul direct la memorie compilatorul își rezervă dreptul să rearanjeze
elementele unei structuri pentru a alinia accesul la acestea în funcție de arhitectura
procesorului. În același timp acesta poate adăuga și date de ”umplutură” ( padding ),
tot din perspectiva impunerii unui aliniament în memorie pentru un acces mai facil.

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 56
Acest comportament poate fi controlat prin folosirea unor atribute precum cel
menționat mai sus. Dacă ar apărea modificări la aranjamentul structurii de date atunci
ar fi încălcat contractul interfeței binare a DLL-ului ceea ce ar conduce la erori dificil
de urmărit și depanat.
Odată inițializată fereastra aceasta va reacționa la mesajele de tip Win32.
Astfel, în cazul modificării dimensiunii ferestrei se poate asculta mesajul WM_SIZE ,
extrage argumentele aferente acestuia din wparam șilparam [22] și modificarea
proprietăților din proiecția WPF a obiectului, cum ar fi Height șiWidth moștenite
dinFrameworkElement . Un dezavantaj al acestui mecanism este că obiectul nu
reacționează la evenimente WPF. Astfel, acesta va primi inclusiv mesaje de tip
WM_INPUT, astfel că aplicația gazdă va trebui să implementeze interpretarea acestor
mesaje.
Un mesaj Win32 ce atrage atenția este WM_PAINT. La prima vedere bucla
interactivă Tungsten poate fi sincronizată cu acest mesaj. Avantajul aparent al acestei
soluții ar fi separarea buclei interactive de cea impusă prin mecanismul dispatcher .
Astfel, bucla de generare a imaginii ar putea fi mai rapidă, și nu ar fi blocată de procese
încete care ocupă firul de execuție principal. Totuși Win32 prezintă tot o arhitectură de
tipretained [22] astfel că acest mesaj nu este declanșat decât atunci când suprafață este
invalidată prin mutare sau redimensionare. Acest factor face mesajul nepotrivit pentru
o arhitectură de tip imediat cum este Tungsten.
În această implementare se pot folosi în aceeași fereastră elemente grafice
heterogene, atât cele din sistemul WPF dar și cele accelerate grafic ce folosesc
Tungsten. Acestea sunt plasate în aceeași fereastră astfel că oferă experiența unei
aplicații unificate și nu a unor componente disparate. Interpretarea mesajelor Win32
reprezintă atât un dezavantaj, deoarece este un sistem diferit de WPF, dar în același se
poate reutiliza serviciul de intrări Tungsten pentru preluarea și procesarea semnalelor
de intrare.
5.7 Integrare WPF folosind imagine editabilă
Se dorește integrarea Tungsten cu un element bine integrat cu sistemul WPF.
Cel mai bun candidat în acest sens se dovedește a fi WriteableImage . Obiectele de
acest sunt obiecte WPF care răspund doar la evenimente din acest sistem și sunt perfect
integrate cu acesta. Caracteristica principală a acestui element este reprezentat de faptul

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 57
ca pixelii ce compun această imagine pot fi setați programatic dintr-un vector de obiecte
de tip byte.
Pentru a asigura compatibilitatea cu imaginea generată de Tungsten în primul
rând trebuie ca atât elementul WPF dar și suprafața de lucru să interpreteze datele în
același, având canalele de culoare organizate în același mod. Tipurile de imagine pot
avea de la o singură culoare(imagini monocrome) până la 4 canale, ultimul fiind
reprezentat de obicei de canalul alpha folosit pentru efecte de transparență și
combinarea culorilor. Un alt factor importat este atribuirea dimensiunii fiecărui canal,
acestea putând ocupa 8 biți fiecare, 16,32, dar în formate mai exotice pot avea și
număr diferit de biți pentru fiecare canal. Alt factor este reprezentat de modul în care
este interpretat canalul alpha . Acesta poate fi premultiplicat sau nu. Toate aceste
caracteristic sunt reprezentate de o serie formate compatibile cu cele două sisteme.
Formatul ales trebuie să fie compatibil cu ambele sisteme grafice. Un format ușor de
folosit și prezent atât în WPF dar și în DirectX este
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB pentru motorul grafic Tungsten și
PixelFormats::Bgra32 pentru elementul WPF. Acesta are avantajul că fiecare
canal ocupă 8 biți, astfel că se poate lucra ușor cu acesta. O dimensiune mai mică ar
duce la lucru greoi deoarece procesoarele moderne nu pot manipula regiștri mai mici
de 8 biți, în plus s-ar pierde dimensiunea paletei de culori la un nivel observabil de
ochiul uman, în timp ce o dimensiune mai mare ar duce la o folosire neoptimă a
memoriei. Acesta este formatul folosit de Tungsten.
După alegerea formatului de imagine apare problema comună tuturor tipurilor
de integrare și anume găsirea unei suprafețe de lucru adecvată. Obiectele de tip lanț
de schimb ( SwapChain) sunt legate în implementare de un obiect de tip HWND astfel
că nu se pot folosi acestea. În această situație Tungsten trebuie să imprime imaginea
pe un obiect de tip textură. Un astfel de obiect creat pentru a fi folosit ca suprafață de
lucru însă nu poate fi creat cu parametrii necesari accesului procesorului principal la
datele acestuia. Singura modalitate de a prelua datele de la acesta folosește o altă
resursă intermediară create cu parametrii D3D11_USAGE_STAGING și
D3D11_CPU_ACCESS_READ .
Datorită arhitecturii exotice a coprocesorului grafic resursele nu pot fi
proiectate în mod direct pe un tablou bidimensional. Accesul la memorie se face mult
mai ușor atunci când texturile au dimensiuni puteri ale lui 2, astfel că atunci când se
cere proiectarea acestora în memoria generală a sistemului trebuie să se ia în
considerare modul în care acea imagine este structurată pe baza parametrilor

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 58
RowPitch șiDepthPitch . Pentru a impune dimensiunea ca putere a lui 2
implementarea de Direct3D poate adăuga o zonă tampon de memorie, astfel că
dimensiunea unui rând al tabloului bidimensional poate fi diferită de cea calculată
prin simpla înmulțire a numărului de pixeli cu dimensiunea formatului aleasă la
crearea resursei. Nu se garantează că rândul final va fi completat, astfel că ultimul
rând poate avea dimensiunea diferită față de celelalte rânduri.
Height
RowPitch
Width
Date utile
Memorie tampon
Figura 5.11: Aranjare în memorie a unei texturi bidimensionale
Avantajul principal al acestei implementări constă în faptul că imaginea este
un obiect WPF propriu-zis și nu prezintă diferențe față de celelalte obiecte. Unt alt
avantaj este ca obiectul poate fi folosit în cadrul altor biblioteci .NET, astfel că imaginea
poate fi salvată într-un fișier, trimisă unui serviciu web, etc. Aceasta funcționalitate
reprezintă un avantaj în special în cazul în care se lucrează cu algoritmi de editate
a imaginilor. Totuși nici această implementare nu permite dezvoltarea unor aplicații
grafice interactive de performanță ridicată deoarece bucla interactivă Tungsten este
sincronizată cu cea a sistemului WPF. Totuși această implementare este utilă în cazul

CAPITOLUL 5. IMPLEMENTAREA BIBLIOTECII TUNGSTEN 59
aplicațiilor de vizualizare și procesare a informației 2D, pentru prototiparea algoritmilor
grafici sau pentru aplicații de vizualizare 3D.

Capitolul 6
Concluzii și dezvoltări ulterioare
Motorul grafic Tungsten a fost integrat în aplicații ce folosesc WPF. Se pot
crea interfețe grafice foarte facil pentru controlul simulării accelerate hardware
folosind un sistem modern de dezvoltare a aplicațiilor grafice. Nu au apărut probleme
la folosirea componentelor din alte biblioteci compatibile cu WPF deoarece metodele
de integrarea Tungsten nu sunt invazive, neafectând mecanismele interne ale WPF.
Scopul proiectului a fost atins, dovedind că se pot crea astfel de aplicații mixte.
Am identificat mai multe căi de integrare a motorului grafic, fiecare
prezentând avantaje și dezavantaje. Implementarea de suprafață compusă s-a dovedit
a fi nepractică. Deși se pot căuta metode prin care să se sincronizeze evenimentele de
redesenare a elementelor WPF cu bucla interactivă, orice astfel de implementare s-ar
baza pe cod nedocumentat sau care poate duce la diverse erori subtile, greu de
detectat și rezolvat. O asemenea dezvoltare ar fi fragilă deoarece s-ar baza pe
mecanisme interne ale WPF asupra cărora codul client nu ar trebui să intervină.
Celelalte implementări sunt funcționale, dar unele prezintă probleme de robustețe și
impun condiții de implementare destul de restrictive, astfel că cea mai bună se
dovedește a fi implementarea cu imagine editabilă. Obiectul de tip WriteableImage
este un obiect WPF bine integrat în mediul .NET, în timp ce HWNDHost este o soluție
de interoperabilitate între Win32 și WPF, prezentând o barieră de impedanță între cele
două sisteme, dar având avantajul că se pot refolosi componente sau biblioteci deja
implementate pentru platforma Win32.
În concluzie, acest proiect demonstrează că se pot crea proiecte software care
pot fructifica atât puterea unui sistem de interfață grafică precum WPF dar și viteza de
60

CAPITOLUL 6. CONCLUZII ȘI DEZVOLTĂRI ULTERIOARE 61
procesare a co-procesorului grafic. Acest tip de aplicație poate avea utilitate în
domenii precum procesarea imaginilor, aplicații de proiectare și vizualizare sau
aplicații multimedia. Prin folosirea unui sistem matur pentru dezvoltarea interfeței cu
utilizatorul se economisește efort de dezvoltare care poate fi fructificat în dezvoltarea
de algoritmi grafici mai realistici sau în reducerea timpului de prototipare în cazul
simulărilor tridimensionale.
În continuare Tungsten poate fi integrat și în alte sisteme de creare a
aplicațiilor cu interfață grafică. Deși este un sistem considerat arhaic WinForms
poate, teoretic, integra Tungsten foarte ușor. Un avantaj al acestui sistem este
implementarea deja existentă pe platforma Mono, varianta open-source a .NET. În
acest mod se pot crea aplicații cu interfață grafică ce integrează o simulare accelerată
grafic evitând partea proprietară. Dacă se implementează și randarea grafică folosind
OpenGL atunci se va putea implementa Tungsten în formă open-source, fără a
depinde de unelte proprietare. Platforma UWP, care dorește să înlocuiască WPF,
prezintă facilități în integrarea Tungsten, deoarece biblioteca Direct3D11 a primit mai
multe îmbunătățiri în variantele 11.1 și 11.2 special pentru integrarea în aplicații
UWP. Acestea prezintă chiar o suprafață de compoziție deja implementată, special
concepută pentru a fi folosită în aplicații tridimensionale interactive de mare
performanță.

Bibliografie
[1]Cdp 1862 data sheet. http://www.cosmacelf.com/publications/data-sheets/
cdp1862.pdf . Accesat: martie 2018.
[2]Directx 9.0 features revolutionary high-level shader language. https:
//web.archive.org/web/20100827232558/http://www.microsoft.com/presspass/
press/2003/Jan03/01-22DirectXHLSLPR.mspx . Accesat: februarie 2018.
[3]Unite 2007 – keynote. https://unite.unity.com/archive/2007 . Unite 2007
Developer Conference.
[4](1977). Build the pixie graphic display. Popular Electronics .
[5](2006). White paper: Ati catalyst ® graphics drivers and wddm systems. https:
//www.amd.com/Documents/ATIWDDMWhitepaperFinalV38.pdf . Accesat: mai
2018.
[6]Aldrich, E. M. (2013). GPU Computing in Economic. Technical report,
Department of Economics, University of California, Santa Cruz.
[7]Anthony, S. (2013). Gabe newell made windows a viable gaming
platform, and linux is next. http://www.extremetech.com/gaming/
167253-gabe-newell-made-windows-a-viable-gaming-platform-and-linux-is-next?
origref= . Accesat: aprilie 2018.
[8]Barnson, J. Tales of the rampant coyote. https://web.archive.org/
web/20060717201712/http://www.rampantgames.com/blog/2006/07/
wildest-birthday-party-ever.html . Accesat: februarie 2018.
[9]Blinn, J. F. (1977). Models of light reflection for computer synthesized pictures.
SIGGRAPH Comput. Graph. , 11(2):192–198.
[10] Cantrell, W. A., Petty, M. D., Knight, S. L., and Schueler, W. K. Physics-based
62

BIBLIOGRAFIE 63
modeling of crowd evacuation in the unity game engine. International Journal of
Modeling, Simulation, and Scientific Computing .
[11] Fear, E. (2009). United they stand, how three guys found unity in starting a
revolution.
[12] Fernando, R. (2004). GPU Gems: Programming Techniques, Tips and Tricks for
Real-Time Graphics . Pearson Higher Education.
[13] Fisher, M. (2014). Gpuview. https://graphics.stanford.edu/~mdfisher/
GPUView.html .
[14] Formosa, N. J., Morrison, B. W., Hill, G., and Stone, D. (2018). Testing
the efficacy of a virtual reality-based simulation in enhancing users’ knowledge,
attitudes, and empathy relating to psychosis. Australian Journal of Psychology ,
70(1):57–65.
[15] Fung, W. W. L., Sham, I., Yuan, G., and Aamodt, T. M. (2007). Dynamic warp
formation and scheduling for efficient gpu control flow. In 40th Annual IEEE/ACM
International Symposium on Microarchitecture (MICRO 2007) , pages 407–420.
[16] Jenner, A. Crtc emulation for mess. https://www.reenigne.org/blog/
crtc-emulation-for-mess/ .
[17] Lin, J. Starcraft ll fried my video card: Here’s a quick fix. http://techland.time.
com/2010/08/10/starcraft-ll-fried-my-video-card-heres-a-quick-fix/ . Accesat:
aprilie 2018.
[18] Marschner, S. and Shirley, P. (2016). Fundamentals of Computer Graphics,
Fourth Edition . A. K. Peters, Ltd., Natick, MA, USA, 4th edition. pag. 646.
[19] Mironov, V ., Khrenova, M., and Moskovsky, A. (2015). On Quantum Chemistry
Code Adaptation for RSC PetaStream Architecture , pages 113–121. Springer
International Publishing, Cham.
[20] Nie, Xiao;Chen, L. T. (2015). Real-time incompressible fluid simulation on the
gpu. International Journal of Computer Games Technology , 2015.
[21] Nobile, M. S., Cazzaniga, P., Tangherloni, A., and Besozzi, D. (2017). Graphics
processing units in bioinformatics, computational biology and systems biology.
https://doi.org/10.1093/bib/bbw058 .

BIBLIOGRAFIE 64
[22] Petzold, C. (1998). Programming Windows, Fifth Edition . Microsoft Press,
Redmond, WA, USA, 5th edition. pag. 54,74.
[23] Rowland, A. (2011). Unity technologies lands $12 million in series b funding led
by westsummit capital and iglobe partners. Market Wired .
[24] Singer, G. The history of the modern graphics processor. https://www.techspot.
com/article/650-history-of-the-gpu/ . Accesat: aprilie 2018.
[25] Technologies, U. Free games by the numbers report (2016 q1).
http://response.unity3d.com/games-by-the-numbers-q1-2016-report?
utm_source=unity3d&utm_medium=blog&utm_campaign=
analytics-whitepaper-2016-04-28-Global-Games-By-The-Numbers-2016-Q1-Report .
[26] Williams, L. (1983). Pyramidal parametrics. SIGGRAPH Comput. Graph. ,
17(3):1–11.
[27] Xu, Y ., Kim, E., Lee, K., Ki, J., and Lee, B. (2013). Fds simulation high rise
building model for unity 3d game engine. International Journal of Smart Home ,
7(5):263–274.
[28] Xueying, L., Shi, M., and Li, C. (2017). Design and implement of swarm self-
organization model based on unity3d. In 2017 IEEE 2nd Information Technology,
Networking, Electronic and Automation Control Conference (ITNEC) , pages 146–
149.
[29] Zink, J., Pettineo, M., and Hoxley, J. (2011). Practical Rendering and
Computation with Direct3D 11 . A. K. Peters, Ltd., Natick, MA, USA, 1st edition.

Similar Posts

  • INTRODUCЕRЕ ………………………….. ………………………….. ………………………….. ………. 3 CАРITOLUL I. INTRODUCЕRЕА… [625223]

    1 INFR АCȚIUN ЕА DЕ VIOL ȘI TЕNTАTIVА DЕ VIOL 2 CUРRINS: INTRODUCЕRЕ ………………………….. ………………………….. ………………………….. ………. 3 CАРITOLUL I. INTRODUCЕRЕА ÎN РROBLЕMАTICА АBORDАTĂ ……….. 5 1.1. Istoriа incriminării violului din аntichitаtе рână în ерocа modеrnă ……………….. 5 1.2. Rереrе dе ordin juridic. Еvoluțiа incriminăriii violului ре tеritoriilе românеști . 8 1.3. Аnаlizа situаțiеi în…

  • Cercetareadefațăvizeazăreglementareamunciitinerilorîndreptulnaționalși [606970]

    2INTRODUCERE Cercetareadefațăvizeazăreglementareamunciitinerilorîndreptulnaționalși europen,deoarececonsidercăesteundomeniudeactualitatecareareuncaracter ridicatdeinterespublicavândînvederecătineriireprezintăocategorievulnerabilăde lucrătoricarenecesităunregimspecialdeprotecție. Nuîntâmplător,OrganizațiaInternaționalăaMunciișiUniuneaEuropeanăau adoptatoseriedenorme,convenții,recomandărișidirectivecarevizeazăprotecția tinerilorlaloculdemuncă. Dreptconsecință,legiuitorulromânprecumșiceldinaltețăriauadoptatoseriede reglementăripecarelevoianalizaînprimeledouăcapitolealeacesteilucrări. Încadrulacesteicercetăriștiințificeamevidențiatimpactulaspectelorteoreticeși practiceasupraevoluțieicadruluilegislativdinsistemuljuridicromânescînmaterie,în raportcuevoluțialanivelulUniuniiEuropeneșiaaltorțăridezvoltatedinpunctde vedereeconomicșijuridicdinEuropa. Evoluțianormelorlaniveleuropeanșipașiiimportanțifăcuțiînultimaperioadăîn direcțiaprotecțieijuridiceatinerilorlaloculdemuncăesteevidentășireprezintăun progressubstanțialînstructurauneiconcepțiicoerentedeprotecție. Reglementareaprotecțieitinerilorsalariațiaconstituitșiconstituieozonăde competențăexclusivăfiecăruistat. Caobiectivgeneral,îmipropunidentificarea,selectareașisistematizarea materialuluinormativspecific,adoctrineișiapracticilordindomeniu,studierea acestoraînscopulprezentăriiaspectelorpozitive,darșinegativeșiînconcluziesăîmi exprimcâtevapunctedevederepropriipetemaabordată. ÎndefinitivvreausăanalizezinfluențelepecareaderareaRomânieilaUniunea Europeanăle-aimpusîndreptulmunciirespectivinstituțiilorvizândprotecțiatinerilor șiaminorilorlaloculdemuncă. PotconcluzionacăînprezentRomâniaaplicădirectșitotodatăadoptăprin transpunere,normeșidirectiveexistentelanivelcomunitar. 3CapitolulI.Protecțiatinerilorlaloculdemuncăîndreptulnațional Înțaranoastră,necesitateașiobligativitateaexistențeireglementărilorînceeace priveșteprotecțiatinerilorlaloculdemuncăconstituieoprioritate,avândînvedere condițiilededesfășurareaproceselordemuncădecătreacestsegmentalpopulației, subaspectulprotejăriitinerilorfațădeoricemuncăsusceptibilăsădăunezesecurității, sănătățiisaudezvoltăriifizice,psihologice,moralesausociale,sausălepericliteze educația.1. Înlegislațiaromână,reglementărileprivindprotecțiamunciitinerilor-sintetizateîn Codulmuncii.2,HotărâreaGuvernuluinr.600/2007privindprotecțiatinerilorlalocul demuncă.3șiHotărâreaGuvernuluinr.867/2009privindinterzicereacelormaigrave formealemunciiminorilorșiacțiuneaimediatăînvedereaeliminăriilor,Convențianr. 138dinanul1973șiRecomandareanr.146dinacelașianprivindvârstaminimăde incadrareînmuncă,șicuDirectivanr.94referitoarelaprotecțiatinerilorînmuncă. Articolul41alineatul2dinConstituțiaRomânieiconsacrădreptullaprotecția socialășilamăsuriledesecuritateșiigienăamuncii. Statulestecelcarereglementeazăsistemuldesănătateșisecuritateînmuncăși impuneobligațiiînacestsensînsarcinaangajatorilor,organelorcuatribuțiiîn domeniu,salariațilorșialtorparticipanțilaproceseledemuncă.4.Aceastăactivitatenu estelăsatălalatitudinaangajatorilorsauasalariaților,eafiindreglementatăîntoate domeniileviețiieconomiceșisociale,iarstatulrealizeazășicontrolulacesteiactivități prinorganespecializate.5. 1MargaretaSavancea,Protecțiatinerilorlaloculdemuncă,în”Revistaromânădedreptulmuncii”nr.8/2010, p.55-56. 2RepublicatînMonitorulOficialalRomâniei,ParteaI,nr.345din18mai2011,modificatulteior,inclusiv prinLegeanr.97/2015pentrumodificareaart.137alin.(1)dinLegeanr.53/2003-CodulMuncii(publicatăîn MonitorulOficialalRomâniei,ParteaInr.316din8mai2015). 3PublicatăînMonitorulOficialalRomâniei,ParteaI,nr.473din13iulie2007,modificatăulterior,inclusiv…

  • 1UNIVERSITATEA”VALAHIA”DINTÂRGOVIȘTE FACULTATEADEȘTIINȚEECONOMICE SPECIALIZAREA:FINANȚEBĂNCI OPERAȚIUNIBANCAREPRIVINDACORDAREADE… [625754]

    1UNIVERSITATEA"VALAHIA"DINTÂRGOVIȘTE FACULTATEADEȘTIINȚEECONOMICE SPECIALIZAREA:FINANȚEBĂNCI OPERAȚIUNIBANCAREPRIVINDACORDAREADE CREDITEPENTRUPERSOANEFIZICE(RETAIL BANKING)ÎNCADRULBCR PROFESORCOORDONATOR: Conf.univ.dr.DRĂGOIVioleta STUDENTĂ: TUDORACHEAndreea 2019 2UNIVERSITATEA"VALAHIA"DINTÂRGOVIȘTE FACULTATEADEȘTIINȚEECONOMICE SPECIALIZAREA:FINANȚEBĂNCI OPERAȚIUNIBANCAREPRIVINDACORDAREADE CREDITEPENTRUPERSOANEFIZICE(RETAIL BANKING)ÎNCADRULBCR PROFESORCOORDONATOR: Conf.univ.dr.DRĂGOIVioleta STUDENTĂ: TUDORACHEAndreea 2019 3Cuprins Introducere/4 CAPITOLUL1.ABORDAREATEORETICĂ 1.1.Retailbanking-definireșievoluție/5 1.2.Avantajeleșidezavantajeleoperațiunilorbancareprivindacordareadecredite/7 1.3.Produsele/serviciileșisoluțiileînretailbanking/9 1.4.RetailbanckingînEuropa/10 CAPITOLUL2.CREDITULȘIRISCURILESALE 2.1.Definirreacredituluișiclasificareasa/12 2.2.Risculdecredit/13 2.3.Măsurarearisculuidecredit/15 CAPITOLUL3.BCR-PREZENTAREGENERALĂ 3.1.Istoric,viziuneșiacționari/16 3.2.Structurașicaracteristicileproduselor/serviciiloracordatedebancăpersoanelor fizice/17 3.3.Datelefinanciare/19 CAPITOLUL4.RETAILBANKINGÎNCADRULBCR 4.1.Analizăcomparativă-BCRșiGarantyBankprivindoperațiuniledeacordare credite/21 4.2.StudiuprivindsatisfacțiacliențilorBCRînceeaceprivescproduseleșiserviciile oferite/22 4.3.AnalizaSWOTaBCR/32 CONCLUZIIȘIPROPUNERI/33 Bibilografie/35 Anexe/37 4Introducere Bănciledinsectorulretailbanckingfolosescfonduriledeponențilorpentruaface împrumuturi.Acesteapercepratealedobânziimaimarilaîmprumuturidecâtplătescla depoziteînscopulobțineriiprofitului.Cuexcepțiacelormaimicibănci,estenecesarcatoate celelaltesăpăstrezeaproximativ10%dindepozitelelorînrezervăînfiecarenoapte,iar restulsuntliberesăîmprumute. Schimbareaparadigmeitehnologieiageneratexploziaretailbancking.Instituțiile financiaretrebuiesăreproiectezeafacerealorconvențională,darșisăîmbunătățească…

  • École Supérieure de la Francophonie pour lAdministration et le Management [303762]

    École Supérieure de la Francophonie pour l’Administration et le Management Master Administration des Entreprises Rapport de stage LA GESTION DU PERSONNEL DANS LE CONTEXTE DES SUIVIS DES PROJETS DANS L’ENTREPRISE SF SANS FRONTIÈRE Étudiante : SVETENCO Anastasia Tuteur académique de stage : HÉNAULT Georges Tuteur professionnel de stage : SCUTELNIC Svetlana Période de stage : juillet – septembre 2016…

  • The Wisdom of the Enneagram [622195]

    ÎNȚELEPCIUNEA ENEAGRAMEI Don Richard Riso și Russ Hudson Editura Mix există pentru a aduce valoare in viața dumneavoastră. ÎNȚELEPCIUNEA ENEAGRAMEI Don Richard Riso și Russ Hudson Traducere: Dr. Gabriela Marin professional member of International Enneagram Association ® EDITURA MIX Brașov, 2008 Culegere: Gabriela Marin Tehnoredactare: Florin Druțu Copertă: Sanda Arsene Consilier editorial: Florin Zamfir Autorul…

  • Știința se bazează pe raționamentul cauză-efect. Prin [631595]

    „Știința se bazează pe raționamentul cauză-efect. Prin urmare, este imposibil ca atunci când cineva leagă efectele de cauzele lor imediate, apoi cauzele acestea de cauzele lor, să nu fie confruntat în cele din urmă cu întrebarea referitoare la CAUZA PRIMARĂ.” Henry M. Morris BIBLIOTECA BIOS ALF A ISBN: 973 -8278 -36-8 Ion Gr. CUCU Vasile…