# LWJGL - Ungewolltes Backface Culling?



## Fu3L (12. Jan 2012)

Hallo,

ich spiele nun auch mit LWJGL rum und stoße hier auf das Problem, dass mindestens eine, je nach Blickwinkel auch 2 Seiten meines Würfels nicht angezeigt werden. Die Koordinatenanordnung habe ich weitgehend aus einem Tutorial übernommen (da war für jeden Eckpunkt ein glVertex3f aufruf im Quelltext geschrieben) und sie scheinen mir richtig. Beim Zeichnen habe ich die Reihenfolge mit der jedes Quad gezeichnet wird auch schon einmal umgedreht (Bei der JMonkeyEngine half das mal^^), aber hier halfs nix. (siehe den auskommentierten Teil in Box.draw())
Die Kamera ist aus diesem Tutorial übernommen und ergänzt.

Ich hoffe euch fällt was auf 


```
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glTexCoord2f;
import static org.lwjgl.opengl.GL11.glVertex3f;

import java.util.Random;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector3f;

public class Box {

	private Vector3f trans;
	private Vector3f scale;

	private float[][] vertices = { { -0.5f, -0.5f, 0.5f }, { 0.5f, -0.5f, 0.5f }, { 0.5f, 0.5f, 0.5f }, { -0.5f, 0.5f, 0.5f },
			{ -0.5f, -0.5f, -0.5f }, { -0.5f, 0.5f, -0.5f }, { 0.5f, 0.5f, -0.5f }, { 0.5f, -0.5f, -0.5f },
			{ -0.5f, 0.5f, -0.5f }, { -0.5f, 0.5f, 0.5f }, { 0.5f, 0.5f, 0.5f }, { 0.5f, 0.5f, -0.5f },
			{ -0.5f, -0.5f, -0.5f }, { 0.5f, -0.5f, -0.5f }, { 0.5f, -0.5f, 0.5f }, { -0.5f, -0.5f, 0.5f },
			{ 0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }, { 0.5f, -0.5f, 0.5f },
			{ -0.5f, -0.5f, -0.5f }, { -0.5f, -0.5f, 0.5f }, { -0.5f, 0.5f, 0.5f }, { -0.5f, 0.5f, -0.5f } };

	private float[][] texCoords = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f },
			{ 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }, { 0.0f, 0.0f },
			{ 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f },
			{ 1.0f, 1.0f }, { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 0.0f },
			{ 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }, { 0.0f, 0.0f },
			{ 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } };

	//***********
	//CONSTRUCTOR
	//***********
	public Box(float x, float y, float z, float scale) {
		this.trans = new Vector3f(x, y, z);
		this.scale = new Vector3f(scale, scale, scale);
	} //End Constructor

	public void draw() {
		glBegin(GL_QUADS);
		Random rnd = new Random(0);
		/*for(int x = 3; x < vertices.length; x += 4) {
			for(int i = 0; i <= 3; i++) {
				GL11.glColor3f(rnd.nextFloat(), rnd.nextFloat(), rnd.nextFloat());
				glTexCoord2f(texCoords[x - i][0], texCoords[x - i][1]);
				glVertex3f(vertices[x - i][0] * scale.x, vertices[x - i][1] * scale.y, vertices[x - i][2] * scale.z);
			}*/
		for(int x = 0; x < vertices.length; x++) {
			GL11.glColor3f(rnd.nextFloat(), rnd.nextFloat(), rnd.nextFloat());
			glTexCoord2f(texCoords[x][0], texCoords[x][1]);
			glVertex3f(vertices[x][0] * scale.x, vertices[x][1] * scale.y, vertices[x][2] * scale.z);
		}
		glEnd();
	}
} //End Box
```


```
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class Boxes {

	FPCamera cam = new FPCamera(0, 0, -5);
	Box b = new Box(0, 0, 0, 2);
	boolean running = true;

	//***********
	//CONSTRUCTOR
	//***********
	public Boxes() {
		this.initDisplay();
		this.initControls();
	} //End Constructor

	//****
	//INIT
	//****
	private void initDisplay() {
		try {
			Display.setDisplayMode(new DisplayMode(500, 500));
			Display.create();
		} catch (LWJGLException ex) {
			ex.printStackTrace();
		}
		/*GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, 2, 2, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);*/
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		GLU.gluPerspective(60, 500 / 500, 0, 200);
		glMatrixMode(GL_MODELVIEW);
	} //End initDisplay

	private void initControls() {
		Mouse.setGrabbed(true);
	}

	//****
	//LOOP
	//****
	public void loop() {
		float dx = 0.0f;
		float dy = 0.0f;
		float dt = 0.0f;
		float lastTime = 0.0f;
		float time = 0.0f;
		while(!Display.isCloseRequested() && running) {
			this.listen();
			float mouseSensitivity = 0.1f;
			float movementSpeed = 10.0f;
			time = Sys.getTime();
			dt = (time - lastTime) / 1000.0f;
			lastTime = time;

			dx = Mouse.getDX();
			dy = Mouse.getDY();

			cam.yaw(dx * mouseSensitivity);
			cam.pitch(dy * mouseSensitivity);

			if(Keyboard.isKeyDown(Keyboard.KEY_W)) {
				cam.walkForward(movementSpeed * dt);
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_S))
			{
				cam.walkBackwards(movementSpeed * dt);
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_A))
			{
				cam.strafeLeft(movementSpeed * dt);
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_D))
			{
				cam.strafeRight(movementSpeed * dt);
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))
			{
				cam.moveUp(movementSpeed * dt);
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
			{
				cam.moveDown(movementSpeed * dt);
			}

			GL11.glLoadIdentity();
			cam.lookThrough();
			this.render();
			try {
				Thread.sleep(10);
			} catch (InterruptedException ex) {
				//Nothing
			}
		}
		Display.destroy();
	} //End loop()

	//*****
	//INPUT
	//*****
	private void listen() {
		while(Keyboard.next()) {
			if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
				running = false;
			}
		}
	}

	//*********
	//RENDERING
	//*********
	private void render() {
		Display.update();
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		GL11.glColor3f(0.0f, 1, 1);
		b.draw();
	}

	//****
	//MAIN
	//****
	public static void main(String[] args) {
		new Boxes().loop();
	}

}
```


