# JOGL-Code != C OpenGL-Code?



## Network (20. Dez 2012)

Hallo

- Ich versuche in OpenGL 4.X für Java Einzug zu finden. Was anscheinend nur mit JOGL funktioniert, jedenfalls habe ich nichts anderes gefunden gehabt.
Tipp am Rande: Nicht JOGL verwenden wenn möglich.

Da ich keine OpenGL 4 JOGL Tutorials finde - habe ich mich an ein C++ Tutorial geheftet und so gut wie möglich versucht den Code in Java zu übersetzen.

- Kurz und gut: Der Code funktioniert nicht.
- Frage: Darf ich mich dabei an solche Tutorials wenden? Oder sind das Welten zwischen JOGL und dem echten OpenGL?


- Nebenbei hier ein kleines compilierbares Beispiel meines Codes (1zu1 übersetzt aus diesem Tutorial)
Vieleicht hat ja jemand mal Lust sich das anzuschauen.


Spoiler: Code



Der Code wurde mit zusätzlichem Code ergänzt im Konstruktor der Main-Klasse (So beschrieben auf der offiziellen JOGL-Website)

```
public class Main implements GLEventListener {
	private int triangleID;

	public Main() {
		JFrame jFrame = new JFrame();

		// Init
		GLProfile glp = GLProfile.getDefault(); // Result: GL4bc
		GLProfile.initSingleton();
		GLCapabilities glcaps = new GLCapabilities(glp);
		GLCanvas glc = new GLCanvas(glcaps);

		jFrame.add(glc);

		glc.addGLEventListener(this);

		FPSAnimator animator = new FPSAnimator(glc, 60);
		animator.add(glc);
		animator.start();

		// End
		jFrame.setTitle("JOGL");
		jFrame.setSize(500, 500);
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jFrame.setVisible(true);
		jFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
	}

	public static void main(String[] args) {
		new Main();
	}

	@Override
	public void init(GLAutoDrawable drawable) {
		System.out.println("Init");

		GL4 gl = drawable.getGL().getGL4();

		// VAO
		int vertexArrayID[] = new int[1];
		gl.glGenVertexArrays(1, vertexArrayID, 0);
		gl.glBindVertexArray(vertexArrayID[0]);

		// Init Triangle
		float triangle[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
				0.0f };
		FloatBuffer fb = FloatBuffer.allocate(triangle.length);
		fb.position(0);
		fb.put(triangle);
		fb.position(0);

		int array[] = new int[1];
		gl.glGenBuffers(1, array, 0);
		triangleID = array[0];
		gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, triangleID);
		gl.glBufferData(GL4.GL_ARRAY_BUFFER, fb.capacity(), fb,
				GL4.GL_STATIC_DRAW);
	}

	@Override
	public void dispose(GLAutoDrawable drawable) {
	}

	@Override
	public void display(GLAutoDrawable drawable) {
		System.out.println("Display");

		GL4 gl = drawable.getGL().getGL4();

		gl.glEnableVertexAttribArray(0);
		gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, triangleID);
		gl.glVertexAttribPointer(0, 3, GL4.GL_FLOAT, false, 0, 0);
		gl.glDrawArrays(GL4.GL_TRIANGLES, 0, 3);
		gl.glDisableVertexAttribArray(0);
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int width,
			int height) {
	}
}
```


----------



## Kr0e (20. Dez 2012)

Also zuerst mal:

Ich meine LWJGL kann auch OpenGL 4 aufwärts. Frag mich nicht wie, aber die Sachen waren damals immer in so GL15, GL20, GL33 etc gegliedert, ist bei mir schon ne Weile her.

Am Code fällt mir grad spontan nichts ein und hab grad auch kein Java etc. isntalliert ums zu testen.

Erste Idee: Du übergibts FloatBuffer. Musste man da nicht iwie rewind() oder flip() aufrufen ? Oder lesen die gl Funktionen den gesamten Buffer aus?

Davon abgesehen, WAS klappt denn nicht ? 



[OT]
Ich persönlich würde für OpenGL C/C++ empfehlen, einfach weil es näher am API ist (nein! Ich rede nicht von Geschwindigkeit). Ich habe mich bei Java oft über diese ganzen Buffer etc. geärgert. Das API ist für eine Zeiger-orientierte Sprache gemacht. Allein schon dass man Wrapper braucht, die gewartet und weiterentwickelt werden müssen finde ich unbefriedigend. C++ & Qt ist der Bringer für OpenGL 
[/OT]


