Triangelremsa
Inom datorgrafik är en triangelremsa en delmängd av trianglar i ett triangelnät med delade hörn och är en mer minneseffektiv metod för att lagra information om nätet. De är effektivare än oindexerade triangellistor, men vanligtvis lika snabba eller långsammare än indexerade triangellistor. Det främsta skälet till att använda triangelremsor är att minska mängden data som behövs för att skapa en serie trianglar. Antalet hörn lagrade i minnet reduceras från 3 N till N + 2 , där N är antalet trianglar som ska ritas. Detta möjliggör mindre användning av diskutrymme , samt gör dem snabbare att ladda in i RAM .
Till exempel skulle de fyra trianglarna i diagrammet, utan att använda triangelremsor, behöva lagras och tolkas som fyra separata trianglar: ABC, CBD, CDE och EDF. Men med hjälp av en triangelremsa kan de enkelt lagras som en sekvens av hörn ABCDEF. Denna sekvens skulle avkodas som en uppsättning trianglar med hörn vid ABC, BCD, CDE och DEF - även om den exakta ordningen som hörnen läses inte kommer att vara i vänster-till-höger-ordning eftersom detta skulle resultera i intilliggande trianglar vända mot alternerande riktningar .
OpenGL implementering
OpenGL har inbyggt stöd för triangellister. Fast funktion OpenGL (utfasad i OpenGL 3.0) har stöd för triangelremsor med omedelbart läge och funktionerna glBegin ()
, glVertex * ()
och glEnd () .
Nyare versioner stöder triangelremsor med glDrawElements
och glDrawArrays
.
För att rita en triangelremsa med omedelbart läge OpenGL måste glBegin ()
passeras argumentet GL_TRIANGLE_STRIP
, vilket meddelar OpenGL att en triangelremsa är på väg att ritas. Funktionsfamiljen glVertex * ()
anger koordinaterna för varje vertex i triangelremsan. För mer information, se The OpenGL Redbook.
För att rita triangelremsan i diagrammet med omedelbart läge OpenGL, är koden som följer:
//Vertices nedan är i medurs orientering //Standardinställningen för glFrontFace är Moturs glFrontFace ( GL_CW ); glBegin ( GL_TRIANGLE_STRIP ); glVertex3f ( 0.0f , 0.0f , 0.0f ); //vertex 1 glVertex3f ( 0.0f , 0.5f , 0.0f ); //vertex 2 glVertex3f ( 0.5f , 0.0f , 0.0f ); //vertex 3 glVertex3f ( 1.0f , 0.5f , 0.0f ); //vertex 4 glEnd ();
Observera att endast en extra vertex behövs för att rita den andra triangeln. I OpenGL är ordningen i vilken hörn specificeras viktig så att ytnormalerna är konsekventa.
Citerar direkt från OpenGL-programmeringsguiden :
GL_TRIANGLE_STRIP
Ritar en serie trianglar (tresidiga polygoner) med hörn v0, v1, v2, sedan v2, v1, v3 (notera ordningen), sedan v2, v3, v4 och så vidare. Beställningen är att säkerställa att trianglarna ritas med samma orientering så att remsan korrekt kan utgöra en del av en yta.
Det är ännu tydligare på manualsidorna:
Ritar en sammankopplad grupp trianglar. En triangel definieras för varje hörn som presenteras efter de två första hörnen. För udda n definierar hörn n , n + 1 och n + 2 triangeln n . För jämna n definierar hörn n + 1 , n och n + 2 triangeln n . n – 2 trianglar ritas.
Observera att n börjar på 1. Ovanstående kodexempel och diagram visar trianglar ritade medurs. För att de ska betraktas som vända framifrån krävs ett föregående anrop till glFrontFace ( GL_CW ) , som annars har ett initialt värde på
GL_CCW
(vilket betyder att trianglar som dras moturs är vända fram som standard). Detta är viktigt om glEnable ( GL_CULL_FACE )
och glCullFace ( GL_BACK )
redan är aktiva ( GL_BACK
som standard), eftersom bakåtvända trianglar kommer att tas ut, så de kommer inte att ritas och visas inte alls på skärmen.
Fastigheter och konstruktion
Det följer av definitionen att en undersekvens av hörn av en triangelremsa också representerar en triangelremsa. Men om denna delremsa börjar vid en jämn (med 1-baserad räkning) vertex, kommer de resulterande trianglarna att ändra sin orientering. Till exempel skulle en delremsa BCDEF representera trianglar: BCD,CED,DEF.
På liknande sätt kommer omkastning av remsornas hörn att resultera i samma uppsättning trianglar om remsan har ett jämnt antal hörn. (t.ex. kommer remsan FEDCBA att representera samma trianglar FED,ECD,DCB,CAB som den ursprungliga remsan). Men om en remsa har ett udda antal hörn kommer den omvända remsan att representera trianglar med motsatt orientering. Till exempel kommer omkastning av en remsa ABCDE att resultera i remsa EDCBA som representerar trianglar EDC, DBC, CBA).
Att konvertera ett allmänt polygonnät till en enda lång remsa var tills nyligen i allmänhet inte möjligt. Vanligtvis är triangelremsorna analoga med en uppsättning kantöglor , och stolpar på modellen representeras av triangelfläktar . Verktyg som Stripe eller FTSG representerar modellen som flera remsor. Att optimalt gruppera en uppsättning trianglar i sekventiella remsor har visat sig vara NP-komplett .
Alternativt kan ett komplett objekt beskrivas som en degenererad remsa , som innehåller noll-area trianglar som bearbetningsmjukvaran eller hårdvaran kommer att kassera. De degenererade trianglarna introducerar effektivt diskontinuiteter eller "hopp" till remsan. Till exempel kan nätet i diagrammet också representeras som ABCDDFFEDC, vilket skulle tolkas som trianglar ABC CBD CDD DDF DFF FFE FED DEC (degenererade trianglar markerade med kursiv stil). Lägg märke till hur den här remsan först bygger två trianglar från vänster, sedan startar om och bygger de återstående två från höger.
Även om diskontinuiteter i triangelremsor alltid kan implementeras genom att skicka om hörn, stödjer API:er ibland uttryckligen denna funktion. IRIS GL stödde Swaps (vända två efterföljande hörn i en remsa), en funktion som förlitas på av tidiga algoritmer som SGI-algoritmen . Nyligen kan OpenGL/DirectX rendera flera triangelremsor utan degenererade trianglar med hjälp av Primitive Restart-funktionen.