Fragen über Object3D (Texturen / Farben) [Android]

Started by Telix, November 07, 2013, 08:37:02 AM

Previous topic - Next topic

Telix

Hallo zusammen,

Aktuell arbeite ich an einem Spiel (Bin eigentlich Web / Desktop / Mobile Entwickler jedoch für Anwendungen).
Und habe direkt mehrere Fragen und hoffe ihr könnt mir helfen :)

Ich habe ein Object3D welches ein "halber" Würfel ist, er hat nur 3 Seiten den rest benötige ich nicht.

1. Wie bekomme ich eine Seite davon mit einer anderen Texture?
(Sprich ich möchte die Texture für eine Seite ändern sobald man drauf klickt)

2. Kann ich eine Seite Farblich kennzeichnen mit Texture?
(Sprich die Seite hat eine Texture und ich möchte, dass diese nun noch Blau oder Rot gefärbt wird)

3. Wie kann ich ein Würfel erzeugen, der nur die außen Linien hat?
(Sprich ein Würfel ohne Inhalt aber man jedoch die Kanten sieht)

Das wars vorerst :)

Vielen Dank für eure Hilfe!

EgonOlsen

Quote from: Telix on November 07, 2013, 08:37:02 AM
1. Wie bekomme ich eine Seite davon mit einer anderen Texture?
(Sprich ich möchte die Texture für eine Seite ändern sobald man drauf klickt)
Im Prinzip geht das über den PolygonManager. Aber da musst du eine Besonderheit beachten: Du kannst nicht mehr verschiedene Texturen nutzen und/oder sie an anderen Stellen nutzen, als du sie beim ersten Rendern verwendet hast. D.h. du müsstest jeder Seite eine individuelle Textur zuweisen. Dann kannst du die nachträglich auch ändern. Wenn du am Anfang nur eine benutzt, wird deine Änderung ber den PolygonManager nicht funktionieren. Das liegt an der Art, wie der Grafikchip die Daten entgegennimmt. In deinem Fall würde ich einfach 3 einzelne
Object3Ds verwenden. Dann ist es einfacher, die Texturen zu ändern.
Quote from: Telix on November 07, 2013, 08:37:02 AM
2. Kann ich eine Seite Farblich kennzeichnen mit Texture?
(Sprich die Seite hat eine Texture und ich möchte, dass diese nun noch Blau oder Rot gefärbt wird)
Jein. Nicht, wenn alle Seiten zum selben  Object3D gehören. Wie oben erwähnt, würde ich das teilen. Dann kannst du mit setAdditionalColor() die Farben manipulieren (in den Grenzen der OpenGL-Beleuchtungsformeln, d.h. du kannst eine komplett grüne Textur nicht rot machen).
Quote from: Telix on November 07, 2013, 08:37:02 AM
3. Wie kann ich ein Würfel erzeugen, der nur die außen Linien hat?
(Sprich ein Würfel ohne Inhalt aber man jedoch die Kanten sieht)
Am einfachsten, indem du eine (evtl. transparente) Textur zuweist, die nur die Außenkanten zeigt. Wireframe an sich geht nicht, weil a) es in jPCT-AE aufgrund einer Limitierung von OpenGL ES nicht gut unterstützt wird und du b) sonst immer die Dreiecksgrenzen, nicht die Würfelkanten sehen würdest.

Telix

erst mal vielen Dank! :)

Nun meine weiteren Fragen :D

1. Wie verhält sich die Performance bei einem object mit 3 seiten oder 3 objecten mit jeweils eine seite?
(wir reden hier nicht von 1 würfel sondern von 500 - 1000)

2. Spielt die anzahl von objecten überhaupt eine rolle (Verwaltungsaufwand?)

3. Texture einer Seite festlegen

Ich nutze:
box.addTriangle(upperLeftBack,0,0, upperLeftFront,0,1, upperRightBack,1,0, TextureManager.getInstance().getTextureID("stone"));
box.addTriangle(upperRightBack,1,0, upperLeftFront,0,1, upperRightFront,1,1, TextureManager.getInstance().getTextureID("stone"));

