Forum | | | | - Seite 1 - |
| Sven Bader | Hallo,
OpenGL in XProfan macht richtig Spaß, mit einer Sache bin ich aber noch nicht ganz zufrieden. Ich hätte gerne glatte Kanten (Antialisasing). Was man so im Netz findet sind die Anleitungen eigentlich immer gleich und gut in XProfan nachzustellen, leider wird auch zwischen den Polygonen, die eigentlich zusammengehören geglättet - das führt zu Löchern Ich habe schon probiert, mit StartList/Endlist/Drawlist Dinge zu gruppieren, auch habe ich testweise große Teile des Codes mit API Aufrufen ersetzt.
Vielleicht passiert im Init-Befehl etwas, dass sich nicht damit verträgt?
Hat sich von euch schonmal jemand mit dem Thema befasst? Ich fände es auch für Spiele mit einfacher Grafik recht wichitg, es gehört irgendwie dazu.
Viele Grüße Sven
Im wesentlichen ist das der Code, der den Objekten vorangestellt werden muss:
Ein lauffähiges Komplettbeispiel ist hier, mit Leertaste lässt sich die Glättung an und ausschalten:
'$H OpenGL.ph
Def &GL_POLYGON_SMOOTH $B41;
Def &GL_NICEST $1102;
Def &GL_ONE_MINUS_SRC_ALPHA $303;
Def &GL_SRC_ALPHA $302;
Def &GL_POLYGON_SMOOTH_HINT $C53;
Def &GL_ONE 1;
Def &GL_BLEND 3042;
proc DrawGLScene
oGL("Clear")
oGL("Color", 1,1,1,1)
if (aa% = 1)
oGL("glBlendFunc",&GL_SRC_ALPHA, &GL_ONE_MINUS_SRC_ALPHA)
oGL("glEnable", &GL_BLEND)
oGL("glEnable", &GL_POLYGON_SMOOTH);
oGL("glHint", &GL_POLYGON_SMOOTH_HINT, &GL_NICEST);
else
oGL("glDisable",&GL_POLYGON_SMOOTH)
oGL("glDisable", &GL_BLEND)
oGL("glBlendFunc",&GL_ONE, &GL_ONE)
endif
oGL("Origin", 0, 0, -4.0)
oGL("Rotate", 0, 0, 22.5)
oGL("Origin", -1.0, 0, -4.0)
oGL("Quad", 2, 2)
oGL("Origin", 1.0, 0, -4.0)
oGL("sphere", 1,20,20)
oGL("Show")
endproc
declare ende%, aa%
window 600,400
oGL("Init", %hWnd, 0.5, 0.5, 0.5, 0)
oGL("PosMode", 1)
aa% = 1
DrawGLScene()
ende% = 0
WhileNot ende%
WaitInput
if (%key = 32)
sleep 200
aa% = abs(aa% - 1)
elseif (%key = 27)
ende% = 1
endif
DrawGLScene()
EndWhile
oGL("Done")
end
Antialiasing AN, die Ränder sind ok, aber alle Schnittkanten haben Löcher
Standardzustand Antialiasing AUS, Schnittkanten ok, aber keine Glättung
Hack: Anti Aliasing per Grafiktreiber erzwungen, so sollte es aussehen
|
| | | | |
| | « Dieser Beitrag wurde als Lösung gekennzeichnet. » | | Sven Bader | Für meine Zwecke habe ich eine Lösung, die leider in jedem etwas komplexerem Umfeld scheitern wird.
Ich lege auf das ungeglättete Objekt ....
... das mit den glatten Kanten ...
... das Ergebnis ist wie gewüsncht
Zum einen ist es falsch und unperformant das ganze Objekt noch einmal zu zeichnen, zum anderen kann diese Methode zu anderen Problemen führen wenn das Objekt keine "culled faces" also unsichtbare Rückseiten hätte oder man je nach Beschaffenheit des Objekts Teile von sich selbst durch die Löcher sieht. Auch Kombination mit transparenten Objekten sorgt bei dieser Lösung für Durcheinander.
Interessant zu sehen ist, dass das Originalobjekt etwas kleiner ist und die Glättung außen dazu kommt - da fragt man sich, wie es überhaupt zu den Löchern im Innenbereich kommt ...
Eine Interessante Variante ist angwendetes Smoothing aber mit deaktiviertem Blending, so bekommt man das "größere" Objekt, aber das nur am Rande.
Liegt die Lösung einfach nur in der richtigen glBlendFunc(), welche letztendlich das tut, was ich mit zwei identischen Objekten nachbilde oder kann es etwas mit Buffern oder oGL Grundeinstellungen zu tun haben?
Hier der neue Code
$H OpenGL.ph
proc DrawGLScene
oGL("Clear")
oGL("Color", 1,1,1,1)
if (aa%)
oGL("glDisable", ~GL_BLEND)
oGL("glDisable", ~GL_POLYGON_SMOOTH)
'Objekt mit harten Kanten
oGL("Push")
oGL("Rotate", 0, 0, 22.5)
oGL("Origin", -1.0, 0, -4.0)
oGL("Quad", 2, 2)
oGL("Origin", 1.0, 0, -4.0)
oGL("sphere", 1,30,30)
oGL("Pop")
oGL("glBlendFunc",~GL_SRC_ALPHA, ~GL_ONE_MINUS_SRC_ALPHA)
oGL("glEnable", ~GL_POLYGON_SMOOTH)
oGL("glEnable", ~GL_BLEND)
'Gleiches Objekt geglätten darüber
oGL("Push")
oGL("Rotate", 0, 0, 22.5)
oGL("Origin", -1.0, 0, -4.0)
oGL("Quad", 2, 2)
oGL("Origin", 1.0, 0, -4.0)
oGL("sphere", 1,30,30)
oGL("Pop")
else
oGL("glDisable", ~GL_BLEND)
oGL("glDisable", ~GL_POLYGON_SMOOTH)
oGL("Push")
oGL("Rotate", 0, 0, 22.5)
oGL("Origin", -1.0, 0, -4.0)
oGL("Quad", 2, 2)
oGL("Origin", 1.0, 0, -4.0)
oGL("sphere", 1,30,30)
oGL("Pop")
endif
oGL("Show")
endproc
declare ende%, aa%
window 600,400
oGL("Init", %hWnd, 0.5, 0.5, 0.5, 0)
oGL("PosMode", 1)
oGL("glHint", ~GL_POLYGON_SMOOTH_HINT, ~GL_NICEST);
ende% = 0
aa% = 1
DrawGLScene()
WhileNot ende%
WaitInput
if (%key = 32)
sleep 200
aa% = abs(aa% - 1)
elseif (%key = 27)
ende% = 1
endif
DrawGLScene()
EndWhile
oGL("Done")
end
|
| | | | | |
| | Sven Bader | Ich habe den Beitrag als gelöst deklariert obwohl es keine perfekte Lösung gibt.
Es ist wohl einfach so, dass die ursprüngliche Möglichkeit über GL_POLYGON_SMOOTH von heutigen Grafiktreibern nicht mehr korrekt behandelt wird und man auf zeitgemäßere (und komplexe) Technologien zurückgreifen sollte. Eine Lösungsansatz mit oldschool OpenGL wäre noch das mehrfache leicht versetzte Rendern in den Accumulation Buffer (glAccum), den habe ich auch schon erfolgreich für Motion Blur verwendet. |
| | | | |
|
AntwortenThemenoptionen | 2.638 Betrachtungen |
ThemeninformationenDieses Thema hat 1 Teilnehmer: |