# "Tiefe" in Objekten - LWJGL



## Pommes9485 (18. Nov 2012)

Guten Tag,

mein Kumpel und ich haben folgendes Problem, wir suchen schon seit Stunden nach einer Lösung :
Unsere Objekte haben  keine Schatten, also keine Tiefe. Heißt : Ohne Texturen sieht man nur die Umrisse vor dem schwarzen Hintergrund. Wir haben unsere eigenen Objekte drinne, das läuft auch. Aber zum Beispiel Furchen in einem Quader sieht man nicht.

Bisher haben wir schon nach richtigen Schatten gesucht, wobei das wohl zu weit geht. Uns würde einfache Tiefe ja reichen.

Ohne Texturen :





Mit Texturen :





Aber man sieht halt keine Ränder und nichts.


----------



## Guest2 (18. Nov 2012)

Moin,

ich vermute, Ihr sucht nicht wirklich Schatten, sondern erstmal Beleuchtung. Das reicht dann schon, um was erkennen zu können. Vermutlich benutzt Ihr die Fixed Function Pipeline, dann gibt es z.B. hier einen Überblick.

Viele Grüße,
Fancy


----------



## Marco13 (19. Nov 2012)

Ja, man nennt das, was ihr sucht, "Körperschatten" (im Vergleich zu Schlagschatten, die beliebig aufwändig zu berechnen sind). Eigentlich braucht man für die Körperschatten in OpenGL nicht viel: 1. Licht und 2. Normalen. Der Link sollte die meisten Fragen beantworten.


----------



## Pommes9485 (19. Nov 2012)

AH! Danke! Wir wussten nicht, dass OpenGL die Normalen zur Lichtberechnung benutzt.
Wir haben uns einen eigenen .obj Loader geschrieben und haben aus Faulheit die Normalen nicht mit eingelesen.


----------



## Pommes9485 (19. Jan 2013)

So, einige Zeit ist vergangen und wir beide haben uns mittlerweile an ein anderes Projekt gemacht.
Dabei haben wir halt einfach nur Blöcke benutzt. Die Normalen haben wir diesmal auch direkt am Anfang hinzugefügt und es funktionierte auch. Wir haben daran nichts geändert, weder an den Normalen noch an der initGL Methode und doch haben wir plötzlich keine Körperschatten mehr. Habt ihr eine Idee, ob irgendein ferner Aufruf über 2 Ecken dies verursachen könnte ?
Hier unsere Init Methode :

```
private void initGL(){
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0);
    	GL11.glShadeModel(GL11.GL_SMOOTH);
    	GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glViewport(0,0,displayMode.getWidth(),displayMode.getHeight());
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f,(float) displayMode.getWidth() / (float) displayMode.getHeight(),0.1f,100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
        
    }
    private void initLight()
    {
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE);
        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        //Licht
        //GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(lightAmbient).flip());
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(lightAmbient).flip());              // Setup The Ambient Light
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(lightDiffuse).flip());              // Setup The Diffuse Light
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION,(FloatBuffer)temp.asFloatBuffer().put(lightPosition).flip());         // Position The Light
        //GL11.glLightf(GL11.GL_LIGHT1, GL11.GL_CONSTANT_ATTENUATION, 0.0f);
        //GL11.glLightf(GL11.GL_LIGHT1, GL11.GL_LINEAR_ATTENUATION, 0.002f);
        //GL11.glLightf(GL11.GL_LIGHT1, GL11.GL_QUADRATIC_ATTENUATION, 0.4f);
        GL11.glEnable(GL11.GL_LIGHT1);
    }
```
Das initLight() wird danach ausgeführt.


----------



## Pommes9485 (24. Jan 2013)

Mist, doppelt geklickt oder so :/


----------



## Pommes9485 (24. Jan 2013)

Also, hier der Render Code von dem Würfel :

