Q3 BSP - Transparente Flächen
-
Hey,
ich schreibe gerade in Java einen Loader für Quake 3 .bsp Karten. Ich bin jetzt eigentlich schon relativ weit, aber habe ein Problem mit transparenten Flächen wie Lichtkegel bzw generell Lichter.
Erstmal zwei Bilder:
- So sieht's in Quake 3 Arena aus: http://bloody-blades.de/images/transparencyQuake3.jpg
- So sieht's bei mir im Loader aus wenn man einfach die Textur draufklatscht: http://bloody-blades.de/images/transparencyLoader.jpg
(-> Lichtkegel oben, Totenkopf links, Flagge links oben, Kabel oben)
Meine Frage jetzt: Wie hat man's bei Quake gelöst?
Der Quake 3 Source ist zwar veröffentlicht, aber nur teilweise anscheinend, weil ich partout nichts bezüglich MapRendering im Code finde. (http://www.idsoftware.com/business/techdownloads/)Ich schätze mal, dass die Texturen geblendet werden, aber wie am besten?
Irgendwas habe ich noch im Kopf von wegen zuerst alle transparenten Objekte ohne Tiefentest mit Blending zeichnen und danach mit Tiefentest die "normalen" Objekte.
Weiß jemand mehr darüber?
Vielen lieben Dank,
Tim
-
Hi!
Du hast das Material System von Quake3 anscheinend noch nicht verstanden.
Jedes Face hat ein Material, dies ist nicht der Name und Pfad zur Textur, wie oft angenommen, sondern der Name des Materials.
Die Materialien sind definiert in Scriptdateien und enthalten alle Informationen über Blending, Texturemaps, Animation usw...
Diese Materialscripte musst du Parsen und hinterlegst die Materialien in einem Manager. Dann kannst du beim Rendern ganze leicht das gewünschte Material auswählen und hast alle Informationen wie du deine Renderstates setzen musst.Informationen zu diesen Shadern gibts hier: http://www.qeradiant.com/manual/Q3AShader_Manual/index.htm
Ich hab vor Zeiten ebenfalls mals so ein Loader geschrieben, da hat das super geklappt:
http://bl4ckd0g.bl.funpic.de/projects/images/q3bsp007.jpg
http://bl4ckd0g.bl.funpic.de/projects/images/q3bsp008.jpg
http://bl4ckd0g.bl.funpic.de/projects/images/q3bsp009.jpgIch hab damals die Softwareshader komplett implementiert, mit allen Features wie Rotation, Translation, Skaling, Vertexlighting, blablabla

P.S.: Achja, hab nochmal in den Quake3 Sourcecode geschaut. Die wichtigen Dateien sind tr_backend.c, tr_bsp.c, tr_shade.c, tr_shade_calc.c und tr_shader.c
grüße
-
Okay, hab vielen Dank.
Das ist sehr hilfreich.
Eine Frage habe ich noch:
Shaderbeispieltextures/gothic_block/blocks17bloody { { map textures/liquids/proto_grueldark2.tga blendFunc GL_ONE GL_ZERO tcmod scale 2 2 tcMod scroll .01 .03 tcMod turb 0 0.05 0 .05 } { map textures/effects/tinfx3.tga blendFunc GL_ONE GL_ONE tcGen environment } { map textures/gothic_block/blocks17bloody.tga blendFunc blend rgbGen identity } { map $lightmap blendFunc filter rgbGen identity } }Da werden 4 TextureMaps angegeben. Bedeutet das jetzt, dass alle vier zusammen mit Multitexturing gebunden werden beim Rendern?
:edit2:
Hahar nein, man muss das Objekt in dem Beispiel 4 mal rendern, nicht wahr?:edit:
Achja genau, und wie sieht es aus mit der Rendereihenfolge? Kann ich einfach die Liste der Faces durchgehen und jedes mit entsprechenden Settings zeichen oder muss ich sie beim Laden entsprechend umsortieren?Vielen Dank
-
Hi!
Du musst das Face natürlich nicht vier mal Rendern. Du kannst Multitexturing verwenden.
Und die Faces müssen vor dem Rendern sortiert werden! Sonst gibts ganz unschöne Fehler bei der Darstellung.grüße
-
David_pb schrieb:
Du musst das Face natürlich nicht vier mal Rendern. Du kannst Multitexturing verwenden.
Okay gut.
David_pb schrieb:
Und die Faces müssen vor dem Rendern sortiert werden! Sonst gibts ganz unschöne Fehler bei der Darstellung.
Hast du darüber mehr Infos wie sie sortiert werden müssen?
Vielen Dank
-
Hi!
Jeder Shader bekommt eine Nummer die beim sortieren hilft.
Aus dem Quake3 Sourcecode:tr_local.h
typedef enum { SS_BAD, SS_PORTAL, // mirrors, portals, viewscreens SS_ENVIRONMENT, // sky box SS_OPAQUE, // opaque SS_DECAL, // scorch marks, etc. SS_SEE_THROUGH, // ladders, grates, grills that may have small blended edges // in addition to alpha test SS_BANNER, SS_FOG, SS_UNDERWATER, // for items that should be drawn in front of the water plane SS_BLEND0, // regular transparency and filters SS_BLEND1, // generally only used for additive type effects SS_BLEND2, SS_BLEND3, SS_BLEND6, SS_STENCIL_SHADOW, SS_ALMOST_NEAREST, // gun smoke puffs SS_NEAREST // blood blobs } shaderSort_t;Die Faces werden nach größe sortiert. Die jeweilige Nummer steht in den Shader Scripten.
So, hoffe das reicht als Anhaltspunkt!grüße
-
Okay, erstmal: Wo hast du den Quake 3 Sourcecode runtergeladen? Wenn ich mir bei id den Q3A 1.27g Game Source runterlade, habe ich nichts dergleichen. Die genannte Datei tr_local.h gibts bei mir nicht; es gibt generell überhaupt nichts, was irgendwie mit Rendering, Netzwerk oder Sound zu tun hat.
Ich versteh jetzt aber auch nicht ganz was du mit Nummer in den Shaderscripten meinst. Dort gibt es keine derartige Nummer....
Tut mir leid, wenn ich mich zu doof anstelle

Danke
-
Hi!
Doch, manche Shader haben einen Wert der mit "sort" definiert ist. Alle anderen haben einen Standardsortierungswert, welcher das ist weiß ich gerade nicht aus dem Kopf.
Der Gamesource bringt dir nichts, du brauchst den vollständigen. Da is alles mit bei, Renderer usw...
Wobei ich damals das Projekt geschrieben habe als es den Quellcode noch nicht gab. Es ist also auch ohne "spicken" möglich!
grüße
-
David_pb schrieb:
Doch, manche Shader haben einen Wert der mit "sort" definiert ist. Alle anderen haben einen Standardsortierungswert, welcher das ist weiß ich gerade nicht aus dem Kopf.
Naja, würdest du vielleicht eventuell nachgucken oder mir sagen, wo ichs finde?
David_pb schrieb:
Wobei ich damals das Projekt geschrieben habe als es den Quellcode noch nicht gab. Es ist also auch ohne "spicken" möglich!

Ich will ja nicht die Logik abschreiben, sondern es geht mir einfach um so Dinge wie oben, wo ich zum Beispiel den Default nicht weiß.
:edit:
ah cool, hab den Source gefunden, glaub ich
-
Okay habs grad zufällig beim Lesen gefunden....
The default behavior is to put all blended shaders in sort "additive" and all other shaders in sort "opaque" [...]
-
Na also!

-
Ich habe gerade gemerkt, dass in den Shadern nur tga's angegeben werden als map.
Und zum Beispiel auf q3dm1 verlangt er "textures/gothic_block/blocks18c_3", gibts jedoch nicht als Shader, liegt aber als jpg vor.
Muss ich das jetzt so interpretieren, dass man zuerst überprüft, ob ein Shader vorliegt und wenn nicht, versucht man das jpg mit dem Namen zu laden?
Danke
-
Hi!
Genau. Zuerst suchst du obs einen Shader gibt und dann suchst du die jeweilige Textur. Das in Shadern nur Tgas verwendet werden und sonst jpegs kann ich nicht bestätigen. Da würd ich einfach alle Möglichkeiten abchecken.
grüße
-
Hey, sag mal, woher hast du eigentlich deine ganzen Informationen über das Rendering und so?
Nur aus den Shader Manuals wie http://www.heppler.com/shader/ ?
Ich hänge gerade ein wenig beim Multitexturing. Momentan sieht es bei mir so aus:
http://bloody-blades.de/images/uhm_naja.jpg
Hab das Zeichnen von MeshFaces und Patches mal rausgeworfen, sind im Moment also nur die Polygonfaces. Die rötlichen Texturen sind Shader.
Ich hab mir die Stellen im Spiel angesehen und festgestellt, dass z.B. über der Tür der Türrahmen über die Flamme gezeichnet wird, aber bei mir werden die Texturen halt schön zusammengemischt.
Woher wusstest du wie das zum Beispiel genau funktioniert?Ich möcht ja echt nicht fragen, aber würdest du mir eventuell vielleicht mal deinen Loader zeigen/geben?

Ich plag mich schon länger damit rum, als ich ursprünglich vorhatte. Es ist fürn Spiel und es gibt noch genug andere Dinge, um die ich mich kümmern muss. Aber ich bin schon so weit, da will ich nicht aufgeben.
Wäre cool; ich will auch nicht (alles :P) abschreiben, hauptsächlich Anregungen bekommen.Vielen Dank
:edit:
Kannst mich ja vielleicht mal kontaktieren unter
ICQ: 343987149
email: xindon (at) gmail (dot) com
-
Hi!
Grundsätzlich renderst du die Layer in der Reihenfolge wie sie geladen wurden. Also:
Layer *l; for ( int pass = 0; pass < currShader->numLayers; ++pass ) { // ... glActiveTextureARB( GL_TEXTURE0_ARB ); glClientActiveTextureARB( GL_TEXTURE0_ARB ); glEnable( GL_TEXTURE_2D ); l = currShader->layer[ pass ]; SetTextureCoordinates( l ); BindTexture( l ) SetState( l ) // usw usw... if ( l->m_nFlags & LF_MULTITEX ) { glActiveTextureARB( GL_TEXTURE1_ARB ); glClientActiveTextureARB( GL_TEXTURE1_ARB ); glEnable( GL_TEXTURE_2D ); // Texture Koordinaten, Bind Texture, Set State glDrawElements( ... ) } else { glDrawElements( ... ) } // ... }Mehr steckt nicht dahinter. Was du aber bedenken musst ist zuvor die Vertices und Texturkoodinaten zu transformieren! Sonst siehst du die ganzen schönen Effekte nicht!

grüße
-
Okay das Prinzip hab ich (grob) ja auch verstanden, aber naja, siehst ja wie's auf dem Screen ausschaut

Also noch eine Verständnisfrage zu deinem Code:
Du gehst jedes Face auf der Karte durch, testest, ob es sichtbar ist.
Wenn sichtbar, geht man jede Shaderstage des Faceshaders durch.Und jetzt: Du aktivierst für jede Stage am Anfang Texture 0 aus und zeichnest damit.
Wenn Multitexturing an ist, bindest du Texture 1 (für die selbe Stage) und zeichnest was anderes damit.
Aber was denn?Ich hab das jetzt so gedacht, dass wenn der Shader z.B. 2 Stages hat, aktiviert man für die erste Stage Texture 0 und für die zweite Stage Texture 1. Bei drei Stages nimmt man für die dritte eben Texture 2. Stimmt das so also nicht?
Dein Code ist en bisschen unvollständig

Trotzdem danke
-
Hi!
Das is ja mehr oder weniger Pseudocode. Nunja, das Prinzip hast du genau richtig verstanden.
Multitexturing kannst du auch ganz weg lassen, dann renderst du aber ggf doppelt so oft.Natürlich Binde ich nicht zweimal den gleichen Texturlayer, sondern den jeweils nächsten.
grüße
-
Okay gut, also hab ich ja eigentlich verstanden was ich machen muss, vielen Dank

Hab jetzt nur noch anscheinend ein rein OpenGL-technisches Problem:
Erstmal zwei Bilder:
q3dm1 - Quake 3
http://bloody-blades.de/images/quake3_door.jpgq3dm1 - mein Loader
http://bloody-blades.de/images/loader_door.jpgMan sieht den Türbogen (Patch) und die Fackeln (MeshFaces) nicht, weil ich momentan nur die Polygonfaces rendere wie schon erwähnt, wegen der Shaderumstellung.
Der Shader zu der Tür sieht so aus:
textures/gothic_door/skullarch_b { { map textures/sfx/firegorre.tga tcmod scroll 0 1 tcMod turb 0 .25 0 5.6 tcmod scale 1.5 1.5 blendFunc GL_ONE GL_ZERO rgbGen identity } { map textures/gothic_door/skullarch_b.tga blendFunc blend rgbGen identity } { map $lightmap blendFunc filter gbGen identity } }Muss jetzt noch etwas anderes Opengl-technisches machen als die genannten Renderstates entsprechend zu setzen?
Der Code für die Tür würde doch dann so aussehen:// Stage 1 1) Texturkoordinaten verändern / berechnen 2) MultitextUnit 0 aktivieren/wählen 3) glEnable(GL_TEXTURE_2D); 4) glBlendFunc(GL_ONE, GL_ZERO) 5) glEnable(GL_BLEND); 6) glColor3f(1.0f, 1.0f, 1.0f); 7) Textur ("textures/sfx/firegorre.tga") binden // Stage 2 8) MultitextUnit 1 aktivieren/wählen 9) glEnable(GL_TEXTURE_2D); 10) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ( = blend) 11) glEnable(GL_BLEND); 12) glColor3f(1.0f, 1.0f, 1.0f); 13) Textur ("textures/gothic_door/skullarch_b.tga") binden // Stage 3 14) MultitextUnit 2 aktivieren/wählen 15) glEnable(GL_TEXTURE_2D); 16) glBlendFunc(GL_DST_COLOR, GL_ZERO); // ( = filter) 17) glEnable(GL_BLEND); 18) glColor3f(1.0f, 1.0f, 1.0f); 19) Lightmap binden 20) glDrawElements() oder soStimmt das so?
Dankeschön
Tim
-
Fast, du musst noch die Texturtransformation und "rgbGen identity" berücksichtigen.
grüße
-
David_pb schrieb:
Fast, du musst noch die Texturtransformation und "rgbGen identity" berücksichtigen.
xindon schrieb:
- Texturkoordinaten verändern / berechnen
- glColor3f(1.0f, 1.0f, 1.0f);
Ist es das nicht?
6.3.2 rgbGen identity
Colors are assumed to be all white (1.0,1.0,1.0). All filters stages (lightmaps, etc) will get this by default.:edit:
Ich hab jetzt schon mehrfach die Methode glTexEnvf() gesehen. Kann ich damit erreichen, dass die Türtextur ÜBER die Flammentexture gemalt wird und nicht wie bei mir gemischt wird?Tim