```
public class FPCamera {

	//3d vector to store the camera's position in
	private Vector3f position = null;
	//the rotation around the Y axis of the camera
	private float yaw = 0.0f;
	//the rotation around the X axis of the camera
	private float pitch = 0.0f;

	public FPCamera(float x, float y, float z) {
		//instantiate position Vector3f to the x y z params.
		position = new Vector3f(x, y, z);
	}

	//increment the camera's current yaw rotation
	public void yaw(float amount)
	{
		//increment the yaw by the amount param
		yaw += amount;
	}

	//increment the camera's current pitch rotation
	public void pitch(float amount)
	{
		//increment the pitch by the amount param
		pitch -= amount;
	}

	//moves the camera forward relative to its current rotation (yaw)
	public void walkForward(float distance)
	{
		position.x -= distance * (float) Math.sin(Math.toRadians(yaw));
		position.z += distance * (float) Math.cos(Math.toRadians(yaw));
	}

	//moves the camera backward relative to its current rotation (yaw)
	public void walkBackwards(float distance)
	{
		position.x += distance * (float) Math.sin(Math.toRadians(yaw));
		position.z -= distance * (float) Math.cos(Math.toRadians(yaw));
	}

	//strafes the camera left relitive to its current rotation (yaw)
	public void strafeLeft(float distance)
	{
		position.x -= distance * (float) Math.sin(Math.toRadians(yaw - 90));
		position.z += distance * (float) Math.cos(Math.toRadians(yaw - 90));
	}

	//strafes the camera right relitive to its current rotation (yaw)
	public void strafeRight(float distance)
	{
		position.x -= distance * (float) Math.sin(Math.toRadians(yaw + 90));
		position.z += distance * (float) Math.cos(Math.toRadians(yaw + 90));
	}

	public void moveUp(float distance)
	{
		position.y -= distance;

	}

	public void moveDown(float distance)
	{
		position.y += distance;
	}

	//translates and rotate the matrix so that it looks through the camera
	//this dose basic what gluLookAt() does
	public void lookThrough()
	{
		//roatate the pitch around the X axis
		GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
		//roatate the yaw around the Y axis
		GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
		//translate to the position vector's location
		GL11.glTranslatef(position.x, position.y, position.z);
	}

}
```


----------



## Evil-Devil (12. Jan 2012)

Backface Culling ist im Normalfall immer aktiv. Du kannst es testweise deaktivieren oder setzen ob Front- bzw. Backface geculled werden sollen.


----------



## Fu3L (12. Jan 2012)

Mhh, ein 

```
GL11.glDisable(GL11.GL_CULL_FACE);
```
in der initDisplay()-Methode hat auch nichts gebracht.
Also wird es nicht am Backface-Culling liegen, dass meine Box irgendwie nicht funktioniert?


----------



## Guest2 (12. Jan 2012)

Moin,

am BackFaceCulling liegt das nicht. Du must einfach den DepthTest aktivieren. Das BackFaceCulling kann aber auch nicht schaden (alle Seiten sind korrekt orientiert / es scheint bei LWJGL auch nicht default zu sein). 

Außerdem darf die zNearPlane nicht 0 sein.


```
GL11.glClearDepth(1.0f);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glEnable(GL11.GL_CULL_FACE);

[..]

GLU.gluPerspective(60, 500 / 500, 0.1f, 200);
```

Dann geht es.

Viele Grüße,
Fancy


----------



## Fu3L (12. Jan 2012)

Vielen Dank Fancy  Funktioniert so wunderbar


----------



## Kr0e (12. Jan 2012)

Fancy, du bist voll der gott, ohne Witz  Ein wandelndes OpenGL Lexikon! (Hatte aus Zufall nämlihc letztes ein ähnlcihes Problem)


----------



## Guest2 (12. Jan 2012)

lol 

Viele Grüße,
Fancy


----------

