Enum mit return methode oder altmodisch final int's ?

Ja, ich erstelle in letzter Zeit irgendwie zu viele Threads…
Aber irgendwie fallen mir irgendwie immerwieder dinge auf, zu denen
ich gerne andere Meinungen hören würde… also, wenns nervt, dann könnt
ihr mir ja ne thread sperre verpassen oder so xD

Also diesmal gehts um folgendes:

Ein Teil einer Klasse sieht so aus:

private int drawMode;

public void draw(){
     glDrawArrays(drawMode, ...);
}

Nun. Die Frage ist, wie kommt man an drawMode. Dazu gibt es in OpenGL definierte
final ints, GL_TRIANGLES, GL_TRIANGLE_STRIP und so weiter.

Sollte man in einer Library, wenn man diese Variablen wrappen will, genauso als final ints lassen?
Oder besser ein enum verwenden, welches dann so aussehen würde:

		
	TRIANGLES(GL_TRIANGLES),
	TRIANGLE_STRIP(GL_TRIANGLE_STRIP);
	
	private int rawMode;
	
	DRAW_MODE(int rawMode){
		this.rawMode = rawMode;
	}
	
	public int getRawMode(){
		return rawMode;
	}
}```

Weil, eigentlich sind enums ja dazu gedacht, aber irgendwie kommen mir die
so ziemlich zweckentfremdet vor.. was meint ihr?

*** Edit ***

Die Frage lässt sich ja verallgemeinern, es ist ja genauso mit allen Dingen 
die eigentlich Aufzählungen sein müssten / könnten, dann aber so eine rückgabe 
methode bräuchten.. zum Beispiel java.awt.Color: hätte man dort, wenn es seit der 
ersten Java Version enums gäbe, ein enum für die vordefinierten farben verwendet?

Pauschale Aussagen sind schwierig. Genaugenommen sind pauschale Aussagen IMMER falsch. :smiley:

Allgemein gibt es „wenige“ Fälle, wo ints (für solche Anwendungsszenarien) gegenüber einer enum Vorteile hätten. Theoretisch können sie effizienter sein, und wenn man sie mit bitweisen Operatoren verknüpfen will, können sie praktisch sein (es hat schon einen Grund, warum int-Konstanten in Java 8 (!) neu eingeführt wurden!). Aber meistens ist das nicht relevant.

In diesem konkreten Fall würde sich mir eine viel drängendere Frage auf einem viel höheren Abstraktionslevel stellen: Inwieweit soll man an deinen Klassen noch erkennen, dass OpenGL verwendet wird? Und insbesondere: Inwieweit soll man erkennen, dass eine spezielle OpenGL-Anbindung verwendet wird? Wenn jemand DEINE Klasse verwenden will, braucht er dann einen import some.jogl.package.GL.GL_TRIANGLES? (bzw. SOLL er ihn brauchen?)

eben nicht, der jenige soll gar nichts mit opengl an sich machen können sollen.
Deshalb will ich die ja auch wrappen. Ich kann ja einfach genauso int konstanten machen
wie sie in opengl verwendet werden, zB public static final int TRIANGLES = GL11.GL_TRIANGLES;

Die Frage ist nur ob das besser ist als ein enum mit einer return methode.
(Beziehungsweise wie ihr das machen würdet)

Also ich persönlich halte diese Enum-Variante für sinnvoller, weil sie typesafe sind. Wenn du ints übergeben ließest, könnte der Anwender auch GL11.GL_TRIANGLES übergeben, wenn ihm dieser Umstand bekannt wäre.
Die Sichtbarkeit des Rawmodes sollte evtl. packageprivate (also default) sein, dazu final und nicht über get erreichbar sein. Klassen, die diese Variable brauchen, müssen dann im selben Verzeichnis (Package) sein, wie das Enum.
Ausserdem: Wie Marco13 bereits sagte… muss es denn so offensichtlich sein, dass deine API so unbedingt an OpenGL bzw. gar LWJGL hängt? Welchen Sinn macht denn deine API dann? Wäre es nicht sinnvoller, den Usern deiner API die Wahl zwischen Java3D, JOGL (bzw. JogAmp) und LWJGL zu lassen? Will sagen, deine API als Bindeglied zwischen den verschiedenen anderen 3D-APIs. An dieser Grätsche versuche ich mich grad (sehr problematisch).
Deine API wählt dann, je nach dem welche 3D-API der User installiert hat, seine eigene Kern-Klasse, an welche die Funktionalität deiner API delegiert wird.
@Marco13 :
Bitweise-Operatoren sind auch kein echter guter Grund für ints. Erstens gibt es die Klasse EnumSet und zweitens den VarArgs-Operator. :wink:

Offtopic

Standard dazu

:wink:


je mehr Einsatz, in diversen eigenen Methoden/ Attributen, wo die Enum sicherer sein kann als int (statt nur bei direkten API-Aufrufen wo man den int rausholen müsste),
je mehr weitere (sinnvolle) Information in der Enum dazu abzulegen, desto sinnvoller

Okay, also tendiert ihr auch zu enums?

Aber Spacerat… hä?
Ich bastel mir eine Lwjgl library… :smiley: Wieso sollte ich eine Joglwjgl3d library machen?
Verstehe nicht was das bringen soll… :smiley:

Moin,

ich weiß nicht genau auf welcher Ebene abstrahiert werden soll, aber es gibt einige (wenige) Stellen wo man mit den OpenGL Konstanten tatsächlich rechnet. Beispiel:

Das Problem dabei ist das wohl seit GL_TEXTURE31 keine neuen Konstanten mehr angelegt wurden. Das Wiki empfiehlt stattdessen GL_TEXTURE0 + i zu übergeben. Hat man ein Enum als Typ definiert müsste man alle 96 Konstanten definieren und regelmäßig aufpassen ob sich da was ändert.

Im Allgemeinen ist Typsicherheit aber natürlich besser.

Viele Grüße
Fancy

@SlaterB :Ja, du kennst deine (oder nun auch meine) Pappenheimer. :lol:
Diese Infos in Enums sollten sich aber nicht direkt auf Fremd-APIs beziehen.

@mymaksimus :Wieso baust du dir eine LWJGL-Library, wenn LWJGL bereits selber eine Library ist? Welchen Vorteil bietet deine API? BTW.: Java3D ist auch, wenn man so will eine OpenGL-Library. Allerdings eine, die unter Windows auch mit DirectX klar kommt (kann sein, das diese Aussage inzwischen ein wenig überholt ist, Java3D ist bei mir schon einige Jährchen tot). Wie dem auch sei. In Java3D selber ist von den darunter liegenden APIs rein gar nichts mehr zu merken.
Als API wäre mMn nur eine Art Graphics-Context (ala Graphics2D) für 3D von Vorteil oder für 2D ein solcher, welcher nicht so stark an Java2D gebunden ist.

@SlaterB und @Spacerat Soweit ich das verstanden habe, geht es nicht um “Yet another OpenGL binding”. OpenGL (egal ob nativ, mit JOGL oder LWJGL - oder auch GL ES in Android) ist schon ermüdend low-level. Da eine schöne, objektorientierte Abstraktionsschicht drüberzustülpen wäre eine feine Sache. Es gibt zwar ein bißchen was, aber das ist dann eher so die “JMonkeyEngine”-Kategorie: Mehr als eine kleine, praktische Lib…

Ich hatte das ja auch irgendwann mal angesetzt ( http://rendering.javagl.de/index.html ), aber … es ist schwierig. OOP und OpenGL sind schon recht weit voneinander weg. Wie so oft stellt sich die Frage, welche low-level-features man durch die OO-Schicht durchschleifen will (schließlich könnte man drüber philosophieren, ob eine API, die die gleiche Funktionalität bietet, wie eine andere, überhaupt deutlich einfacher zu verwenden sein KANN ;-)). Und letztendlich hat man dabei ein gewaltiges Problem, das anzugehen recht schnell “praktisch unmöglich” erscheint: Man kann Shader schreiben. Und in Shadern kann jeder Sche!ß gemacht werden. “Alles” zu unterstützen, was damit gemacht werden kann, ist schwierig (von den üblichen Ärgernissen, wie etwa “Diese-und-jene Funktion ist bei GL 4.1 noch nicht dabei, sondern erst bei GL 4.2…”, mal abgesehen).

[QUOTE=Marco13]schließlich könnte man drüber philosophieren, ob eine API, die die gleiche Funktionalität bietet, wie eine andere, überhaupt deutlich einfacher zu verwenden sein KANN ;-)[/QUOTE]Deswegen fragte ich ja auch nach dem Sinn einer solchen Lib, die nur auf LWJGL aufbaut. Wenn man eine Grafik-Lib bauen will, sollte diese eben nicht stark an solche Dinge gebunden werden. Die einzige Daseinsberechtigung einer solchen ist ja Simplifizierung dieser LowLevel-Features, natürlich mit den Einschränkungen jener Features, die durch diese überlagerte Lib ausgeschaltet werden. Und wenn ich (man) weis, dass eine solche Lib auf einer speziellen anderen Java-API aufbaut, brauch(t) ich (man) sie nicht, ganz einfach, weil man seinen eigenen Abstraktionslevel mit der verdeckten Lib viel besser erreichen kann.

Joar, ich denke Marco hat ausgedrückt was ich meine.

Aber ich mach das so, das man Shader alleine schreibt und fertig.
Der Nutzer muss der lib halt nachher sagen was drin ist.

Und woher wissen die Shader, wo die Daten für ihre Eingaben herkommen? Irgendwie müssen die Variablennamen, die im Shader vorkommen, auch im Java-Code vorkommen. Das ist der Knackpunkt (und wenn ich mich an die Krämpfe errinnere, die das bei meinen Versuchen verursacht hat, könnte man bei diesem Wort auch das erste “n” weglassen :verzweifel: )

naja, wie gesagt, der Nutzer sagt das der Lib.
Zum Beispiel wenn die Kamera erzeugt wird: void createCamera(AGLMat4Uniform binding);
und vorher wird halt ein UniformObjekt erstellt: (konstruktor ->) public AGLMat4Uniform(AGLShaderProgram progarm, String name);

So ist das Prinzip. Vbos werden nach einem ähnlichen Prinzip gestaltet.

(Ich dachte mal daran eine Art ShaderAnalyser zu bauen oder so… der würde dann alleine einlesen was drin ist und so weiter…
ergibt aber eigentlich keinen sinn, weil der user ja trozdem selber die werte setzen muss und so weiter…)

[QUOTE=Marco13]Pauschale Aussagen sind schwierig. Genaugenommen sind pauschale Aussagen IMMER falsch. :smiley:

Allgemein gibt es „wenige“ Fälle, wo ints (für solche Anwendungsszenarien) gegenüber einer enum Vorteile hätten. Theoretisch können sie effizienter sein, und wenn man sie mit bitweisen Operatoren verknüpfen will, können sie praktisch sein (es hat schon einen Grund, warum int-Konstanten in Java 8 (!) neu eingeführt wurden!).[/QUOTE]

Marco, kanntest du:
int mid = ((lo + fence) >>> 1) & ~1;
um die Mitte zu erhalten und gerade Zahl? schon