# JOGL: Dreiseitige Pyramide



## Guest (22. Dez 2006)

Hi,

ich habe mir mal das Tutorial auf soulflyhome.com durchgelesen. 
Danach habe ich versucht nicht ein Dreieck, sondern eine dreiseitige Pyramide rotieren zu lassen. Der Code in display() vom GLEventListener schaut dann so aus:

```
GL gl = drawable.getGL();
		
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);
		gl.glLoadIdentity();
		
		gl.glRotatef(rtri, 1.0f, 1.0f, 1.0f);
	
		gl.glBegin(GL.GL_TRIANGLES);
			gl.glColor3f(0.0f, 1.0f, 0.0f);
			gl.glVertex3f(0.5f, -0.5f, 0.0f);
			//gl.glColor3f(0.0f, 1.0f, 0.0f);
			gl.glVertex3f(0.0f, 0.5f, 0.0f);
			//gl.glColor3f(0.0f, 0.0f, 1.0f);
			gl.glVertex3f(0.0f, -0.5f, 0.5f);
		gl.glEnd();
		
		gl.glBegin(GL.GL_TRIANGLES);
			gl.glColor3f(1.0f, 0.0f, 0.0f);
			gl.glVertex3f(-0.5f, -0.5f, 0.0f);
			//gl.glColor3f(0.0f, 1.0f, 0.0f);
			gl.glVertex3f(0.0f, 0.5f, 0.0f);
			//gl.glColor3f(0.0f, 0.0f, 1.0f);
			gl.glVertex3f(0.5f, -0.5f, 0.0f);
		gl.glEnd();
		
		gl.glBegin(GL.GL_TRIANGLES);
			gl.glColor3f(0.0f, 0.0f, 1.0f);
			gl.glVertex3f(0.0f, 0.5f, 0.0f);
			//gl.glColor3f(0.0f, 1.0f, 0.0f);
			gl.glVertex3f(-0.5f, -0.5f, 0.0f);
			//gl.glColor3f(0.0f, 0.0f, 1.0f);
			gl.glVertex3f(0.0f, -0.5f, 0.5f);
		gl.glEnd();
	
		gl.glBegin(GL.GL_TRIANGLES);
			gl.glColor3f(1.0f, 1.0f, 1.0f);
			gl.glVertex3f(0.0f, -0.5f, 0.5f);
			//gl.glColor3f(0.0f, 1.0f, 0.0f);
			gl.glVertex3f(-0.5f, -0.5f, 0.0f);
			//gl.glColor3f(0.0f, 0.0f, 1.0f);
			gl.glVertex3f(0.5f, -0.5f, 0.0f);
		gl.glEnd();
		rtri+=0.1;
```
Allerdings wird die Pyramide nicht richtig dargestellt, irgendwie scheinen einige Seitenfläschen transparent zu sein. Was mache ich da falsch?

Danke


----------



## Campino (22. Dez 2006)

ich hab schon ewig nichtmehr mit JOGL OpenGL gearbeitet, aber: 

1) Deine Seiten haben keine Normalen. Die Normale für eine Dreiecksfläche berechnest du per: 


```
Vector v1v2, v1v3, kreuz; //Vector ist eine eigene Klasse, die einen x, einen y und einen z-Wert zusammenfasst
		double betrag;
//Zusätzlich zu dem hier definierten werden die Eckpunkte der Fläche als Vector v1, v2 und v3 benötigt
		
		//Vorbereitung
		v1v2=new Vector(v2.x-v1.x, v2.y-v1.y, v2.z-v1.z);
		v1v3=new Vector(v3.x-v1.x, v3.y-v1.y, v3.z-v1.z);
		
		//Berechnung des Kreuz
		double x=+((v1v2.getY()*v1v3.getZ())-(v1v2.getZ()*v1v3.getY()));
		double y=-((v1v2.getX()*v1v3.getZ())-(v1v2.getZ()*v1v3.getX()));
		double z=+((v1v2.getX()*v1v3.getY())-(v1v2.getY()*v1v3.getX()));
		kreuz=new Vector(x, y, z);
		
		
		//prüfen des Vectors
		betrag=Math.sqrt(Math.pow(kreuz.getX(), 2.0)+Math.pow(kreuz.getY(), 2.0)+Math.pow(kreuz.getZ(), 2.0));
		if(betrag==0.0){
			return null; //d.h. der Normale ist null, Berechnung vermutlich falsch...eventuell bilden v1, v2 und v3 keine Fläche
		}
		
		return kreuz; //In jedem anderen Fall ist das Ergebnis richtig, kann also verwendet werden
```

2) hast du beachtet, dass eine Fläche in OpenGL eine Vorder- und eine Rückseite hat? Die Vorderseite ist die, wo deine Eckpunkte gegen den Uhrzeigersinn definiert sind, das ist bei dir glaub ich falsch rum.