----------



## Marco13 (20. Dez 2012)

gl.glBufferData(GL4.GL_ARRAY_BUFFER, fb.capacity()**4*, fb, GL4.GL_STATIC_DRAW);

Das sind bytes - was auch siezof im originalcode liefert.


----------



## Network (21. Dez 2012)

"Tipp am Rande: Nicht JOGL verwenden wenn möglich."
Nicht falsch verstehen, ich verwende JOGL weil ich es im Moment für eine sehr gute Schnittstelle halte - die fehlende Dokumentation des Codes kann einen aber wahnsinnig machen als Umsteiger auf 3 und höher.



Kr0e hat gesagt.:


> Also zuerst mal:
> 
> Ich meine LWJGL kann auch OpenGL 4 aufwärts. Frag mich nicht wie, aber die Sachen waren damals immer in so GL15, GL20, GL33 etc gegliedert, ist bei mir schon ne Weile her.
> 
> ...



Ja LWJGL hatte ich früher für <3.0 verwendet, wusste nicht, dass es auch höher geht. (Habe aber auch nie die Libs aktualisiert).
Es "wurde" kein Dreieck angezeigt.



Kr0e hat gesagt.:


> [OT]
> Ich persönlich würde für OpenGL C/C++ empfehlen, einfach weil es näher am API ist (nein! Ich rede nicht von Geschwindigkeit). Ich habe mich bei Java oft über diese ganzen Buffer etc. geärgert. Das API ist für eine Zeiger-orientierte Sprache gemacht. Allein schon dass man Wrapper braucht, die gewartet und weiterentwickelt werden müssen finde ich unbefriedigend. C++ & Qt ist der Bringer für OpenGL
> [/OT]



Definitiv. Man bemerkt die leichte Unverträglichkeit von Java und OpenGL.
Im Moment bringe ich mir zum zweiten mal OpenGL und allgemein Hardware3DComputergrafik bei, auf Rat von Marco13 (Ja zufällig die andere Person die hier geantwortet hat) bei - da zwischen 2 und 3 ja ein extremer Sprung liegt.
Und genau was du beschreibst stört mich auch jedesmal wieder beim studieren der Texte.

Jedoch wird aus einer platformunabhängigen Schnittstelle und einer platformabhängigen Sprache ein platformabhängiges Programm.  (Wer darauf aber kein Wert legt sondern auf OpenGL selbst...)



Marco13 hat gesagt.:


> gl.glBufferData(GL4.GL_ARRAY_BUFFER, fb.capacity()**4*, fb, GL4.GL_STATIC_DRAW);
> 
> Das sind bytes - was auch siezof im originalcode liefert.



Natürlich! Vielen Dank - Den Wald vor lauter Bäumen nicht gesehen! Und mit so einem Problem habe ich das Forum behelligt.
Jetzt kann ich auf jedenfall mit gutem Gewissen von der Kompatiblität zwischen C++ und Java ausgehen.


Mit freundlichen Grüßen,
Net


----------



## Guest2 (21. Dez 2012)

Moin,

streng genommen ist glVertexAttribPointer außerdem ausschließlich für die Verwendung mit Shadern spezifiziert. Das es manchmal auch mit der Fixed Function Pipline geht ist mehr Zufall als zu erwartendes Verhalten (oder Toleranz der Treiberentwickler ).

Viele Grüße,
Fancy


----------



## Marco13 (21. Dez 2012)

Der eigentliche Fehler war ja eher ein "Tipp"fehler. Genausogut hätte man in C statt
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), ... );
"versehentlich"
glBufferData(GL_ARRAY_BUFFER, numberOfVertices, ... );
schreiben können. 

BTW, @Fancy: Ja, ich hatte schon eine Antwort geschrieben: ~"Ich bin nicht sicher, ob ohne Shader überhaupt was angezeigt werden KANN". Aber dann wollte ich nichts falsches schreiben (auch weil das ja so im Tutorial stand - das muss nicht viel aussagen, aber trotzdem). EDIT> Aber gibt's nicht sogar eine Regel, dass die Vertices immer Attribute Location 0 haben müssen? Kann mich täuschen, bin nicht ganz auf dem neuesten Stand <EDIT

Deswegen habe ich ca. 1 Stunde rumprobiert, Shader eingefügt, die Initialisierung stückweise an ein Beispiel angepasst, bei dem ich wußte, dass es funktioniert, aber es wollte um's verrecken das Dreieck nicht anzeigen - bis ich den Bleistift auf die Tastatur geworfen habe, und er Zufällig auf den Tasten [c]*4[/c] landete.