um die oberen triangle's zu erzeugen.

nun wollte ich mit:

dataObject.setTexture(new TextureInfo(TextureManager.getInstance().getTextureID("texture"), 0, 0, 0, 1, 1, 0));

die oberseite ändern jedoch verändert er die Texture vom ganzen würfel?!

Gruß
Michael


EgonOlsen

Die Performance mit 3 Objekten wird etwas schlechter sein. Vermutlich aber nicht viel, weil das nur auf der Engine-Seite mehr Aufwand bedeutet. Für den Grafikchip ist es egal, denn für den werden die Daten ohnehin nach Texturverwendung gruppiert. D.h. sogenannte Draw-Calls hast du in beiden Fällen 3, bei 3 Objekten statt einem ist aber der Overhead der Engine größer. Generell sind 500-1000 Objekte bei Android eine Hausnummer. Musst du gucken, wie gut das noch funktioniert.

Damit ist auch Frage 2 beantwortet: Ja, eine ziemlich große! Die Anzahl Draw-Calls ist besonders auf Mobilgeräten entscheidend für die Performance. Wobei der Einfluss von Chip zu Chip schwankt. Bei PowerVR oder Mali ist es z.B. nicht so tragisch wie bei Adreno-Chips.

Zu Frage 3: Ja, weil das so nicht geht. Du änderst mit setTexture immer die Textur für das ganze Object3D. Wenn du einzelne Polygone ändern willst, musst du wie erwähnt den PolygonManager nehmen. Aber dann müsstest du alle anderen Flächen mit einer anderen Textur als "stone" behaften...das ist vielleicht nicht ganz klar, was ich damit meine und wieso das so ist. Ich versuche mal ein Erklärung:
Die Objekte werden beim ersten Rendern für die GPU "compiliert". Dabei werden gleichartige Polygone zusammengefasst, so dass sie in einem Draw-Call gerendert werden können. Haben nun alle Polygone dieselbe Textur, entsteht bei diesem Vorgang eine Struktur, die mit einem Draw-Call gezeichnet werden kann. Hast du z.B. drei verschiedene Texturen verwendet, entsteht eine Struktur, die mit drei Draw-Calls gerendet wird. Diese Struktur ist danach aber nicht mehr änderbar. D.h. wenn du einem Objekt, welches für einen Draw-Call compiliert worden ist, plötzlich drei Texturen zuweist, dann kann es damit nicht umgehen, weil die Strukur das nicht hergibt. Wenn du das machen willst, musst du gleich am Anfang die Grundlage dafür schaffen, damit das Objekt in 3 Draw-Calls zerlegt wird. Das tust du, indem du 3 unterschiedliche Texturen zuweist.

Telix

wow super Erklärungen! Vielen Dank!

Hast du zufällig ein Beispiel oder Tipps nach was ich suchen kann beim PolygonManager?

Wie ich die Texturen einzelnd zuweise und dann später ändern kann?

weil ich hab nicht immer nur 3 seiten das kann unterschiedlich sein nach typ und dann wäre es glaube ich overkill dann für jede seite ein object zu machen.

Vielen Dank schonmal.

EgonOlsen

Einfach beim Erzeugen (das machst du ja im Code) den Seiten jeweils eine andere Textur zuweisen. Danach kannst mit PolygonManager.getPolygonTexture() jeweils diesen Polygonen eine andere Texture zuweisen. Dabei musst du eine PolygonID angeben. In diesem einfachen Fall ist das quasi die Position, an der du das Polygon eingefügt hast, d.h. das mittels der ersten addTriangle-Anweisung angelegte hat die ID 0, das nächste 1, dann 2 usw.

Telix

ich habe beim erstellen nun direkt als letzten parameter versucht eine texture zu setzen aber auch über den manager:

box.getPolygonManager().setPolygonTexture(0, TextureManager.getInstance().getTextureID("texture"));
          box.getPolygonManager().setPolygonTexture(1, TextureManager.getInstance().getTextureID("texture"));
         
          box.getPolygonManager().setPolygonTexture(2, TextureManager.getInstance().getTextureID("stone"));
          box.getPolygonManager().setPolygonTexture(3, TextureManager.getInstance().getTextureID("stone"));
         
          box.getPolygonManager().setPolygonTexture(4, TextureManager.getInstance().getTextureID("texture"));
          box.getPolygonManager().setPolygonTexture(5, TextureManager.getInstance().getTextureID("texture"));
          box.getPolygonManager().setPolygonTexture(6, TextureManager.getInstance().getTextureID("texture"));
          box.getPolygonManager().setPolygonTexture(7, TextureManager.getInstance().getTextureID("texture"));


leider wenn ich nachträglich versuche die texture zuändern, passiert garnichts :(

dataObject.getPolygonManager().setPolygonTexture(2, TextureManager.getInstance().getTextureID("texture"));
dataObject.getPolygonManager().setPolygonTexture(3, TextureManager.getInstance().getTextureID("texture"));


Die Texture von 2 und 3 will ich von stone auf texture ändern.
Muss ich dafür noch irgend etwas aktivieren?

Und was macht die Methode build() und strip()?
Bewirkt bei mir keinen unterschied ob die drin sind oder nicht.

Gruß
Michael

Telix

Noch eine Frage für heute und dann is erstmal Feierabend :)