campino


----------



## Gast (22. Dez 2006)

Wozu sind die Normalen gut?


----------



## Campino (22. Dez 2006)

Die Normalen stehen jeweils senkrecht auf der Fläche und dienen z.B. dazu, zu gucken, welche Flächen überhaupt gemalt werden müssen. 

Mal dir mal ein Achteck, dann auf an Seite einen Pfeil=Vektor, der senkrecht auf der Fläche steht (=den Normalen). jetzt setzt du irgendwo daneben einen Punkt. Das ist der Betrachterstandpunkt. Wenn du jetzt jeweils das untere Ende eines Pfeils mit diesem Punkt verbindest, musst du nur die Flächen, deren Normalen in einem spitzen Winkel (<90 Grad) zu diesen Verbindungslinien stehen, malen. Alle Anderen sind vom Betrachterstandpunkt aus sowieso nicht zu sehen. 

Wenn dein Normalvektor jetzt (0, 0, 0) ist, ist der Winkel mit jedem Vektor 90 Grad. Weil cos winkel=a*b[/b]=ax*bx+ay*by, wenn ax und ay oder bx und by 0, ist also cos winkel=0, und cos 0 entspricht 90 Grad. Also ist der Winkel nicht spitz, die Fläche wird nicht gemalt. 

Deshalb wird eine Fläche ohne Normalvektor nicht dargestellt.


----------



## Gast (22. Dez 2006)

Und wie bringe ich es der Ebene dann bei, welchen Normalenvektor sie hat?

PS: Das OpenGL-Tutorial von NeHo (Kapitel 5: 3D) und das dazugehörige JOGL-Code-Beispiel kommen ohne Normalenvektor aus!


----------



## Campino (22. Dez 2006)

Gast hat gesagt.:
			
		

> Und wie bringe ich es der Ebene dann bei, welchen Normalenvektor sie hat?


Eigentlich müsste der Code mit drei beliebigen der vier Ecken einen richtigen Normalen liefern. 



> PS: Das OpenGL-Tutorial von NeHo (Kapitel 5: 3D) und das dazugehörige JOGL-Code-Beispiel kommen ohne Normalenvektor aus!



Seltsam...vllt. ist dort CULL_FACE nicht aktiviert. bzw. löst das mit den Normalen und mit dem Gegen-den-Uhrzeigersinn den dein Problem? Sonst müssen wir da sowieso nicht weiter drüber reden...


----------



## Gast (22. Dez 2006)

Ich habe das etwas anderst gemeint: Was mache ich den mit dem Normalenvektor, wenn ich ihn ausgerechnet habe???
Und nein, die Sortierung gegen den Uhrzeigersinn ändert nichts!


----------



## Campino (23. Dez 2006)

Achso, sry, das hatte ich falsch verstanden. 


```
gl.glBegin(GL.GL_TRIANGLES);
         gl.glNormal3f(x, y, z); /*<--- Die Funktion ist wie üblich am ende mit Wertanzahl+Werttypkürzel markiert, glNormal3f will also drei Floatwerte als Parameter, 2d, zwei Double usw. */
         gl.glColor3f(0.0f, 0.0f, 1.0f);
         gl.glVertex3f(0.0f, 0.5f, 0.0f);
         //gl.glColor3f(0.0f, 1.0f, 0.0f);
         gl.glVertex3f(-0.5f, -0.5f, 0.0f);
         //gl.glColor3f(0.0f, 0.0f, 1.0f);
         gl.glVertex3f(0.0f, -0.5f, 0.5f);
      gl.glEnd();
```


----------



## Gast (23. Dez 2006)

Sorry, eine Nachfrage noch: aus welchem Paket stammt die Vector-Klasse? Ich habe den aus Java.until.Vector versucht, aber der kennt nicht v1.getX usw.


----------



## Campino (23. Dez 2006)

Die Vector-Klasse ist, wie ich in meinen Kommentar zum Code geschrieben habe, eine eigene Klasse. Nimm einfach: 


```
public class Vector{
private float x, y, z;

public Vector(float x, float y, float z){
this.x=x; this.y=y; this.z=z;
}

public float getX(){
return x;
}

public float getZ(){
return z;
}

public float getZ(){
return z;
}
}
```


----------



## Gast (23. Dez 2006)

Ok danke zunächst. 
Aber auch mit den Normalen wird die Pyramide nicht richtig angezeigt!


----------



## Soulfly (24. Dez 2006)

Hmm ich meld mich hier mal 

Bei Opengl wird unterschieden zwischen eine Wand von hinten angucken oder von vorne.

Die Punkte der Wand müssen AFAIK gegen den Uhrzeigersinn gesetzt sein  dann ist sie von vorne sichtbar und von hinten nischt.

Hmm doof sone sache! Sorry

MfG


----------