```
GL11.glColor4f(1, 1, 1, 1);
		texture.bind();
    	          
		//Oben
	
		GL11.glNormal3f(0,1,0);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x+r,y+r,z+r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x-r,y+r,z+r);
		GL11.glTexCoord2f(0,0);
		GL11.glVertex3f(x-r,y+r,z-r);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x+r,y+r,z-r);
		//Unten
		GL11.glNormal3f(0,-1,0);
		//GL11.glTexCoord2f(texturePoints.get(tmp[0][1]).x, texturePoints.get(tmp[0][1]).y);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x+r,y-r,z+r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x-r,y-r,z+r);
		GL11.glTexCoord2f(0,0);
		GL11.glVertex3f(x-r,y-r,z-r);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x+r,y-r,z-r);
		// Hinten
		GL11.glNormal3f(0,0,-1);
		//GL11.glTexCoord2f(texturePoints.get(tmp[0][1]).x, texturePoints.get(tmp[0][1]).y);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x-r,y+r,z-r);
		GL11.glTexCoord2f(0f,0f);
		GL11.glVertex3f(x+r,y+r,z-r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x+r,y-r,z-r);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x-r,y-r,z-r);
		//Vorne
		GL11.glNormal3f(0,0,1);
		//GL11.glTexCoord2f(texturePoints.get(tmp[0][1]).x, texturePoints.get(tmp[0][1]).y);
		GL11.glTexCoord2f(0f,0f);
		GL11.glVertex3f(x-r,y+r,z+r);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x+r,y+r,z+r);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x+r,y-r,z+r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x-r,y-r,z+r);
		//Links
		GL11.glNormal3f(-1,0,0);
		//GL11.glTexCoord2f(texturePoints.get(tmp[0][1]).x, texturePoints.get(tmp[0][1]).y);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x-r,y+r,z+r);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x-r,y-r,z+r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x-r,y-r,z-r);
		GL11.glTexCoord2f(0f,0f);
		GL11.glVertex3f(x-r,y+r,z-r);
		//Rechts
		GL11.glNormal3f(1,0,0);
		//GL11.glTexCoord2f(texturePoints.get(tmp[0][1]).x, texturePoints.get(tmp[0][1]).y);
		GL11.glTexCoord2f(0f,0f);
		GL11.glVertex3f(x+r,y+r,z+r);
		GL11.glTexCoord2f(0f,1f);
		GL11.glVertex3f(x+r,y-r,z+r);
		GL11.glTexCoord2f(1f,1f);
		GL11.glVertex3f(x+r,y-r,z-r);
		GL11.glTexCoord2f(1f,0f);
		GL11.glVertex3f(x+r,y+r,z-r);
```

Aufrufen tun wir alles über eine Display List :

```
private void genList()
	{
        list = GL11.glGenLists(1);
        GL11.glNewList(list, GL11.GL_COMPILE);
        {
        	GL11.glBegin(GL11.GL_QUADS);
        	for(int x=0;x<(int)(gx/0.25f)-1;x++)
        	{
        		for(int z=0;z<(int)(gz/0.25f)-1;z++)
        		{
        			if(welt[x][z]!=null)
        			{
        				for(int y=0;y<welt[x][z].length;y++)
        				{
        					//System.out.println(x+" "+y+" "+z);
        					if(welt[x][z][y].gibSicht() && welt[x][z][y].gibZerstoert()==false)
        					{
        						welt[x][z][y].render();
        					}
        				}
        			}
        		}
        	}
        	GL11.glEnd();
        }
        GL11.glEndList();
        
	}
	public void render()
	{
		GL11.glCallList(list);
	}
```

Die Blöcke stehen in der Array Welt, die render Methode steht ja oben.
Wir haben eigentlich nichts daran geändert und trotzdem sehen wir nur einen weißen Fleck, wenn wir uns das Ergebnis ansehen.


----------



## Guest2 (24. Jan 2013)

Versuch mal ein KSKB draus zu machen.