Wieso kann ich diese 2 Modi gleichzeitig nutzen?
Sobald ich Lighting aktiviere, verliert die box die additionalColor :(

dataObject.setLighting(Object3D.LIGHTING_ALL_ENABLED);
dataObject.setAdditionalColor(0, 0, 0);

EgonOlsen

Quote from: Telix on November 07, 2013, 10:12:18 PM
Die Texture von 2 und 3 will ich von stone auf texture ändern.
Muss ich dafür noch irgend etwas aktivieren?

Und was macht die Methode build() und strip()?
Bewirkt bei mir keinen unterschied ob die drin sind oder nicht.
Das geht, wie erwähnt, nur, wenn 2 und 3 vorher nicht auch "stone" waren. Ansonsten kannst du die nicht mehr individuell ändern. Also 2 und 3 beim Erstellen auf z.B. "hurz" setzen. Dann kannst du sie im Nachgang zu "texture" machen.

build() generiert Normalen, Bounding Boxes und diverses andere. Wenn du es nicht aufrufst, macht jPCT-AE das zur Laufzeit automatisch. Es ist aber besser, es explizit zu machen. strip() spart Speicher, ist aber nicht für alle Objekte sinnvoll möglich. Textur umsetzen auf getstrippten Objekten geht z.B. nicht.

EgonOlsen

Quote from: Telix on November 07, 2013, 10:39:50 PM
Wieso kann ich diese 2 Modi gleichzeitig nutzen?
Sobald ich Lighting aktiviere, verliert die box die additionalColor :(
Nein, tust du nicht. Du siehst es nur nicht mehr. Das liegt an der Lichtberechnung, wie die OpenGL-Pipeline sie durchführt. Was hast du denn als Lightquelle gesetzt...(255,255,255)? Wenn ja, mach die mal dunkler. Dann sollte man wieder was sehen.

Telix

Ok macht Sinn :)

Neue Fragen neues Glück :D

LIGHTING_ALL_ENABLED sollte das immer aktiv sein oder sollte man das wirklich nur für licht nutzen?

Gibt es ein Licht, welches rund rum leuchtet als kugelform?
Hab nur ein Licht gefunden, welches auf ein bestimmten punkt leuchtet.

Desweiteren die Frage wieviele Lichtquellen kann man haben? Wären 100 kein Problem?
(Natürlich im ganzen Level verstreut)

Gibt es ein unterschied ob ich 3 x eine kleiche fläche mit 6 polys oder ob ich eine große habe die ich "kombiniere" und nur 2 polys jedoch alle mit der gleichen texture?

Falls es ein Unterschied gibt, kann ich eine Texture irgendwie kacheln? sprich hab eine fläche von 3x3 wären ja 9 felder und würde ja unterschiedliche texturen benötigen. wie kann ich eine Texture schaffen, die 9 unterschiedliche texturen beinhaltet jedoch auf nur 2 polys gezogen wird?

Gruß
Michael

EgonOlsen

 
Quote
          LIGHTING_ALL_ENABLED sollte das immer aktiv sein oder sollte man das wirklich nur für licht nutzen?
         
Default ist an und das sollte im Normalfall auch so sein. Nur in speziellen Fällen will man das nicht.
         
         
Quote
          Gibt es ein Licht, welches rund rum leuchtet als kugelform?
          Hab nur ein Licht gefunden, welches auf ein bestimmten punkt leuchtet.
         
Hmmm...da verstehe ich Frage nicht so ganz. Die Lichtquellen sind alle Punktlichter. Es gibt keine gerichteten Lichtquellen in jPCT-AE. Von daher sollte das eigentlich das sein, was du meinst.
         
         
Quote
          Desweiteren die Frage wieviele Lichtquellen kann man haben? Wären 100 kein Problem?
          (Natürlich im ganzen Level verstreut)
         
Ahem...naja, also...100 Lichter sind ziemlich viele. Die Hardware kann 8 pro Objekt, die Engine wählt die "besten" pro Objekt aus. Von daher gehen 100 pro Level schon, aber das sollte man eigentlich vermeiden, wenn es möglich ist. Wenn du 1000 Objekte mit je 100 Lichtern beleuchten möchtest, muss ja erstmal ermittelt werden, welche 8 dann passen. D.h. du hast pro Bild alleine 100.000 Berechnungen nur dafür.
         
         
Quote
          Gibt es ein unterschied ob ich 3 x eine kleiche fläche mit 6 polys oder ob ich eine große habe die ich "kombiniere" und nur 2 polys jedoch alle mit der gleichen texture?
         
Letzteres ist schneller, ersteres hat die bessere Beleuchtung (sofern du keine Shader/OpenGL ES 2.0 einsetzt).
         
Quote
kann ich eine Texture irgendwie kacheln?
Ja, wenn du Koordinaten>1 oder <0 für u/v angibst.

Telix

okay ich denke ich werde ein Problem mit der Anzahl der Objekte bekommen.

würde es evtl. Sinn machen für die komplette Umgebung nur 1 Object3D zu nutzen und alle polys selber zu berechnen?
Es geht darum, dass man unter der erde ist und gänge "bauen" kann... (nur eine ebene)

Wenn ich alles in einem Objekt habe müsste ich für jede Kachel die Texture berechnen.
Wäre das Sinnvoll? Somit hätte ich eine art "Level"

Frage zu den Lichtern. Ich habe nun 20 gänge und möchte dass in jedem gang 2 - 3 fackeln sind.
Wäre das nicht möglich? es werden ja nicht alle gänge gleichzeitig angezeigt denke so 4 - 5 fackeln gleichzeitig :)
Die Fackeln strahlen ja aber nicht ein bestimmten punkt an sondern erleuchten einfach die Umgebung.

Ist das machbar alles? Sollte ich weg von den vielen Objekten für das Level?
Wichtig wäre, dass der Nutzer das Level verändern kann.

Gruß
Michael

EgonOlsen

Ich würde sagen: Probier es aus! Das ist schwer abschätzbar. Wenn der LEvel änderbar sein soll, würde ich mit einzelnen Objekten beginnen. Es gibt sicher auch Wege, dass mit einem großen Objekt zu machen, welches zur Laufzeit geändert wird. Aber wird ungleich komplizierter.
Was die Lichter angeht: Wenn du weißt, welche Fackeln sichtbar sind, könntest du die einfach selber umsetzen. Dann kommst du mit weniger Lichtquellen aus und die Berechnungen werden weniger.

Telix

#14
ok dann probiere ich es doch mit optimierten eizelnen objekten :)

was bewirkt strip genau? Warum kann ich damit nicht mehr die Texture ändern?
Sollte ich strip verwenden?

Werden lichtquellen die nicht sichtbar sind nicht einfach ignoriert?

Kann ich irgendwie anders bewirken, dass es so aussieht als ob es "heller / beleuchtet" ist?
(Ansich soll es ein Tunnel sei wo der nutzer selber lichtpunkte setzen kann)