# [LWJGL] BMP Textur wird nicht richtig dargestellt



## aptem (26. Dez 2012)

Hallo zusammen,

ich habe ein kleines Problem mit LWJGL und BMP-Texturen. Folgendes Video sollte mein Problem deutlich machen. Rechts seht ihr eine Variante in C++ und wie es richtig aussehen sollte. Rechts ist die LWJGL Variante. Ich weiß leider nicht woran es liegt, dass es mit LWJGL falsch gerendert wird. Ich vermute aber das es beim Laden des Bildes ein Problem gibt, da der Code mit dem von der C++ Variante identisch ist.

LWJGL Texturing BMP Problem - YouTube



Spoiler: Java BMP-Loader Code





```
public Texture loadTexture(String path) {
		Texture texture = null;
		ShortBuffer buffer = null;
		int width = 0;
		int height = 0;
		int offset = 0;
		
		File file = new File(path);
		if (file.exists()) {
			try {
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
				int cache[] = new int[4];
				
				bis.skip(10);
				readData(bis, cache);
				offset = parse(cache);
				bis.skip(4);
				readData(bis, cache);
				width = parse(cache);
				readData(bis, cache);
				height = parse(cache);
				
				cache = new int[width * height * 3];
				bis.mark(0);
				bis.reset();
				bis.skip(offset);
				readData(bis, cache);
				
				
				
				buffer = BufferUtils.createShortBuffer(cache.length);
				for(int i = 0;i < cache.length;i++) {
					buffer.put((short)cache[i]);
				}
				buffer.rewind();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			int id = glGenTextures();
			glBindTexture(GL_TEXTURE_2D, id);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer);

			System.out.println("Texture created -- width:[" + width + "px] height:[" + height + "px]");
			
			texture = new Texture(id);
		}

		return texture;
	}
```






Spoiler: C++ BMP-Loader Code





```
Texture* BmpTextureLoader::loadTexture(std::string path)
{
	GLuint textureId;

	std::ifstream inputFileStream;
	inputFileStream.open(path, std::ios_base::in | std::ios_base::binary);

	if(inputFileStream.good())
	{
		long fileSize;
		char* inputPuffer;

		int offset;
		int width;
		int height;
		int bitCount;
		GLubyte* data;

		inputFileStream.seekg(0, std::ios::end);
		fileSize = inputFileStream.tellg();
		inputPuffer = new char[fileSize];
		inputFileStream.seekg(0, std::ios::beg);
		inputFileStream.read(inputPuffer, fileSize);
		inputFileStream.close();
		std::string stringPuffer(inputPuffer, fileSize);
		std::stringstream inputRunner(stringPuffer);
		
		inputRunner.seekg(10, std::ios::beg);
		inputRunner.read(reinterpret_cast<char*>(&offset), 4);
		inputRunner.seekg(18, std::ios::beg);
		inputRunner.read(reinterpret_cast<char*>(&width), 4);
		inputRunner.seekg(22, std::ios::beg);
		inputRunner.read(reinterpret_cast<char*>(&height), 4);
		inputRunner.seekg(28, std::ios::beg);
		inputRunner.read(reinterpret_cast<char*>(&bitCount), 2);

		int dataSize = width * height * bitCount / 3;
		data = new GLubyte[dataSize];
		inputRunner.seekg(offset, std::ios::beg);
		inputRunner.read((char*)data, dataSize);

		glGenTextures(1, &textureId);
		glBindTexture(GL_TEXTURE_2D, textureId);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
		

		delete[](inputPuffer);
		delete[](data);
	}

	return new Texture(textureId);
}
```


----------



## Guest2 (26. Dez 2012)

Moin,

geht es Dir wirklich darum das BMP von Hand einzulesen und darzustellen oder "nur" darum, wie man vernünftig Texturen aus Bildern bauen kann? 

Wenn es allgemein ums Einlesen geht, könntest Du Dir z.B. dieses Beispiel ansehen.

Wenn es Dir wirklich ums Auseinanderbauen des BMPs geht, müsste man sich das noch mal genauer ansehen.