Viele Grüße,
Fancy


----------



## Pommes9485 (24. Jan 2013)

Also, ich habe es als RAR verpackt hochgeladen, in dem Ordner ist es sehr unübersichtlich, momentan bekomme ich es aber nicht anders hin. Die beiden Datein SpielMitTextur und SpielOhneTextur starten das Spiel. Die Steuerung ist erfolgt über die Maus, wasd sowie e und q für das Bewegen auf der y-Achse.
Hier klicken.
Hoffe auf gute Antworten, ich bin am verzweifeln


----------



## Guest2 (24. Jan 2013)

Bei nem KSKB geht es hauptsächlich um den Quelltext. Ein kurzes Beispiel, das man schnell in seine IDE kopieren kann, die Fehler behebt und das Ergebnis wieder hier posten kann.

In Deinem RAR habe ich aber zumindest auf die schnelle keine Quelltexte gefunden.

Viele Grüße,
Fancy


----------



## Pommes9485 (24. Jan 2013)

Ok dann noch mal so abgespeckt wie möglich.
Man sieht auf eine Quadrat und von dem auf eine Spitze.
Das Licht ist direkt über der Sicht.

```
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
public class Show
{
    private int frames;
    private long time;
    private int fps=0;
    private float lightAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    private float lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    private float lightPosition[] = { 0.0f, 5.0f, 0.0f, 1.0f };
    private DisplayMode displayMode;
    private static int list;
	public Show()
	{
		 try
	        {
	            displayMode = org.lwjgl.util.Display.getAvailableDisplayModes(800,600,800,600,32,32,60,60)[0];
	            Display.setDisplayMode(displayMode);
	            Display.create();
	        } 
	        catch(LWJGLException e)
	        {
	            System.out.println(e.getMessage());
	        }
	        initGL();
	        initLight();
	        blockErzeugen(0,0,0,1);
	        time = System.currentTimeMillis();
	        while(!Display.isCloseRequested())
	        {
	        	//Spiel Zyklus
	            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
	            GL11.glLoadIdentity();
	            render();
	            Display.setTitle(""+fps);
	            Display.update();
	        }
	        Display.destroy();
	        System.exit(0);
	    }
	    public void fpsberechnen()
	    {
	    	frames++;	
	    	if(time+1000<=System.currentTimeMillis())
	    	{
	    		fps = frames;
	    		frames=0;
	    		time = System.currentTimeMillis();
	    	}
	    }
	    public void render()
	    {
	    	fpsberechnen();
			blockZeigen();
	    }
	    private void blockZeigen()
	    {
			GL11.glTranslatef(0, 0, -10);
			GL11.glRotatef(45, 1.0f, 0.0f, 0.0f);
			GL11.glRotatef(45, 0.0f, 1.0f, 0.0f);
			GL11.glCallList(list);
			GL11.glRotatef(-45, 0.0f, 1.0f, 0.0f);
			GL11.glRotatef(-45, 1.0f, 0.0f, 0.0f);
			GL11.glTranslatef(0, 0, 10);
	    }
	    private void initGL(){
	        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	        GL11.glClearDepth(1.0);
	    	GL11.glShadeModel(GL11.GL_SMOOTH);
	    	GL11.glEnable(GL11.GL_TEXTURE_2D);
	        GL11.glEnable(GL11.GL_DEPTH_TEST);
	        GL11.glEnable(GL11.GL_BLEND);
	        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
	        GL11.glDepthFunc(GL11.GL_LEQUAL);
	        GL11.glViewport(0,0,displayMode.getWidth(),displayMode.getHeight());
	        GL11.glMatrixMode(GL11.GL_PROJECTION);
	        GL11.glLoadIdentity();
	        GLU.gluPerspective(45.0f,(float) displayMode.getWidth() / (float) displayMode.getHeight(),0.1f,100.0f);
	        GL11.glMatrixMode(GL11.GL_MODELVIEW);
	        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
	        
	    }
	    private void blockErzeugen(float x, float y, float z,float r)
	    {
	    	list = GL11.glGenLists(1);
	        GL11.glNewList(list, GL11.GL_COMPILE);
	        {
	        	GL11.glBegin(GL11.GL_QUADS);
	        	GL11.glColor4f(1, 1, 1, 1);
		//Oben
	        	GL11.glNormal3f(0,1,0);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x+r,y+r,z+r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x-r,y+r,z+r);
	        	GL11.glTexCoord2f(0,0);
	        	GL11.glVertex3f(x-r,y+r,z-r);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x+r,y+r,z-r);
	        	//Unten
	        	GL11.glNormal3f(0,-1,0);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x+r,y-r,z+r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x-r,y-r,z+r);
	        	GL11.glTexCoord2f(0,0);
	        	GL11.glVertex3f(x-r,y-r,z-r);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x+r,y-r,z-r);
	        	// Hinten
	        	GL11.glNormal3f(0,0,-1);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x-r,y+r,z-r);
	        	GL11.glTexCoord2f(0f,0f);
	        	GL11.glVertex3f(x+r,y+r,z-r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x+r,y-r,z-r);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x-r,y-r,z-r);
	        	//Vorne
	        	GL11.glNormal3f(0,0,1);
	        	GL11.glTexCoord2f(0f,0f);
	        	GL11.glVertex3f(x-r,y+r,z+r);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x+r,y+r,z+r);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x+r,y-r,z+r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x-r,y-r,z+r);
	        	//Links
	        	GL11.glNormal3f(-1,0,0);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x-r,y+r,z+r);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x-r,y-r,z+r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x-r,y-r,z-r);
	        	GL11.glTexCoord2f(0f,0f);
	        	GL11.glVertex3f(x-r,y+r,z-r);
	        	//Rechts
	        	GL11.glNormal3f(1,0,0);
	        	GL11.glTexCoord2f(0f,0f);
	        	GL11.glVertex3f(x+r,y+r,z+r);
	        	GL11.glTexCoord2f(0f,1f);
	        	GL11.glVertex3f(x+r,y-r,z+r);
	        	GL11.glTexCoord2f(1f,1f);
	        	GL11.glVertex3f(x+r,y-r,z-r);
	        	GL11.glTexCoord2f(1f,0f);
	        	GL11.glVertex3f(x+r,y+r,z-r);
        		GL11.glEnd();
	        }
	        GL11.glEndList();
	    }
	    private void initLight()
	    {
	        GL11.glEnable(GL11.GL_LIGHTING);
	        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
	        GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE);
	        ByteBuffer temp = ByteBuffer.allocateDirect(16);
	        temp.order(ByteOrder.nativeOrder());
	        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(lightAmbient).flip());
	        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(lightDiffuse).flip());
	        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION,(FloatBuffer)temp.asFloatBuffer().put(lightPosition).flip());
	        GL11.glEnable(GL11.GL_LIGHT1);
	    }
	    public static void main(String[] args)
	    {
	    	new Show();
	    }
	}
```


----------



## Guest2 (25. Jan 2013)

Genau, das ist ein KSKB. Dann sieht man auch direkt, das das vor allem erstmal einfach verdammt hell ist. Der Würfel wird als rein weiß definiert und die Beleuchtung hat die Maximalwerte, dadurch ist halt alles einfach weiß. Du kannst mal andere Beleuchtungsparameter versuchen, wie etwa:


```
private final float lightAmbient[] = { 0.2f, 0.2f, 0.2f, 0.2f };
    private final float lightDiffuse[] = { 0.5f, 0.5f, 0.5f, 0.5f };
    private final float lightPosition[] = { 2.0f, 5.0f, 0.0f, 1.0f };
```

Viele Grüße
Fancy


----------



## Pommes9485 (25. Jan 2013)

Danke schön, es läuft !!!


----------

