Hallo Forum,
hmm.. ich glaube es ist passender hier zu posten als im "normalen" OpenGL Forum...(?)
Ich programmiere unter Linux in C++, benutze die Cg Runtime und habe eine GeForce4Ti, Treiber Version ist 8776.
Also vereinfacht gesagt ist es mein Ziel, eine Tube (also quasi einen Zylinder) per VBO an die Graka zu übergeben. In dem VBO habe ich die Koordinaten, die Farbe und die Normale für jeden Vertex gespeichert.
Anfangs haben je zwei aufeinander folgende Vertices die gleichen Koordinaten, aber von diesen je zwei Vertices hat einer den alpha Wert Null und der andere 1. Mein arbvp1 Vertex Shader erkennt das und schiebt den einen Vertex etwas nach "oben" und den anderen nach "unten". Alle aufeinander folgenden Vertices ergeben so einen Quad Strip. Das klappt so weit auch sehr gut (hoffe habe mich verständlich ausgedrückt).
Ein Detail (um Fragen zuvor zu kommen), das aber für eine Lösung meines Problems unwichtig sind: der Shader erhält als uniform Parameter die Position der Kamera. Außerdem dient die Normale eines Vertex als Parameter, der die Position des nächsten Vertex kodiert. So kann ich die Richtung berechnen, die nach "oben" zeigt:
"oben" = kreuzprodukt ( (kameraposition - vertexposition) , (normale - vertexposition) )
Dazu der Vertex Shader (Cg):
Code: struct VertexInput { float3 position : POSITION; float4 color : COLOR0; float3 next : NORMAL; }; struct VertexOutput { float4 position : POSITION; float4 color : COLOR0; float texCoord : TEXCOORD0; }; VertexOutput main( VertexInput IN, uniform float4x4 ModelViewProj, uniform float3 viewPos, uniform float radius ) { VertexOutput OUT; float3 up = normalize( cross( (viewPos - IN.position), (IN.next - IN.position) ) ); up *= radius; if (IN.color.a == 0) { OUT.position.xyz = IN.position - up; OUT.texCoord = 0; } else { OUT.position.xyz = IN.position + up; OUT.texCoord = 1; } OUT.position.w = 1; OUT.position = mul( ModelViewProj, OUT.position ); OUT.color.xzy = IN.color.xzy; OUT.color.a = 1; return OUT; }
So, damit nun der Eindruck eines 3dimensionalen Zylinders entsteht, möchte ich die Quads mit einer 1dimensionalen Luminance Map shaden, dafür kriegt der eine von diesen je zwei Vertices die Texturkoordinate Null und der andere 1. Die Luminance Map besteht aus unsigned bytes, bis zur Hälfte der Textur steigen die Werte von 0 bis 255, und ab der Hälfte sinken sie von 255 nach 0.
Dafür habe ich einen fp20 Fragment Shader geschrieben:
Code: struct FragmentInput { float4 color : COLOR0; float texCoord : TEXCOORD0; }; float4 main( FragmentInput IN, uniform sampler1D lumiMap ) : COLOR { float luminance = tex1D(lumiMap, IN.texCoord).r; float4 OUT; OUT.rgb = IN.color.rgb * luminance; OUT.a = 1; return OUT; }
Wenn ich den nun laufen lasse, bleibt die gesamte Szene schwarz.
Sorry wenn ich euch jetzt mit Fragen überhäufe, aber ich mach einfach mal ein kurzes Brainstorming....:
1. In einem anderen Post habe ich gelesen, dass man den Fragment Shader an den Vertex Shader "binden" muss? Das verstehe ich nicht. Die sind doch automatisch durch die Ein- und Ausgabesemantiken verbunden?
2. Muss ich mit glActiveTexture TextureUnits aktivieren? Hat zu keinen Ergebnissen geführt, außer dass dann Fehlermeldungen vom VBO kommen (glBindBufferARB(): invalid enumerant).
3. glEnable(GL_TEXTURE_1D), glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE), habe ich mit rumexperimentiert, hat aber nichts geändert.
4. Kann es sein, dass 2. und 3. nur gemacht werden muss, wenn ich keinen eigenen Frag. Shader benutze? Das habe ich auch versucht, dann bleibt die Szene zwar nicht schwarz, aber der ganze Quad Strip ist dann flat geshadet in den Farben die im VBO übergeben werden (also nix von wegen Luminance Map funktioniert)
5. Ich kann mich erinnern, dass ich mal gelesen habe, dass im fp20 (= texture_shader + register_combiner) nur Texturkoordinaten genutzt werden können, die an den Frag. Shader übergeben wurden und nicht solche, die dort online generiert wurden. Es müsste aber doch trotzdem erlaubt sein, die Text.koordinaten im Vertex Shader zu generieren? Muss ja eigentlich.... aber ich weiß einfach nicht mehr weiter.....
Wichtig noch: Es ist nicht mein Ziel, einen eigenen Shader zu benutzen, eigentlich sogar im Gegenteil, ich würde das lieber durch OpenGL machen lassen damit es auf möglichst vielen Systemen läuft. Hauptsache, es funktioniert überhaupt.
Bitte fragt mich, wenn ich irgendwas nicht gut erklärt habe oder Infos fehlen! Ich bin für jede Hilfe dankbar!
So, Grüße und vielen Dank schon mal wenigstens fürs Lesen dieses langen Posts.....
|