Viele Grüße,
Fancy


----------



## aptem (26. Dez 2012)

Ich versteh einfach nicht warum die Textur falsch gerendert wird. Ich habe im Debugger die Werte in C++ und Java stichprobenartig verglichen. Sieht sauber aus. Die Art wie gerendert wird ist bei beiden Varianten ebenfalls identisch. Ich check das einfach nicht.


----------



## Guest2 (26. Dez 2012)

Mir ist z.B. nicht klar, warum Du ein ShortBuffer verwendest? Für ein BGR-Pixel ist es zu klein und für einen einzelnen Wert zu groß.

Bau doch mal ein komplettes KSKB, dann lässt sich das einfacher ausprobieren.

Viele Grüße,
Fancy


----------



## jemandzehage (4. Jan 2013)

Hi,
Das Problem ist, dass du den Code nicht komplett übernommen hast. Im C++ Code steht ein GLbyte Array. Du verwendest aber ein Shortbuffer. Hier sollte eine bytebuffer Abhilfe schaffen. Wenn nicht, dann beschreibe mal genauer, was bei dir anders aussieht oder mach mal einen Screenshot. 

Gruß


----------



## aptem (20. Jan 2013)

Aber ein Byte kann doch nur Werte von -128 bis 128 aufnehmen und die RGB-Werte befinden sich im Bereich 0-255. Dann kann es doch nur mit einem ByteBuffer funktionieren.

Hier ein leicht zu kompilierendes Beispiel:



Spoiler





```
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import org.lwjgl.util.glu.GLU;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL15.*;

public class Test {
	
	private int width = 1024;
	private int height = 768;
	
	private int vertexBuffer, textureBuffer, normalBuffer, indexBuffer;
	private int texId;
	
	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,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[] textures = {1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f};
	private float[] normals  = {0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f};
	private int[] indices    = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35};
	private short[] texture = {255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255,};
	
	private FloatBuffer vBuffer;
	private FloatBuffer tBuffer;
	private FloatBuffer nBuffer;
	private IntBuffer iBuffer;
	private ShortBuffer sBuffer;
	
	private float angle = 0.0f;
	
	private long timeLastFrame = 0;
	
	public Test() {
		try {
			Display.setDisplayMode(new DisplayMode(width,height));
			Display.create();
			
			init();
			
			while(!Display.isCloseRequested()) {
				update(getDelta());
				render();
				Display.update();
			}
			
			Display.destroy();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
	}
	
	private int getDelta() {
		long time = Sys.getTime();
		int delta = (int)(time - timeLastFrame);
		timeLastFrame = time;
		return delta;
	}
	
	private void init() {
		glMatrixMode(GL_PROJECTION);
		glViewport(0, 0, Display.getWidth(), Display.getHeight());
		GLU.gluPerspective(45.0f, (float)Display.getWidth()/(float)Display.getHeight(), 1.0f, 500.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);
		
		vBuffer = BufferUtils.createFloatBuffer(vertices.length);
		vBuffer.put(vertices);
		vBuffer.rewind();
		vertexBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
		
		tBuffer = BufferUtils.createFloatBuffer(textures.length);
		tBuffer.put(textures.length);
		tBuffer.rewind();
		textureBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
		glBufferData(GL_ARRAY_BUFFER, tBuffer, GL_STATIC_DRAW);
		
		nBuffer = BufferUtils.createFloatBuffer(normals.length);
		nBuffer.put(normals);
		nBuffer.rewind();
		normalBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
		glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);
		
		iBuffer = BufferUtils.createIntBuffer(indices.length);
		iBuffer.put(indices);
		iBuffer.rewind();
		indexBuffer = glGenBuffers();
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);
		
		sBuffer = BufferUtils.createShortBuffer(texture.length);
		sBuffer.put(texture);
		sBuffer.rewind();
		texId = glGenTextures();
		glBindTexture(GL_TEXTURE_2D, texId);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, sBuffer);
	}
	
	private void update(int delta) {
		angle += (0.05f * delta);
	}
	
	private void render() {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(0, 1, 1, 0);
		glLoadIdentity();

		glPushMatrix();
		{
			glTranslatef(0, 0, -3);
			glRotatef(angle, 0, 1, 0);
			
			glBindTexture(GL_TEXTURE_2D, texId);
			
			glEnableClientState(GL_VERTEX_ARRAY);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glEnableClientState(GL_NORMAL_ARRAY);

			glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
			glVertexPointer(3, GL_FLOAT, 0, 0);
			glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
			glTexCoordPointer(3, GL_FLOAT, 0, 0);
			glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
			glNormalPointer(GL_FLOAT, 0, 0);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
			glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0);

			glDisableClientState(GL_VERTEX_ARRAY);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			glDisableClientState(GL_NORMAL_ARRAY);
		}
		glPopMatrix();
	}

	public static void main(String[] args) {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				Test t = new Test();
			}
		}).start();
		
	}
}
```




Die Textur sieht so aus...
|x0x0|
|0x0x|
|x0x0|
|0x0x|
...wobei die 'x' für Schwarz und '0' für Weiß stehen.

Bei mir ist der Würfel Lila.


----------



## JCODA (20. Jan 2013)

Spoiler: Klick





```
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
 
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
 
import org.lwjgl.util.glu.GLU;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL15.*;
 
public class Test {
    
    private int width = 1024;
    private int height = 768;
    
    private int vertexBuffer, textureBuffer, normalBuffer, indexBuffer;
    private int texId;
    
    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,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[] textures = {1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f};
    private float[] normals  = {0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,1.0f,-0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,-0.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f,-1.0f,0.0f,-0.0f};
    private int[] indices    = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35};
    private byte[] texture = {(byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF};
    
    private FloatBuffer vBuffer;
    private FloatBuffer tBuffer;
    private FloatBuffer nBuffer;
    private IntBuffer iBuffer;
    private ByteBuffer sBuffer;
    
    private float angle = 0.0f;
    
    private long timeLastFrame = 0;
    
    public Test() {
        try {
            Display.setDisplayMode(new DisplayMode(width,height));
            Display.create();
            
            init();
            
            while(!Display.isCloseRequested()) {
                update(getDelta());
                render();
                Display.update();
            }
            
            Display.destroy();
        } catch (LWJGLException e) {
            e.printStackTrace();
        }
    }
    
    private int getDelta() {
        long time = Sys.getTime();
        int delta = (int)(time - timeLastFrame);
        timeLastFrame = time;
        return delta;
    }
    
    private void init() {
        glMatrixMode(GL_PROJECTION);
        glViewport(0, 0, Display.getWidth(), Display.getHeight());
        GLU.gluPerspective(45.0f, (float)Display.getWidth()/(float)Display.getHeight(), 1.0f, 500.0f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        
        vBuffer = BufferUtils.createFloatBuffer(vertices.length);
        vBuffer.put(vertices);
        vBuffer.rewind();
        vertexBuffer = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
        
        tBuffer = BufferUtils.createFloatBuffer(textures.length);
        tBuffer.put(textures);
        tBuffer.rewind();
        textureBuffer = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
        glBufferData(GL_ARRAY_BUFFER, tBuffer, GL_STATIC_DRAW);
        
        nBuffer = BufferUtils.createFloatBuffer(normals.length);
        nBuffer.put(normals);
        nBuffer.rewind();
        normalBuffer = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
        glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);
        
        iBuffer = BufferUtils.createIntBuffer(indices.length);
        iBuffer.put(indices);
        iBuffer.rewind();
        indexBuffer = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);
        
        sBuffer = BufferUtils.createByteBuffer(texture.length);
        sBuffer.put(texture);
        sBuffer.rewind();
        texId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texId);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, sBuffer);
    }
    
    private void update(int delta) {
        angle += (0.05f * delta);
    }
    
    private void render() {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0, 1, 1, 0);
        glLoadIdentity();
 
        glPushMatrix();
        {
            glTranslatef(0, 0, -3);
            glRotatef(angle, 0, 1, 0);
            
            glBindTexture(GL_TEXTURE_2D, texId);
            
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glEnableClientState(GL_NORMAL_ARRAY);
 
            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
            glVertexPointer(3, GL_FLOAT, 0, 0);
            glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
            glTexCoordPointer(3, GL_FLOAT, 0, 0);
            glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
            glNormalPointer(GL_FLOAT, 0, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
            glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0);
 
            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisableClientState(GL_NORMAL_ARRAY);
        }
        glPopMatrix();
    }
 
    public static void main(String[] args) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                Test t = new Test();
            }
        }).start();
        
    }
}
```




Also dein KSKB war schon eine kleine Herausforderung... 


```
tBuffer = BufferUtils.createFloatBuffer(textures.length);
        tBuffer.put(textures.length);
        tBuffer.rewind();
```
Hat ne Weile gedauert, bis man das findet ^^,


----------



## jemandzehage (20. Jan 2013)

Hi, 

nach längerem basteln habe ich genau den gleichen Fehler gefunden, wie JCODA. Ich wollte dir noch ein paar Anmerkungen zu deinem Code geben: 

Wenn du Texturen erzeugst, dann solltest du darauf achten, dass das Array (bzw. der Buffer) in dem deine Bildwerte gespeichert sind auch den Typ hat, den du danach angibst. Wenn du z.B. Byte angibst, dann sollten das auch GL_BYTE sein. Des weiteren must du beachten, das GL_RGB nur dann funktioniert, wenn jeder Farbwert ein Byte groß ist und keine Offset hat. Durch die Verwendung von Shortbuffern erhältst du aber Offsets und es kommen seltsame Farben (wie z.B. Pink heraus). 

Wenn du in deinem Programm Zeiten misst, dann solltest du das in genauerer Abständen machen und als Float. Bei mir z.B. ist dein Programm mit 1500 FPS gelaufen, dann waren die Abstände für einen Integer in Millisekunden zu klein und der Würfel hat sich nicht gedreht. Dazu würde ich dir Empfehlen, Vsync anzuschalten, damit sich die Framerate an deine Hardware anpasst. 

Wenn du ein VBO verwendest und deinen Indizes von 0 bis 35 durchnummerierst, dann verwende besser keine Indizes. Das ist übersichtlicher und verbraucht keinen Speicher. 

Wenn du etwas Testen wilst, wie z.B. ob deine Textur ordentlich geladen wird, dann mache es wirklich mit einem KSKB. Also am besten einfach ein Quad mit einer Textur. Dann kannst du äußere Fehler minimieren und kannst sofort feststellen, was der Fehler ist. 

Btw: Ich hab alles, was ich oben geschrieben habe mal in deine Datei eingearbeitet (um mögliche Fragen vorzubeugen): 


```
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import org.lwjgl.util.glu.GLU;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

public class Test {

	private int width = 1024;
	private int height = 768;

	private int vertexBuffer, textureBuffer, normalBuffer;
	private int texId;

	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, 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[] textures = { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
			1.0f, 0.0f, 0.0f, 1.0f, 0.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, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
			1.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, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.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, 0.0f, 0.0f,
			1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
	private float[] normals = { 0.0f, -1.0f, -0.0f, 0.0f, -1.0f, -0.0f, 0.0f,
			-1.0f, -0.0f, 0.0f, -1.0f, -0.0f, 0.0f, -1.0f, -0.0f, 0.0f, -1.0f,
			-0.0f, 0.0f, 1.0f, -0.0f, 0.0f, 1.0f, -0.0f, 0.0f, 1.0f, -0.0f,
			0.0f, 1.0f, -0.0f, 0.0f, 1.0f, -0.0f, 0.0f, 1.0f, -0.0f, 0.0f,
			0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
			0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
			-0.0f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f, -0.0f,
			1.0f, 0.0f, -0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
			0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
			-1.0f, -1.0f, 0.0f, -0.0f, -1.0f, 0.0f, -0.0f, -1.0f, 0.0f, -0.0f,
			-1.0f, 0.0f, -0.0f, -1.0f, 0.0f, -0.0f, -1.0f, 0.0f, -0.0f };
	private byte[] texture = { (byte) 255, (byte) 255, (byte) 255, 0, 0, 0,
			(byte) 255, (byte) 255, (byte) 255, 0, 0, 0, 0, 0, 0, (byte) 255,
			(byte) 255, (byte) 255, 0, 0, 0, (byte) 255, (byte) 255,
			(byte) 255, (byte) 255, (byte) 255, (byte) 255, 0, 0, 0,
			(byte) 255, (byte) 255, (byte) 255, 0, 0, 0, 0, 0, 0, (byte) 255,
			(byte) 255, (byte) 255, 0, 0, 0, (byte) 255, (byte) 255,
			(byte) 255, };

	private FloatBuffer vBuffer;
	private FloatBuffer tBuffer;
	private FloatBuffer nBuffer;
	private ByteBuffer sBuffer;

	private float angle = 0.0f;

	private long timeLastFrame = 0;

	public Test() {
		timeLastFrame = System.nanoTime();

		try {
			Display.setDisplayMode(new DisplayMode(width, height));
			Display.setVSyncEnabled(true);
			Display.create();

			init();

			while (!Display.isCloseRequested()) {
				update(getDelta());
				render();
				Display.update();
			}

			Display.destroy();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
	}

	private float getDelta() {
		long time = System.nanoTime();
		long delta = time - timeLastFrame;
		timeLastFrame = time;
		return delta / 1000000f;
	}

	private void init() {
		glMatrixMode(GL_PROJECTION);
		glViewport(0, 0, Display.getWidth(), Display.getHeight());
		GLU.gluPerspective(45.0f,
				(float) Display.getWidth() / (float) Display.getHeight(), 1.0f,
				500.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		glEnable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);

		vBuffer = BufferUtils.createFloatBuffer(vertices.length);
		vBuffer.put(vertices);
		vBuffer.rewind();
		vertexBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);

		tBuffer = BufferUtils.createFloatBuffer(textures.length);
		//hier lag der Fehler!!
		tBuffer.put(textures);
		tBuffer.rewind();
		textureBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
		glBufferData(GL_ARRAY_BUFFER, tBuffer, GL_STATIC_DRAW);

		nBuffer = BufferUtils.createFloatBuffer(normals.length);
		nBuffer.put(normals);
		nBuffer.rewind();
		normalBuffer = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
		glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);

		sBuffer = BufferUtils.createByteBuffer(texture.length).put(texture);
		sBuffer.rewind();
		texId = glGenTextures();
		glBindTexture(GL_TEXTURE_2D, texId);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB,
				GL_UNSIGNED_BYTE, sBuffer);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	private void update(float delta) {
		angle += (0.05f * delta);
	}

	private void render() {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(0, 1, 1, 0);
		glLoadIdentity();

		glPushMatrix();
		{
			glTranslatef(0, 0, -3);
			glRotatef(angle, 0, 1, 0);

			glBindTexture(GL_TEXTURE_2D, texId);

			glEnableClientState(GL_VERTEX_ARRAY);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glEnableClientState(GL_NORMAL_ARRAY);

			glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
			glVertexPointer(3, GL_FLOAT, 0, 0);
			glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
			glTexCoordPointer(2, GL_FLOAT, 0, 0);
			glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
			glNormalPointer(GL_FLOAT, 0, 0);

			glDrawArrays(GL_TRIANGLES, 0, 36);

			glDisableClientState(GL_VERTEX_ARRAY);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			glDisableClientState(GL_NORMAL_ARRAY);
		}
		glPopMatrix();
	}

	public static void main(String[] args) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				new Test();
			}
		}).start();

	}
}
```


----------



## Guest2 (20. Jan 2013)

jemandzehage hat gesagt.:


> Wenn du ein VBO verwendest und deinen Indizes von 0 bis 35 durchnummerierst, dann verwende besser keine Indizes. Das ist übersichtlicher und verbraucht keinen Speicher.



