Ich habe ein kleines Programm geschrieben, welches 3D-Daten mit OpenGL rendert. Die aktuelle Mauspostion rechne ich mit gluUnProject in Weltkoordinaten um. Mittels Point and Click soll eine Linie auf das Objekt gezeichnet werden. Ich speichere dabei bei jedem Klick die Weltkoordinaten und render nachher das 3D-Objekt und die Linie.
Das klappt alles vom Prinzip her. Aber man kann die Linien nicht wirklich in der Renderausgabe erkennen.
Das Objekt kann nun wahlweise mit oder ohne Wireframe angezeigt werden. Damit der Wireframe über der Fläche zu sehen ist, benutzte ich GL_POLYGON_OFFSET_FILL. Ich habe nun die Idee gehabt, die Linien auch mit der selben Funktion sichtbar zu machen. Dabei gibt es leider einige Probleme.
Wenn ich GL_POLYGON_OFFSET_FILL aktiviere und in der gerenderten Scene die Mauskoordinaten in Weltkoordinaten umrechne, liegen die berechneten Koordinaten immer hinter der Fläche. Wenn ich Beispielsweise ein glPolygonOffset(100, 100) einstelle, dann liegen die berechneten Weltkoordinaten sehr viel weiter hinten, als die eigentliche Fläche.
Wie schaffe ich es nun die Mausposition trotz eingeschalteten GL_POLYGON_OFFSET_FILL korrekt zu bestimmen? Und ist es vielleicht möglich für den Wireframe und die Linie ein unterschiedlichen Wert für glPolygonOffset einzustellen? (Bis jetzt rendere ich das Objekt mit einstellten glPolygonOffset und dann den Wireframe und die Linie)
Jetzt will ich aber die Linien auch mit GL_POLYGON_OFFSET_LINE rendern. Aber anscheinend hat GL_POLYGON_OFFSET_LINE keinen Einfluss auf reine Linien, sonder nur Outlines von Polygonen.
While polygon offset can alter the depth value of filled primitives in point and line mode, under no circumstances will polygon offset affect the depth values of GL_POINTS, GL_LINES, GL_LINE_STRIP, or GL_LINE_LOOP primitives. If you are trying to render point or line primitives over filled primitives, use polygon offset to push the filled primitives back. (It can't be used to pull the point and line primitives forward.)
Aber wie kriege ich denn nun die richtigen Weltkoordinaten, wenn ich die gefüllten Polygone nach hinten schiebe?
Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Hey, spricht etwas dagegen, einfach den DepthTest vor dem Rendern der Linie zu deaktivieren? Oder könnte es sein, dass schon etwas vor der Linie liegt?
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 21:14, insgesamt 1-mal geändert.
Das mit dem Rendern ohne Offset hatte ich auch bereits bedacht, nur habe ich gehofft irgendwie drum rum zu kommen. Ich habe es jetzt so implementiert und es funktioniert. Jetzt habe ich allerdings keine Möglichkeit, dass ich den Offset für die Linien unabhängig zum Wireframe ändern. Ich würde eigentlich ganz gerne den Offset für die Linien noch erhöhen. Dazu passend hätte ich jetzt noch eine Frage: Wie kann ich dieses eine Mal Rendern ohne Offset für jede Koordinatenabfrage ohne Bildschirmausgabe hingekommen?
Und ich habe noch ein weiteres Problem: Die Linien werden sauber gezeichnet, aber sobald ich mit der "Kamera" näher ran gehe, verschwinden die Linien in der Fläche. Dabei hab ich beim Offset schon (4,4) eingetragen.
Das mit dem dem Deaktivieren des Depth-Tests habe ich auch schon probiert. Das Objekt lässt sich allerdings in alle Richtungen drehen, sodass das wirklich etwas komisch aussieht. Aber das wäre echt die einfachtste Variante.
Jetzt habe ich noch zwei Problemchen. Und zwar, dass ich immer noch keinen Offset separat für Wireframe und Linien einstellen kann. Wenn ich mich jetzt damit abfinde, dass der Offset für Wireframe und Linien gleich ist, dann habe ich nämlich Probleme mit den Linien. Die Linien werden prinzipiell so wie ich es haben möchte dargestellt. Die Linien ragen an vielen Stellen ein wenig in die Oberfläche hinein. Durch der Offset werden sie aber trotzdem vor dem Objekt dargestellt. Wenn ich jetzt aber die "Kamera" nahe an das Objekt bringe, dann ragen immer mehr Linien in das Objekt hinein. Der Offset scheint also nicht die Nähe zum Objekt zu berücksichtigen. Kann ich das irgendwie was tricksen?
Ok, also das mit dem verschiedenen Offsets scheint ja nicht wirklich ohne Weiteres möglich zu sein. Um die Linien sichtbar zu machen, kann man aber jetzt einfach das Objekt halbtransparent machen. Dabei habe ich folgendes Problem. Das Rendern sieht folgendermaßen aus
Also Reihenfolge: Objekt, Wireframe, Linien Das Ganze funktioniert auch, außer wenn ich das Objekt halbdurchsichtig mache. Dann sieht man nämlich die Linien nicht durch das Objekt, so wie ich mir das vorgestellt habe. Kann es sein, dass die DisplayList da Probleme macht und sich nicht mit dem direkten Rendern verträgt?
Probiert habe ich auch die Reihenfolge: Linien, Objekt, Wireframe Jetzt kann man die Linien durch das Objekt sehen. Allerdings ist bei aktiviertem GL_LINE_SMOOTH die Linie blau und nicht schwarz. Und man sieht um die Linie auch stellenweise einen weißen Rand. Ist das auf ein Fehler beim Blending oder so zurückzuführen?
Also wie schaffe ich es, dass man die Linien durch das Objekt sieht und gleichzeitig GL_LINE_SMOOTH funktioniert?
Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
vielleicht kannst du mal paar screenshots machen, ich glaube man kann sich nur sehr wage vorstellen, was du genau haben willst. weiter oben hat jemand glaube schon empfohlen den depth test für die linien einfach auszuschalten, hattest du das mal probiert?
Ich hab mal ein paar Screenshots gemacht: Bei aktiviertem GL_LINE_SMOOTH ist die Linienfarbe blau. Von der Seite sieht man auch die weißen Ränder um die Linie. Bei deaktiviertem GL_LINE_SMOOTH ist alles ok. Wenn GL_LINE_SMOOTH aktiviert ist, verschwinden die Artefakte mit zunehmender Transparenz des Objektes.
Dateianhang:
opengl.jpg
Und wie gesagt: Wenn ich die Linien nach dem Objekt render, dann klappt das mit dem GL_LINE_SMOOTH. Allerdings kann man bei einem halbtransparenten Objekt die Linien nicht mehr sehen, wenn sich diese hinter dem Objekt befinden.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Also Alternative zu den GL_LINE_SMOOTH könnte ich natürlich auch Multisampling benutzen. Ich habe meiner Form wie in viewtopic.php?p=45167#45167 einen Renderingcontext vergeben. Das klappt auch soweit. Ich habe noch eine Funktion implementiert um das Multisampling ein und auszuschalten. Allerdings funktioniert das nur vernünftig, wenn ich die Anwendung neu starte. Dann man nicht im laufenden Betrieb das Multisampling wechseln?
Die Funktion zu wechseln sieht so aus:
Code:
DeactivateRenderingContext; DestroyRenderingContext(RC); ReleaseDC(Handle, DC); if AA then SetPixelFormat(DC,PFAA,nil) else SetPixelFormat(DC,PF,nil); RC := wglCreateContext(DC); ActivateRenderingContext(DC,RC);
wobei PF das Pixelformat ohne und PFAA das Pixelformat mit Multisampling ist. Aber so ganz funktioniert das nicht. Habe es auch schon mit Form.DestroyWnd und Form.CreateWnd, aber damit verschwindet auch meine Form. Weiß jemand Rat?
Ok, das mit dem Multisampling habe ich hinbekommen. Für Alle, die es interessiert: Einfach den alten Context löschen, dann RecreateWnd (um ein neues Handle zu bekommen, anders scheint es nicht zu gehen) und dann einen neuen Context setzten. Zwar verschwindet das Fenster dann kurz, aber ist nicht so schlimm.
Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.