Das zeigt aber IMHO das _eigentliche_ Problem: Es geht nicht um OpenGL oder JOGL, sondern darum, dass OpenGL SEHR low-level ist (und darum prinzipbedingt schwer zu verwenden und viele Fehlerquellen hat), aber vielleicht noch viel mehr darum, dass es kaum Fehlermeldungen oder Debugmöglichkeiten gibt: Wenn was nicht stimmt, zeigt er nichts an. Viel Spaß beim Suchen.

Genaugenommen ist JOGL da sogar noch etwas "gutmütiger", weil man immerhin ein 
GL4 gl = *new DebugGL4*(drawable.getGL().getGL4());
erstellen kann, und zumindest die "offensichtlichen" Fehler (die man in C durch Abfragen von glGetError nach JEDER Zeile :autsch: checken müßte) mit einer Exception quittiert bekommt.


----------



## Evil-Devil (21. Dez 2012)

LWJGL 2.8.5 unterstützt aktuell OGL 4.3 und OGL ES 3.0

Solange man keine explizite Version beim erzeugen des Displays angibt wird meine ich ein OGL Context im Kompatibilitätsmodus erzeugt. Für OGL 3.0 und aufwärts muss man lediglich beim erzeugen die Major und Minor Version mit übergeben. Dazu sollte es im Wiki eigentlich ein Beispiel geben.


----------



## Guest2 (21. Dez 2012)

Marco13 hat gesagt.:


> BTW, @Fancy: Ja, ich hatte schon eine Antwort geschrieben: ~"Ich bin nicht sicher, ob ohne Shader überhaupt was angezeigt werden KANN". Aber dann wollte ich nichts falsches schreiben (auch weil das ja so im Tutorial stand - das muss nicht viel aussagen, aber trotzdem). EDIT> Aber gibt's nicht sogar eine Regel, dass die Vertices immer Attribute Location 0 haben müssen? Kann mich täuschen, bin nicht ganz auf dem neuesten Stand <EDIT



Imho steht in der aktuellen Spec nichts, was die Location 0 von den anderen unterscheidet (außer das es eben die Erste ist). Im OpenGL Wiki stand / steht (?) das man aus Kompatibilitätsgründen die Positionen in Location 0 ablegen sollte. Allerdings finde ich den entsprechenden Abschnitt dort auch nicht mehr.

Wenn ein OpenGL Core Profil verwendet wird, ist es eh einfach: Kein Shader -> kein Bild.

Im Compatibility Profile wird das dann imho schwammig. Ich würde mich nicht drauf verlassen, dass es überall geht. 




Marco13 hat gesagt.:


> Das zeigt aber IMHO das _eigentliche_ Problem: Es geht nicht um OpenGL oder JOGL, sondern darum, dass OpenGL SEHR low-level ist (und darum prinzipbedingt schwer zu verwenden und viele Fehlerquellen hat), aber vielleicht noch viel mehr darum, dass es kaum Fehlermeldungen oder Debugmöglichkeiten gibt: Wenn was nicht stimmt, zeigt er nichts an. Viel Spaß beim Suchen.



Das schärft den Blick für Details. 

Viele Grüße,
Fancy


----------



## Network (21. Dez 2012)

Ich werde auf die zusätzlichen jedoch sehr interessanten Kommentare nicht eingehen, habe es aber gelesen und das "zusätzliche Wissen" anwenden. : )

Nebenbei hat sich LWJGL doch sehr zum positiven entwickelt. Es hat immernoch schwächen insbesondere da die höheren GL-Versionen nicht von den niedrigeren erben (Jedesmal die unvollständige OpenGL-Doc durchsuchen nach der richtigen Version) scheint aber sehr schön gepflegt zu werden.
Ich freu mich schon wie ein kleines Kind auf die ShaderProgrammierung - Wenn man sich die Beispiele der NVIDIA Corporation dazu anschaut wird es warm ums Programmiererherz.

Gruß
Net


----------



## Marco13 (21. Dez 2012)

[TIPP]Auf meinem Desktop liegt eine Datei namens "lwjgl imports.txt" mit diesem Inhalt:[/TIPP]

```
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL21.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL31.*;
import static org.lwjgl.opengl.GL32.*;
import static org.lwjgl.opengl.GL33.*;
import static org.lwjgl.opengl.GL40.*;
```


----------

