Home » Articole » Articole » Calculatoare » Imagini » Grafica pe calculator: OpenGL 1.1- Geometrie

Grafica pe calculator: OpenGL 1.1- Geometrie

postat în: Imagini 0

Este timpul să trecem la grafica computerizată în trei dimensiuni, deși nu vom intra cu adevărat în 3D până în Secțiunea 2 a acestui capitol. Veți descoperi că multe concepte din grafica 2D sunt transferate în 3D, dar trecerea în dimensiunea a treia aduce cu sine câteva caracteristici noi pentru care e nevoie de ceva timp cu care să ne obișnuim.

Accentul nostru va fi OpenGL, un API grafic care a fost introdus în 1992 și a trecut prin multe versiuni și multe modificări de atunci. OpenGL este un API grafic de nivel scăzut, similar cu API-urile 2D pe care le-am acoperit. Este și mai primitiv în anumite privințe, dar, desigur, este complicat de faptul că acceptă 3D.

Pentru următoarele două capitole, discuția se limitează la OpenGL 1.1. OpenGL 1.1 este un API mare și vom acoperi doar o parte din acesta. Scopul este de a introduce concepte de grafică 3D, nu de a acoperi complet API-ul. O parte semnificativă a ceea ce acoperim aici a fost eliminată din cele mai moderne versiuni de OpenGL. Cu toate acestea, OpenGL modern în forma sa pură are o curbă inițială de învățare foarte abruptă și chiar nu este un bun loc de plecare pentru cineva care întâlnește grafica 3D pentru prima dată. Este nevoie de un suport suplimentar – dacă nu OpenGL 1.1, atunci un cadru similar. Deoarece OpenGL 1.1 este încă acceptat, cel puțin de toate implementările OpenGL pe desktop, este un loc rezonabil pentru a începe.

Acest capitol se concentrează pe aspectele geometrice ale graficii 3D, cum ar fi definirea și transformarea obiectelor și proiectarea scenelor 3D în imagini 2D. Imaginile pe care le producem vor părea foarte nerealiste. În capitolul următor, vom vedea cum să adăugăm ceva realism prin simularea efectelor luminii și ale proprietăților materiale ale suprafețelor.

Forme și culori în OpenGL 1.1

Această secțiune prezintă câteva dintre caracteristicile de bază ale OpenGL. O mare parte din discuția din această secțiune este limitată la 2D. Pentru moment, tot ce trebuie să știți despre 3D este că adaugă o a treia direcție la direcțiile x și y care sunt utilizate în 2D. Prin convenție, a treia direcție se numește z. În sistemul de coordonate implicit, direcția pozitivă a axei z indică într-o direcție perpendiculară pe imagine.

În sistemul de coordonate implicit pentru OpenGL, imaginea arată o regiune a spațiului 3D în care x, y și z variază de la minus unu la unu. Pentru a afișa o regiune diferită, trebuie să aplicați o transformare. Pentru moment, vom folosi doar coordonatele care se află între -1 și 1.

O notă despre programare: OpenGL poate fi implementat în multe limbaje de programare diferite, dar specificația API presupune mai mult sau mai puțin că limbajul este C. În cea mai mare parte, specificația C se traduce direct în alte limbi. Principalele diferențe se datorează caracteristicilor speciale ale tablourilor în limbajul C. Exemplele mele vor urma sintaxa C, cu câteva note despre modul în care lucrurile pot fi diferite în alte limbi. Deoarece urmez API-ul C, mă voi referi la „funcții” mai degrabă decât la „subrutine” sau „metode”. Secțiunea 3.6 explică în detaliu cum să scrieți programe OpenGL în C și în Java. Va trebui să consultați acea secțiune înainte de a putea face orice programare reală. Demo-urile live OpenGL 1.1 pentru această carte sunt scrise folosind un simulator JavaScript care implementează un subset al OpenGL 1.1. Acest simulator este discutat și în Secțiunea 3.6.

Primitive OpenGL

OpenGL poate desena doar câteva forme de bază, inclusiv puncte, linii și triunghiuri. Nu există suport încorporat pentru curbe sau suprafețe curbate; ele trebuie aproximate prin forme mai simple. Formele de bază sunt denumite primitive. O primitivă în OpenGL este definită de vârfurile sale. Un vârf este pur și simplu un punct în 3D, dat de coordonatele sale x, y și z. Să sărim direct și să vedem cum să desenăm un triunghi. Este nevoie de câțiva pași:

glBegin(GL_TRIANGLES);
glVertex2f( -0.7, -0.5 );
glVertex2f( 0.7, -0.5 );
glVertex2f( 0, 0.7 );
glEnd();

Fiecare vârf al triunghiului este specificat printr-un apel la funcția glVertex2f. Trebuie specificate vârfuri între apelurile la glBegin și glEnd. Parametrul pentru glBegin spune ce tip de primitivă este desenat. Primitiva GL_TRIANGLES vă permite să desenați mai mult de un triunghi: trebuie doar să specificați trei vârfuri pentru fiecare triunghi pe care doriți să-l desenați.

(Ar trebui să notez că aceste funcții trimit de fapt comenzi către GPU. OpenGL poate salva loturi de comenzi pentru a le transmite împreună, iar desenul nu se va face de fapt până când comenzile nu sunt transmise. Pentru a se asigura că acest lucru se întâmplă, funcția glFlush() trebuie apelată În unele cazuri, această funcție poate fi apelată automat de un API OpenGL, dar s-ar putea să întâlniți momente când trebuie să o apelați singur.)

Pentru OpenGL, nodurile au trei coordonate. Funcția glVertex2f specifică coordonatele x și y ale vârfului, iar coordonata z este setată la zero. Există, de asemenea, o funcție glVertex3f care specifică toate cele trei coordonate. „2” sau „3” din nume indică câți parametri sunt trecuți funcției. „f” de la sfârșitul numelui indică faptul că parametrii sunt de tip float. De fapt, există și alte funcții „glVertex”, inclusiv versiuni care preiau parametri de tip int sau double, cu nume precum glVertex2i și glVertex3d. Există chiar și versiuni care iau patru parametri, deși nu va fi clar pentru o vreme de ce ar trebui să existe. Și, așa cum vom vedea mai târziu, există versiuni care iau ca parametri o serie de numere în loc de numere individuale. Întregul set de funcții de vârf este adesea denumit „glVertex*”, cu „*” în locul specificației parametrului. (Proliferarea numelor se datorează faptului că limbajul de programare C nu acceptă supraîncărcarea numelor de funcții; adică, C distinge funcțiile numai după numele lor și nu după numărul și tipul parametrilor care sunt transferați funcției. )

OpenGL 1.1 are zece tipuri de primitive. Șapte dintre ele există încă în OpenGL modern; celelalte trei au fost abandonate. Cea mai simplă primitivă este GL_POINTS, care pur și simplu redă un punct la fiecare vârf al primitivei. În mod implicit, un punct este redat ca un singur pixel. Mărimea primitivelor punct poate fi modificată prin apelare

glPointSize(size);

unde parametrul, size, este de tip float și specifică diametrul punctului randat, în pixeli. În mod implicit, punctele sunt pătrate. Puteți obține puncte circulare apelând

glEnable(GL POINT SMOOTH);

Funcțiile glPointSize și glEnable schimbă „starea” OpenGL. Starea include toate setările care afectează redarea. Vom întâlni multe funcții care schimbă starea. Funcțiile glEnable și glDisable pot fi folosite pentru a activa și dezactiva multe funcții. În general, regula este că orice caracteristică de randare care necesită calcul suplimentar este dezactivată în mod implicit. Dacă doriți această funcție, trebuie să o activați apelând glEnable cu parametrul corespunzător.

Există trei primitive pentru desenarea segmentelor de linie: GL_LINES, GL_LINE_STRIP și GL_LINE_LOOP. GL_LINES desenează segmente de linie deconectate; specificați două vârfuri pentru fiecare segment pe care doriți să îl desenați. Celelalte două primitive desenează secvențe conectate de segmente de linie. Singura diferență este că GL_LINE_LOOP adaugă un segment de linie suplimentar de la vârful final înapoi la primul vârf. Iată ce obțineți dacă utilizați aceleași șase vârfuri cu cele patru primitive pe care le-am văzut până acum:

Punctele A, B, C, D, E și F au fost specificate în această ordine. În această ilustrație, toate punctele se află în același plan, dar rețineți că, în general, punctele pot fi oriunde în spațiul 3D.

Lățimea pentru primitivele de linie poate fi setată apelând glLineWidth(width). Lățimea liniei este întotdeauna specificată în pixeli. Nu este supusă scalarii prin transformări.

Să ne uităm la un exemplu. OpenGL nu are o primitivă cerc, dar putem aproxima un cerc desenând un poligon cu un număr mare de laturi. Pentru a desena un contur al poligonului, putem folosi o primitivă GL_LINE_LOOP:

glBegin( GL_LINE_LOOP );
for (i = 0; i < 64; i++) {
    angle = 6.2832 * i / 64; // 6.2832 represents 2*PI
    x = 0.5 * cos(angle);
    y = 0.5 * sin(angle);
    glVertex2f( x, y );
}
glEnd();

Aceasta face o aproximare pentru circumferința unui cerc cu raza 0,5 cu centrul la (0,0). Amintiți-vă că pentru a învăța cum să utilizați exemple ca acesta într-un program complet care rulează, va trebui să citiți Secțiunea 3.6. De asemenea, este posibil să trebuiască să faceți unele modificări codului, în funcție de implementarea OpenGL pe care o utilizați.

Următorul set de primitive este pentru desenarea triunghiurilor. Există trei dintre ele: GL_TRIANGLES, GL_TRIANGLE_STRIP și GL_TRIANGLE_FAN.

Cele trei triunghiuri din stânga formează o primitivă GL_TRIANGLES, cu nouă vârfuri. Cu acea primitivă, fiecare set de trei vârfuri formează un triunghi separat. Pentru o primitivă GL_TRIANGLE_STRIP, primele trei vârfuri produc un triunghi. După aceea, fiecare vârf nou adaugă un alt triunghi la bandă, conectând noul vârf la cele două vârfuri anterioare. Două primitive GL_TRIANGLE_FAN sunt afișate în dreapta. Din nou pentru un GL_TRIANGLE_FAN, primele trei vârfuri formează un triunghi, iar fiecare vârf după aceea adaugă un triunghi anteră, dar în acest caz, noul triunghi este realizat prin conectarea noului vârf la vârful anterior și la primul vârf care a fost specificat. (vârful „A” din imagine). Rețineți că GL_TRIANGLE_FAN poate fi folosit pentru a desena poligoane completate. În această imagine, apropo, punctele și liniile nu fac parte din primitivă; OpenGL ar desena doar interioarele verzi și completate ale figurilor.

Cele trei primitive rămase, care au fost eliminate din OpenGL modern, sunt GL_QUADS, GL_QUAD_STRIP și GL_POLYGON. Numele „quad” este prescurtarea pentru patrulater, adică un poligon cu patru laturi. Un quad este determinat de patru vârfuri. Pentru ca un quad să fie redat corect în OpenGL, toate vârfurile quad-ului trebuie să se afle în același plan. Același lucru este valabil și pentru primitivele poligoane. În mod similar, pentru a fi redate corect, quad-urile și poligoanele trebuie să fie convexe (vezi Subsecțiunea 2.2.3). Deoarece OpenGL nu verifică dacă aceste condiții sunt îndeplinite, utilizarea quad-urilor și a poligoanelor este predispusă la erori. Deoarece aceleași forme pot fi produse cu ușurință cu primitivele triunghiulare, acestea nu sunt cu adevărat necesare, dar aici sunt câteva exemple:

Nodurile pentru aceste primitive sunt specificate în ordinea A, B, C, …. Observați cum diferă ordinea pentru cele două primitive quad: Pentru GL_QUADS, nodurile pentru fiecare quad individual ar trebui specificate în ordinea inversă acelor de ceasornic în jurul quad-ului; pentru GL_QUAD_STRIP, nodurile ar trebui să alterne de la o parte la cealaltă a benzii.

Sursa: David J. Eck, Introduction to Computer Graphics (Eck), LibreTexts, licența CC BY-NC-SA 4.0. Traducere și adaptare Nicolae Sfetcu

Ghid Facebook pentru utilizatori
Ghid Facebook pentru utilizatori

Un ghid complet îți oferă toate informațiile esențiale pentru a naviga eficient pe Facebook.

Nu a fost votat 9.14 lei Selectează opțiunile Acest produs are mai multe variații. Opțiunile pot fi alese în pagina produsului.
Introducere în Business Intelligence
Introducere în Business Intelligence

O resursă esențială pentru toți cei interesați de analiza datelor și de optimizarea proceselor de afaceri.

Nu a fost votat Interval de prețuri: 13.74 lei până la 24.67 lei Selectează opțiunile Acest produs are mai multe variații. Opțiunile pot fi alese în pagina produsului.
PowerPoint - Ghid pentru începători
PowerPoint – Ghid pentru începători

Descoperă tainele PowerPoint-ului cu un ghid complet și gratuit!

Nu a fost votat 0.00 lei Selectează opțiunile Acest produs are mai multe variații. Opțiunile pot fi alese în pagina produsului.


Descoperă mai multe la MultiMedia

Abonează-te ca să primești ultimele articole prin email.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *