Moin, mir sind beim Rumprobieren zwei allgemeine Fragen zur Graphikprogrammierung gekommen. 1: Wird jedes Bild (oder Frame) komplett neu gezeichnet? In Java benutze ich für 2D-Graphik die paint()-Funktion, die jedes Mal die ganze Fläche leert und dann jedes Objekte neu zeichnet. Wird das in der 3D-Graphik auch so gemacht? Ich stelle mir das ziemlich ineffektiv vor, wenn ein Objekt geändert wird, alles neu zu zeichnen. Aber andererseits weiß ich nicht, wie es allgemeingültig sonst gehen könnte. 2: Wer übernimmt das Zeichnen der Objekte in der 3D-Graphik? Gibt es eine einzige paint()-Funktion, die alle Objekte selber zeichnet oder hat jedes Objekt seine eigene paint()-Funktion, die von der 'obersten' Funktion zyklisch aufgerufen wird? Als Beispiel, was ich meine, sollen 2D Rechtecke und Elipsen gezeichnet werden. Das könnte man auf zwei Arten lösen. Entweder die paint()-Funktion bekommt eine Liste aller Rechtecke und Kreise und macht dann sowas wie for Alle Rechtecke ZeichneRechteck(i.x,i.y,i.Höhe,i.Breite); for Alle Elipsen ZeichneElipse(i.x,i.y,i.Höhe,i.Breite); oder die Funktion ruft die paint()-Funktion jedes Objekts auf for Alle Rechtecke Rechteck[i].paint(); for Alle Kreise Elipse_[i].paint(); Der Unterschied ist, dass im ersten Fall die paint()-Funktion alle Objekte zeichnen kann, während sie im zweiten Fall nur nacheinander die Objekte aufruft, die sich daraufhin selber zeichnen. Wie wird das im Allgemeinen zum Beispiel bei Spielen gemacht? Die Fragen beziehen sich auf die Hochsprachenprogrammierung, zum Beispiel mit DirectX oder OpenGL, nicht auf die Hardwareebene.
http://de.wikipedia.org/wiki/Bildsynthese Fang dort mal an zu lesen. Vielleicht hilft dir das. Grüße Julian
Dussel schrieb: > Moin, > mir sind beim Rumprobieren zwei allgemeine Fragen zur > Graphikprogrammierung gekommen. > > 1: Wird jedes Bild (oder Frame) komplett neu gezeichnet? In Java benutze > ich für 2D-Graphik die paint()-Funktion, die jedes Mal die ganze Fläche > leert und dann jedes Objekte neu zeichnet. Wird das in der 3D-Graphik > auch so gemacht? Ich stelle mir das ziemlich ineffektiv vor, wenn ein > Objekt geändert wird, alles neu zu zeichnen. Wenn ein Objekt geändert wird, dann kennt man auch den Bereich am Bild, der sich durch diese Änderung verändert (das klingt jetzt banal, ist es auch). Logischerweise kann sich daher auch nur bei den Objekten an der Darstellung was ändern (die können zb verdeckt werden oder aus der Verdeckung auftauchen), die ihr Bild in diesem Bereich haben. Daher genügt es, wenn man nur alle Objekte in diesem Bereich neu zeichnet. Du sollt nicht den Box-Test ausser acht lassen. Der ist ein wichtiger Anlaufpunkt um Dinge zu beschleunigen. Grob gesagt geht es nicht darum den Bereich bis ins letzte Detail zu kennen, sondern es genügt zu wissen, in welchem Rechteck (eben der 'Box') ein Objekt am Bild abgebildet wird. Wenn man keine inverse Information hat um aus dem Bild wieder auf die dargestellten Objekte in einem Pixel zu schliessen, dann dreht man das eben um. Man malt im Prinzip wieder das komplette Bild, wobei man Objekte, deren Box im Bild gar nicht im bewussten Bereich (der Invalidate-Box) liegen übergehen kann und nicht durch die Malroutine durch muss. Denn ihr Abbild liegt ja im Bild bereits vor und ändert sich auch nicht. > 2: Wer übernimmt das Zeichnen der Objekte in der 3D-Graphik? Gibt es > eine einzige paint()-Funktion, die alle Objekte selber zeichnet oder hat > jedes Objekt seine eigene paint()-Funktion, die von der 'obersten' > Funktion zyklisch aufgerufen wird? Kannst du machen wie du willst. Letzten Endes mündet aber alles in den zentralen System-Malroutinen. Das eine ist eben die Objektorientierte Sichtweise (Objekte malen sich unter zuhilfenahme der System-Malroutinen selber) das andere ist mehr die traditionelle Sichtweise, die benutzt wurde ehe OOP in Mode kam. > Als Beispiel, was ich meine, sollen 2D Rechtecke und Elipsen gezeichnet > werden. Das könnte man auf zwei Arten lösen. Entweder die > paint()-Funktion bekommt eine Liste aller Rechtecke und Kreise und macht > dann sowas wie > > for Alle Rechtecke > ZeichneRechteck(i.x,i.y,i.Höhe,i.Breite); > for Alle Elipsen > ZeichneElipse(i.x,i.y,i.Höhe,i.Breite); > > oder die Funktion ruft die paint()-Funktion jedes Objekts auf > > for Alle Rechtecke > Rechteck[i].paint(); > for Alle Kreise > Elipse_[i].paint(); No
1 | for all objects |
2 | object[i].paint(); |
und das object weiss selber wie 'paint' geht. Vorteil: der 'Verwalter' muss nichts weiter wissen, als das es objecte gibt und dass die sich selber malen können. Rechtecke und Ellipsen interessieren ihn nicht und brauchen ihn auch nicht zu interessieren. Was du gemacht hast, ist einfach nur Funktionsaufrufe ein wenig hin und herschieben. Das ändert aber konzeptionell nichts bzw. nicht viel.
:
Bearbeitet durch User
Julian V. schrieb: > Fang dort mal an zu lesen. Vielleicht hilft dir das. Danke, aber da geht es ja darum, wie die Objekte gezeichnet werden und nicht wodurch. Karl Heinz schrieb: > No for all objects > object[i].paint(); > > und das object weiss selber wie das geht. Stimmt, klar. Das war ich gedanklich noch beim ersten Beispiel. Karl Heinz schrieb: > Logischerweise kann sich daher auch nur bei den Objekten an der > Darstellung was ändern […] die ihr Bild in diesem Bereich haben. Daher > genügt es, wenn man nur alle Objekte in diesem Bereich neu zeichnet. Muss man das bei DirectX oder OpenGL von Hand bestimmen oder machen die das automatisch? Karl Heinz schrieb: > Letzten Endes mündet aber alles in den zentralen System-Malroutinen. Das ist klar. Irgendeine Funktion muss 'die Fäden in der Hand haben'. Karl Heinz schrieb: > Das eine ist eben die Objektorientierte Sichtweise Das ist dann wohl auch die heute gebräuchlichere.
Da du konkret nach OpenGl fragst: http://www.opengl-tutorial.org/ Schau dir einfach mal den Code dort an.
Erstmal noch Dank für die Antworten. Julian V. schrieb: > Da du konkret nach OpenGl fragst: http://www.opengl-tutorial.org/ > > Schau dir einfach mal den Code dort an. OpenGL-Tutorials habe ich natürlich schon gelesen (das Verlinkte noch nicht), aber in den meisten steht nur, wie man es grundsätzlich macht und nicht, wie man es schön/gut macht. Ich werde es mir trotzdem nochmal ansehen ;-)
Dussel schrieb: > OpenGL-Tutorials habe ich natürlich schon gelesen Wobei OpenGL ja wohl demnächst, jedenfalls für Linux, von GLnext bzw. Vulkan abgelöst werden soll? Zu Deinen anderen Fragen: 2D oder 3D macht natürlich schon einen großen Unterschied. Ebenso ob man für 2D Hardwarebeschleunigung hat. Ohne Hardwarebescheunigung, etwa mit Cairo, ist es schon recht langsam, wenn man jeweils alles neu zeichnet. Für meinen Schaltplaneditor habe ich daher für jedes Element eine Bounding-Box und versuche immer nur den Bereich zu Zeichnen, der verändert wurde. Aber leider ist das nicht ganz trivial -- wenn man etwa Schatten für angehobene Elemente hat, oder wenn etwa Linien dicker gemacht werden. Da kann die Box dann plötzlich zu klein sein. Es kommt also auf den Einzelfall an. Und wenn Du wirklich ein echter Dussel bist, dann würde ich einfach alles mit OpenGl jeweils neu Zeichnen, dann ist bei weitem am Einfachsten. Wobei -- wenn die Grafik interaktiv ist, dann hat man ja eh Boxen für die Elemente, etwa damit man sie greifen kann. Und bei Cairo habe ich eben sehr gute Qualität, etwa auch Beziere-Kurven, und viele Backends wie etwa PDF. Alternative hätte man aber auch Canvas Frameworks verwenden können, etwa Clutter oder Qt GraphicsView.
Dussel schrieb: > for Alle Rechtecke > ZeichneRechteck(i.x,i.y,i.Höhe,i.Breite); > for Alle Elipsen > ZeichneElipse(i.x,i.y,i.Höhe,i.Breite); > > oder die Funktion ruft die paint()-Funktion jedes Objekts auf > > for Alle Rechtecke > Rechteck[i].paint(); > for Alle Kreise > Elipse_[i].paint(); Oder schöner: Foreach(r : rectangles) rectangleRenderer.render(r) Analog dann für Kreise. Hat den Vorteil daß weder das Objekt noch der Renderer unnötig ueberladen sind. Das Rechteck kennt nur seine Position und Größe, der Rechteck-Renderer kann nur Rechtecke zeichnen hat aber nichts mit der Logik eines Rechteck es am Hut. Somit gibt es eine saubere Trennung von Geschäftslogik und Darstellung. Der Hauptrenderer ruft einfach für alle Objekte die spezifischen Renderer auf.
mop schrieb: > Oder schöner: Das geht so in die Richtung, wie man es vor 20 Jahren mitten im OOP Hype gelernt hat. Sieht zunächst ganz nett aus. Nur Rechteck hat eben auch Farbe, Linienstil, Schraffur und mehr. Die ganzen Parameter werden dann stets neu gesetzt. Wobei man bei OO ja eher ein allgemeines Grafik-Element hat, dass dann jeweils seine Draw() Methode aufruft,
mop schrieb: > nichts mit der Logik eines Rechteck es am Hut. Somit gibt es eine > saubere Trennung von Geschäftslogik und Darstellung. Der Hauptrenderer > ruft einfach für alle Objekte die spezifischen Renderer auf. Und dann noch mal abstrahieren. Der Hauptrenderer soll nicht wissen, welche Objekte es gibt. Ein spezifischer Renderer solle sich daher beim Programmstart registrieren und dabei mitteilen für welche Objekte er benutzt werden kann. Und jetzt wird das System dann plötzlich schon recht aufwändig. Hat aber den Vorteil, dass man zur Laufzeit (zb per DLL) neue Objekttypen 'nachschieben' kann. DLL für Bezier-Patches vorhanden, dann laden und die entsprechenden Objekte registrieren und schon kann das Graphiksystem auch mit Bezier Patches umgehen. Ok, ganz so einfach ist es dann auch wieder nicht, aber es geht schon mal in die Richtung.
Salewski, Stefan schrieb: > mop schrieb: >> Oder schöner: > > Das geht so in die Richtung, wie man es vor 20 Jahren mitten im OOP Hype > gelernt hat. Sieht zunächst ganz nett aus. Nur Rechteck hat eben auch > Farbe, Linienstil, Schraffur und mehr. Die ganzen Parameter werden dann > stets neu gesetzt. Nicht unbedingt. So ein Objekt rendert sich ja nicht im luftleeren Raum sondern in einer Umgebung, einem Canvas. Den kriegt die paint Methode natürlich mit und wenn da der Pen schon gesetzt ist, dann wird er vom Objekt nicht neu gesetzt. Und natürlich gibt es für jedes Objekt dann mehrere Zeichenmethoden. Eine die aufgerufen wird, wenn es sich normal zeichnen soll. Und eine die aufgerufen wird, wenn es sich selektiert zeichnen soll. Wobei man in letzterm Fall dann dem Objekt auch noch mitgeben kann, ob es bei einer Mehrfachselektion das hauptselektierte oder das nebenselektierte Objekt ist. Letzters ist zb interessant, wenn es zb Verfahren gibt, um mehrere Objekt nach einem ganz bestimmten Objekt auszurichten (zb alle selektierten Rechtecke an der linken Kante untereinanderstellen. Oder alle selektierten gleich breit machen) Alles in allem funktioniert aber ein OOP Ansatz hier schon nicht schlecht. Mein Standard 2D-Editor ist eine Sammlung von Objekten, die ich je nach Anforderungen zusammenkopiere und so den Editor konfiguriere. Da gibt es graphische Primitiva, Renderer, Werkzeuge, Operationen (der unterschied zwischen Operation und Werkzeug ist: Bei einer Operation wird zuerst selektiert und dann die Aktion ausgeführt, bei einem Werkzeug wird erst das Werkzeug angewählt und durch anklicken der Objekte wird die Aktion auf das jeweilige Objekt angewendet), Aktionen (Werkzeuge und Operationen handeln das GUI aus, Aktionen implemetieren die Manipulation), natürlich einen Malkontext, es gibt eine Propertyliste, in der jedes Objekt seine Eigenschaften auf Anforderung reingeben kann, enstprechende GUI Elemente die dem Benutzer eine Propertyliste zum Bearbeiten geben, Do/Undo Manager der Aktionen zwischenspeichert und bei Bedarf wieder rückgängig machen kann, etc. etc. Jedes Primitiv muss ein paar Operationen unterstützen, wie zb malen, Punkt zur Selektion auswerten, Selektiert sein, auf File laden, vom File speichern. Dinge wie Schnittpunkte hab ich so gelöst, dass es eigene Routinen gibt, die Schnittpunkte zwischen Primtivtypen berechnen können. Das ist ein Punkt an dem Mehrfach-polymorphe Aufrufe schmerzlich vermisst werden. C++ kann das nicht (Smalltalk könnte das). Der klassische Ansatz, mit einer weiterleitung über virtuelle Funktionen funktioniert leider nicht so gut. Hat man 10 unterschiedliche Primtivtypen, dann artet das in ein Chaos aus
1 | PointList Line::Intersect( Primitiv* with ) |
2 | {
|
3 | return with->Intersect( this ); |
4 | }
|
5 | |
6 | PointList Line::Intersect( Line* with ) |
7 | {
|
8 | ...
|
9 | }
|
10 | |
11 | PointList Line::Intersect( Circle* with ) |
12 | {
|
13 | ....
|
14 | }
|
15 | |
16 | PointList Line::Intersect( Rectangle* with ) |
17 | {
|
18 | ....
|
19 | }
|
20 | |
21 | ....
|
und das ganze dann noch mal für Circle und Rectangle in allen noch nicht behandelten Kombinationen. (Und vor allen Dingen zieht man sich in die Basisklasse das Wissen rein, welche abgeleiteteten Klassen es gibt). Das artet aus. Vor allen Dingen, wenn dann noch weitere Tpen dazukommen. Letzten Endes war eine map aus einem std::pair aus den Datentypen und einem Funktionspointer dann doch einfacher, die zur behandelnden Funktion führt. Zur Lufzeit wird der effektive Runtime Typ der beiden Objekte festgestellt und aus der map der entsprechende Funktionspointer geholt falls einer existiert. Arbeit ist das alles natürlich schon. Die jetzige Struktur ist auch nicht über Nacht gewachsen sondern nach und nach entstanden und wurde immer wieder verändert. Genau da wird OOP dann richtig schön: Man kann einzelne Teilsysteme recht leicht durch eine ganz andere Implementierung oder eine andere Strategie ersetzen, ohne dass gleich erst mal alles zusammenbricht. So eine Klassenhierarchie ist nicht in Stein gemeisselt und kann und darf verändert werden, wenn man in der laufenden Arbeit drauf kommt, dass man nur krampfhaft damit programmieren kann.
:
Bearbeitet durch User
Dussel schrieb: > 1: Wird jedes Bild (oder Frame) komplett neu gezeichnet? Wenn man beliebig viel Rechenpower verblasen darf für beliebig einfache Bildchen, kann man das machen. Hat man wenig Rechenleistung und will flimmern vermeiden, zeichnet man in eine Bitmap und kopiert dann komplett um. Weiss man, welcher Teilbereich betroffen ist, zeichnet man gar nur diese Regiom. > 2: Wer übernimmt das Zeichnen der Objekte in der 3D-Graphik? Häufig hat man eine Datenstruktur, die den Bildschirmaufbau beschreibt, ob nun 2d oder 3d. Da kann man die Funktionen, die die Daten ändern, schön trennen von der Funktion, die sie zeichnet. Funktionen, die ändern, tragen gleich die Änderungsregion ein, in der sich im Bild was geändert haben könnte. Normalerweise iteriert die durch die Elemente und zeichnet jedes wenn es im sichtbaren Bereich liegt "zeichne dich". Windows macht das sehr schön: Wenn sich was ändert (Menü schliesst sich und deckt damit mehrere Fenster mit Elementen auf) wird das zur Invalid-Region hinzugefügt, und dann, wenn alles erledigt ist, kommt ein PAINT das jedes darin befindliche Element und Fenster auffordert, sich selbst zu zeichnen. So vermeidet man die Probleme, die man mit fortlaufenden Operationen hat "muss ich jetzt schon neu zeichnen oder wird das sowieso gleich wieder verworfen".
Karl Heinz schrieb: > und das ganze dann noch mal für Circle und Rectangle in allen noch nicht > behandelten Kombinationen. Daher unterstützen schlauere Graphiksysteme Regionen, das sind Flächen bestehend aus Begrenzungen jeder Form, von Linie bis Kreisbogen. Dann werden zuerst alle Elemente zusammen in eine Region gefasst (Union), und dann die Schnittmenge gebildet.
Hier wurde ja jetzt viel geschrieben und ich habe mir noch nicht alles durchgelesen. Aber nur noch mal um es klarzustellen, beide Fragen bezogen sich auf die 3D-Programmierung. Das Beispiel mit den Rechtecken und Kreisen habe ich nur gebracht, weil ich da weiß, wie es geht und wissen wollte, wie das in 3D gemacht wird. Wenn man zum Beispiel etwas hinter der Kamera zeichnet, erkennen die Graphikbibliotheken das dann und zeichnen es gar nicht oder wird das gezeichnet und erst wenn die 3D-Szene auf den Bildschirm projiziert wird, wird das Objekt weggelassen? Ich weiß, das man im Allgemeinen mit der Angabe der Ecken Polygone im Raum zeichnen kann, aber ich weiß nicht, wie das dann intern umgesetzt wird, dass das 3D-Polygon 2D auf den Bildschirm projiziert wird. Deshalb auch die Frage.
3D Anwendungen funktionieren (oder funktionierten einmal) meistens nach folgendem schema: 1) Grafik/Physik/Sound library initialisieren ( opengl,opencl/physix,openal | directx,opencl/physix,directsound ) 2) Objekte laden, umfast folgendes: a) Laden von verteces und indices (Geometrie) b) Vorausberechnungen für umboxen, umshären, etc. c) Laden von Animationen (Keyframes, Skelett) d) Laden benötigter shader (Vertex-,Fragment-,Tesselation- shader, etc. Auch mehrere verschiedene davon.) e) Laden von Texturen (Color-,Shadow-,Light-,Bump-,Normal-Map) f) Sonstiges, opencl programme für physik, etc. 3) Erstellen Mehrerer threads oder einer Main loop für: 1) Rendering 2) Collision detection 3) Physik 4) Nachladen von daten, Speichern von daten, etc. 4) cleanup, alles wieder freigeben Das Rendering: Meistens wird Doublebuffering eingesetzt. Es wird der nicht sichtbare buffer bemahlt, und die Buffer dan ausgetauscht. Beim Rendering werden haufig mehrere Rendering passes durchlaufen, meistens für: 1) Zeichnen des Schattens in eine Textur und/oder den Stancil buffer 2) Generieren von Reflektionstexturen (kann häufig vermieden werden durch statische cube maps/shadow maps) 3) Rendern der Scene unter verwendung der Resourcen der Vorherigen rendering passes Vor einem Render pass werden normalerweise andere shader geladen und eventuel parameter wie die Model-/View-matrix geändert. Welche Objekte werden Gerendert? Die Geometrie von Objekte besteht aus Dreiecken, die aus je 3 Verteces (eckpunkte) bestehen. Alle komponenten des Vertex (Position,Farbe,etc.) können in unterschiedlichen buffern liegen, werden aber durch den selben Index referenziert. Mithilfe der Verteces des Objekts kann immer die Umbox, Umsphäre, etc. berechnen, und in der software manuell entscheiden welche Objekte gezeichnet werden sollen. Wann wird ein Dreiecke gezeichnet? Folgendes übernimmt die Graphik pipeline der graka oder die Grafics library: 1) Wenn mindestens ein Punkt des Dreiecks inerhalb der Clipping planes ist, wird es gezeichnet. Normalerweise gibt es eine Oben,Unten,Links,Rechts,Vorne und Hinten, sowie Benutzerdefinierte. 2) Wenn die Reihenfolge der verteces des Dreiecks korreckt ist. (front/back face culling) Wann werden die Fragmente (Bildpunkte) eines Dreiecks gezechnet? Folgendes übernimmt die Graphics library: 1) Wenn die Bildpunkte im Viewport liegen. 2) Wenn die z-koordinate des fragments einen höheren, bzw. kleineren wert als dass im depth buffer hat und dieser aktiviert wurde. 3) Wenn im Fragmentshader das Fragment nicht verworfen wurde. Worauf muss beim zeichnen im bezug auf Performance geachtet werden? 1) Möglichst wenige Aufrufe von Grafiklibraryfunktionen. Die sind langsam. 2) Daten einmal mit VBO auf grafigkarte, diese möglichst selten oder garnicht ändern und immer wieder verwenden. Animationen mittels Texturen und instancing realisieren, um die langsame Übertragung vieler Zeichenbefehle und neuer Indexvariabelverte zu Vermeiden. 3) Sichtbarkeitsberechnungen von Objekten zuerst ungefähr und nur bei bedarf genauer. Im zweifelsfall keine. 4) Paralelisierbare berechnungen auf graka (opencl/shader) auslagern. Das ist jetzt nur eine ungefäre unvolständige beschreibung. Gillt nicht für alle und nur für Rasterizer. Dinge wie Raytraceing sind eine andere geschichte. Es sollte nur einen überblick geben. Um die Ursprüngliche frage zu Beantworten, was denn nun neu gezeichnet wird: Normalerweise alles, wobei das der anwendung überlassen wird. 2D sachen über der 3D Scene werden mit Viewport und Stanciltest meistens anders behandelt, also seltener und nur die Geänderten Bereiche gezeichnet (ausser diese sind transparent, dann muss man sich zwischen neuzeichnen oder nur Änderungen nach textur/renderbuffer zeichnen entscheiden). Das Zeichnen macht die Grafigkarte mithilfe der Shader.
:
Bearbeitet durch User
Daniel A. schrieb: > ungefäre unvolständige beschreibung. Nun hast Du Deinen gesammten Vorrat an Rechtschreibfehlern verbraucht. Ich kann Dir aber noch ein paar abgeben, oben findest Du schon mal die Bezier-Kurve mit einem e zu viel am Ende.
mop schrieb: > Oder schöner: > > Foreach(r : rectangles) rectangleRenderer.render(r) Ach ja, und für alle Objektorientierer hab' ich noch das hier: http://www.bonkersworld.net/object-world/ ;-)
tictactoe schrieb: > Ach ja, und für alle Objektorientierer Ich hatte dazu kürzlich das hier gefunden: http://harmful.cat-v.org/software/OO_programming/ Der OO Hype ist wohl nicht mehr so groß, aber für grafische Elemente ist Objektorientierung wohl doch angemessen.
Ach was, gerade bei der 3D Programmierung ist da keine Gefahr. Wenn man es mit OO als Selbstzweck übertreibt, wird die Engine unbrauchbar träge. Wenn man die OO Daten-Methoden Kapselung nicht benutzt, wird es ein Gestrüpp, was sich nicht mehr debuggen lässt.
Salewski, Stefan schrieb: > http://harmful.cat-v.org/software/OO_programming/ LOL: '90% of the shit that is popular right now wants to rub its object-oriented nutsack all over my code” – kfx'
LOLer schrieb: > Salewski, Stefan schrieb: >> http://harmful.cat-v.org/software/OO_programming/ Oder der: " “The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” – Joe Armstrong" LOL
> and the entire jungle
Dieses Problem hat man in der 3D Grafik sowieso. Man kommt nur auf eine
brauchbare Geschwindigkeit, wenn die Module interne Daten anderer Module
weiterverwenden.
Es gibt eigentlich gar kein Rechteck.paint(). Die Informationen für
Kamera, Clipping, Sichtbarkeit, Dreiecksnetze, Beleuchtung... werden
durch das gesamte System durch gereicht.
Die Arbeit wird dann nicht dort gemacht, wo es selbstverständlich
erscheint. Durchaus üblich, ein Teil der Sichtbarkeitsprüfung wird im 3D
Modell gemacht, der andere Teil nach der Rasterung.
Bei animierter Grafik wird es dann noch schlimmer. So weit wie möglich
benutzt die Hauptschleife interne Informationen aus der Render-Pipeline.
MaWin schrieb: > Karl Heinz schrieb: >> und das ganze dann noch mal für Circle und Rectangle in allen noch nicht >> behandelten Kombinationen. > > Daher unterstützen schlauere Graphiksysteme Regionen, das sind Flächen > bestehend aus Begrenzungen jeder Form, von Linie bis Kreisbogen. > > Dann werden zuerst alle Elemente zusammen in eine Region gefasst > (Union), und dann die Schnittmenge gebildet. Ich bin im CAD tätig. Da helfen mir Regionen nicht viel. Denn ich hab Einzellinien, ich hab Kreisbögen, ich hab .... und ich muss mit denen auch geometrische Operationen machen. Ich komm also nicht umhin den genauen Typ des Elements zu kennen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.