Umstellung auf OpenGL 3.2
-
Hui, fast fertig. Ich hab die letzten Tage meine Anwendung auf OpenGL 3.2 Core Context umgestellt.
Und ich muss sagen, ich bin begeistert. VBO sind etwas anders als in 2.0 aber im Prinzip das gleiche. Und seit ich Shader jetzt besser verstehe und wie man sie verwendet ( um das Thema habe ich mich lange gedrückt ), bin ich ein Fan davon :D.
Nur, ist das wirklich so "einfach" oder habe ich grade Glück dass das bei mir funzt?
Als Beispiel Alpha Blending:// Fragment Shader: #version 150 uniform sampler2D NL_TextureID; smooth in vec4 theColor; smooth in vec2 theTextureCoord; out vec4 outputColor; void main() { vec4 value = texture2D(NL_TextureID, theTextureCoord); if ( value.a <= 0.01 ) discard; outputColor = value; } // Vertex Shader: #version 150 layout (location = 0) in vec4 vertex; layout (location = 1) in vec4 color; layout (location = 2) in vec2 texture_coord; uniform mat4 NL_ProjectionMatrix; uniform mat4 NL_ModelView; smooth out vec4 theColor; smooth out vec2 theTextureCoord; void main() { gl_Position = NL_ProjectionMatrix * NL_ModelView * vertex; theColor = color; theTextureCoord = texture_coord; }
http://img151.imageshack.us/img151/9924/alpharv.jpg
Das schaut gut aus und ist scheinbar sehr präzise. Normal ist das Bild ja nur 64x64 und drumrum alles weiss.
Ich bin nur erstaunt weil ich das alles aus dem Material gelernt habe was ich gelesen habe und scheinbar sogar was verstanden habe lol.
Ich weiss, das ist nix weltbewegendes und ihr studierten könnt euch bestimmt auf Anhieb 10 versch. Phong Shader mit dutzenden Effekten ausm Gedächtnis tippen, aber für mich Hobbyist ist das ein guter Anfang :).Als Referenz für andere lass ich mal noch nen Link hier:
http://www.arcsynthesis.org/gltut/
Das Tutorial hat mir viel weitergeholfen.
Hattet Ihr schon Erfahrungen mit 3.2 Core?Desweitere habe ich noch eine techische Frage:
Ich setze ja die orthographisce Matrix im Shader mittels NL_ProjectionMatrix. Diese muss ich ja nur 1x beim Shader laden setzen. Die Position NL_ModelView muss ich allerdings immer dann setzen, wenn sich das Objekt bewegt.
Da ich hier ein Spiel habe, in dem sich viele Objekte ständig bewegen, sind pro Frame immer wieder die gleichen Calls auf ein kleines Stück VSpeicher. Ich würde aber lieber große Chunks rendern.
Ja, ich weiss bei einem kleinen Spiel wie meinem macht das kaum nen Unterschied, aber ich möchte einfach lernen wie man sowas optimieren kann. Weil jedes Schiff braucht ja eigene Positions-Daten.Danke :).
-
Naja, niemand zwingt dich eine ModelView Matrix zu verwenden. Da du ja offenbar einfach einen Haufen Sprites hast und die wohl alle den gleichen Shader verwenden sollte es kein großes Problem sein die alle in einem dynamischen Vertexbuffer zu batchen oder überhaupt Instancing zu verwenden, wobei der Unterschied in den übertragenen Datenmengen vermutlich nicht allzu groß sein dürfte. Dazu das ganze noch so gebaut dass möglichst viele Sprites sich eine Textur teilen (Tilesets) und fertig ist der High Performance Sprite Renderer. Aber wenn du weniger als, sagen wir, 1000 Sprites hast ist es wohl sowieso praktisch egal wie du die renderst^^
-
Mit HW Instancing kannst du viele Instanzen eines Objekts in einem Drawcall rendern. Große Performancesprünge würde ich aber nicht erwarten.
Oh, nur als Anmerkung: Was du machst ist kein Alpha-Blending, sondern Alpha-Test. Alpha-Blending wird nach dem Fragment Shader ausgeführt (in DX nennt man es die Output Merger Stage).
-
Danke für eure Antworten.
Hmm, instancing habe ich schonmal bei DirectX gelesen, mich aber nie damit beschäftigt. Mal schauen was man darüber so findet.
Und ja, isn Alpha-Test :). Trotzdem bin ich angenehm überrascht wie elegant das geht.
@DoT
Also lieber die Vertex Daten manipulieren statt die Matrx und dann das ganze wieder in VRAM schieben?
Nen Tileset sollte jetzt nicht so das große Problem sein.Und ja, ich habe hier nur maximal 20-30 Sprites gleichzeitig momentan, will das ganze aber trotzdem so gut wie möglich implementieren.
-
wenn es wenige vertices sind, z.b. 4 pro sprite, dann lieber den buffer befuellen und alles am stueck rendern, weil sonst der drawcall an sich das teuerste ist. so ab 50vertices lohnt sich instancing wuerde ich sagen und ab 1000 sollte instancing und drawcalls sich nichts nehmen, meiner erfahrung nach.
-
Scorcher24 schrieb:
Also lieber die Vertex Daten manipulieren statt die Matrx und dann das ganze wieder in VRAM schieben?
Jop.
Die Idee von Instancing ist dass du im Prinzip zwei VBOs hast. In einem befindet sich nur dein Quad (Model). Und im andren die Daten von jedem Sprite (jeder Instanz des Models), also z.B. Position, Scale + Offset der Texturkoordinaten, etc.
Dann sagst du der Grafikkarte du willst das Model aus dem einen VBO x Mal rendern und dabei jedesmal eine neue Instanz aus dem anderen VBO verwenden und im VertexShader baust du alles zusammen. So kannst du mit minimalem Datenstransfer und minimaler Anzahl an Drawcalls operieren.Aber wenn du nur < 500 Sprites hast ist das wie gesagt sowieso komplett egal und da die 4 vertices von jedem Sprite wohl nur unwesentlich mehr Speicher brauchen als die Instanzdaten brauchen würden wird da mit Instancing vermutlich auch nicht so viel zu holen sein. Darum würd ich die Sprites einfach in ein dynamisches VBO batchen und fertig.