Noch besser wäre es allerdings, die Indizes tatsächlich sinnvoll zu verwenden. Ohne die Indizes verliert man den Post Transform Cache. Zwar ist ein Würfel eine der schlechtesten Strukturen um den Cache sinnvoll auszunutzen, aber auch da werden pro Seite mit GL_TRIANGLES und ohne Cache 6 Vertices berechnet. Mit Cache sind es nur 4.

Hier mal eine Variante mit IBO, interleaved VBO, triangle strip, primitive restart und der GPU als Zeitgeber. Benötigt dann allerdings OpenGL 3.3, ist aber immer noch deprecated Fixed Function.


```
import static org.lwjgl.opengl.GL11.GL_CLAMP;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_LIGHT0;
import static org.lwjgl.opengl.GL11.GL_LIGHTING;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_NEAREST;
import static org.lwjgl.opengl.GL11.GL_NORMAL_ARRAY;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_RGB;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_COORD_ARRAY;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_SHORT;
import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glDrawElements;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glNormalPointer;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTexCoordPointer;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameterf;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertexPointer;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL15.glBindBuffer;
import static org.lwjgl.opengl.GL15.glBufferData;
import static org.lwjgl.opengl.GL15.glGenBuffers;
import static org.lwjgl.opengl.GL31.GL_PRIMITIVE_RESTART;
import static org.lwjgl.opengl.GL31.glPrimitiveRestartIndex;
import static org.lwjgl.opengl.GL32.glGetInteger64;
import static org.lwjgl.opengl.GL33.GL_TIMESTAMP;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;

public class Test {

    private static final short RESTART = (short) 0xFFFF;

    private static final short[] CUBE_IBO = new short[] {

        0, 1, 2, 3, RESTART,
        4, 5, 6, 7, RESTART,
        8, 9, 10, 11, RESTART,
        12, 13, 14, 15, RESTART,
        16, 17, 18, 19, RESTART,
        20, 21, 22, 23

    };

    // x, y, z, s, t, nx, ny, nz
    private static final float[] CUBE_VBO = new float[] {

        +1.0f, -1.0f, -1.0f, 1.0f, 0.0f, +0.0f, -1.0f, +0.0f,
        +1.0f, -1.0f, +1.0f, 1.0f, 1.0f, +0.0f, -1.0f, +0.0f,
        -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, +0.0f, -1.0f, +0.0f,
        -1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +0.0f, -1.0f, +0.0f,

        -1.0f, +1.0f, +1.0f, 0.0f, 1.0f, +0.0f, +1.0f, +0.0f,
        +1.0f, +1.0f, +1.0f, 1.0f, 1.0f, +0.0f, +1.0f, +0.0f,
        -1.0f, +1.0f, -1.0f, 0.0f, 0.0f, +0.0f, +1.0f, +0.0f,
        +1.0f, +1.0f, -1.0f, 1.0f, 0.0f, +0.0f, +1.0f, +0.0f,

        +1.0f, -1.0f, +1.0f, 1.0f, 0.0f, +0.0f, +0.0f, +1.0f,
        +1.0f, +1.0f, +1.0f, 1.0f, 1.0f, +0.0f, +0.0f, +1.0f,
        -1.0f, -1.0f, +1.0f, 0.0f, 0.0f, +0.0f, +0.0f, +1.0f,
        -1.0f, +1.0f, +1.0f, 0.0f, 1.0f, +0.0f, +0.0f, +1.0f,

        -1.0f, +1.0f, -1.0f, 0.0f, 1.0f, +0.0f, +0.0f, -1.0f,
        +1.0f, +1.0f, -1.0f, 1.0f, 1.0f, +0.0f, +0.0f, -1.0f,
        -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, +0.0f, +0.0f, -1.0f,
        +1.0f, -1.0f, -1.0f, 1.0f, 0.0f, +0.0f, +0.0f, -1.0f,

        -1.0f, -1.0f, +1.0f, 0.0f, 1.0f, -1.0f, +0.0f, +0.0f,
        -1.0f, +1.0f, +1.0f, 1.0f, 1.0f, -1.0f, +0.0f, +0.0f,
        -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, +0.0f, +0.0f,
        -1.0f, +1.0f, -1.0f, 1.0f, 0.0f, -1.0f, +0.0f, +0.0f,

        +1.0f, +1.0f, -1.0f, 1.0f, 0.0f, +1.0f, +0.0f, +0.0f,
        +1.0f, +1.0f, +1.0f, 1.0f, 1.0f, +1.0f, +0.0f, +0.0f,
        +1.0f, -1.0f, -1.0f, 0.0f, 0.0f, +1.0f, +0.0f, +0.0f,
        +1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, +0.0f, +0.0f,

    };

    // r, g, b
    private static final byte[] TEXTURE = {
        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00,
        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00,
        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };


    private static final int FLOAT_SIZE = Float.SIZE / Byte.SIZE;

    private static final double NANO_TO_MILLI = 1 / 1000000.0;

    private static final int WIDTH = 1024;
    private static final int HEIGHT = 768;

    private int vbo;
    private int ibo;
    private int texId;

    private long lastTime;

    private double angle = 0.0f;


    public Test() {

        try {

            final DisplayMode displayMode = new DisplayMode(WIDTH, HEIGHT);
            final PixelFormat pixelFormat = new PixelFormat().withSamples(4);

            Display.setDisplayMode(displayMode);
            Display.create(pixelFormat);

        } catch (final LWJGLException e) {

            e.printStackTrace();
            System.exit(1);

        }
    }


    public void run() {

        initGL();

        while (!Display.isCloseRequested()) {

            render();

            Display.update();

        }

    }


    public void dispose() {

        Display.destroy();

    }


    private void initGL() {

        glMatrixMode(GL_PROJECTION);
        GLU.gluPerspective(45.0f, (float) Display.getWidth() / (float) Display.getHeight(), 1.0f, 500.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_TEXTURE_2D);

        glEnable(GL_PRIMITIVE_RESTART);
        glPrimitiveRestartIndex(0xFFFF & RESTART);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);

        final FloatBuffer vboBuffer = BufferUtils.createFloatBuffer(CUBE_VBO.length);
        vboBuffer.put(CUBE_VBO);
        vboBuffer.rewind();
        vbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vboBuffer, GL_STATIC_DRAW);

        final ShortBuffer iboBuffer = BufferUtils.createShortBuffer(CUBE_IBO.length);
        iboBuffer.put(CUBE_IBO);
        iboBuffer.rewind();
        ibo = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, iboBuffer, GL_STATIC_DRAW);

        final ByteBuffer textureBuffer = BufferUtils.createByteBuffer(TEXTURE.length);
        textureBuffer.put(TEXTURE);
        textureBuffer.rewind();
        texId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texId);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, textureBuffer);

    }


    private void render() {

        final long currentTime = glGetInteger64(GL_TIMESTAMP);
        final long deltaTime = currentTime - lastTime;
        lastTime = currentTime;
        angle += deltaTime * NANO_TO_MILLI * 0.05;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0, 1, 1, 0);
        glLoadIdentity();

        glTranslatef(0, 0, -5);
        glRotatef((float) angle, 0, 1, 0);

        glBindTexture(GL_TEXTURE_2D, texId);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexPointer(3, GL_FLOAT, 8 * FLOAT_SIZE, 0 * FLOAT_SIZE);
        glTexCoordPointer(2, GL_FLOAT, 8 * FLOAT_SIZE, 3 * FLOAT_SIZE);
        glNormalPointer(GL_FLOAT, 8 * FLOAT_SIZE, 5 * FLOAT_SIZE);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glDrawElements(GL_TRIANGLE_STRIP, CUBE_IBO.length, GL_UNSIGNED_SHORT, 0);

    }


    public static void main(final String[] args) {

        new Thread(new Runnable() {

            @Override
            public void run() {

                final Test test = new Test();

                test.run();
                test.dispose();

            }

        }).start();

    }

}
```

Viele Grüße
Fancy


----------

