# OpenGL - Texture falsch herum



## Oneric (6. Okt 2013)

Hi

ich bin gerade dabei ein Grundgerüst für ein Projekt mit OpenGL aufzubauen.
Da ich mich aber schon länger nicht mehr mit OpenGL beschäftigt habe gibts erwartungsgemäß ein paar Probleme.
Ich habe eine Methode zum Laden von Texturen (auch nicht-"power of two") erstellt und zum testen eine Texture auf ein Quadrat gemappt.
Seltsamerweise ist die Texture jetzt aber falsch herum.

Hier ist das Ergebnis:






Hier das eigentliche Bild:





Und hier mein Code:

Hauptklasse:


Spoiler: Code





```
package oneric.level.main;

import java.io.File;
import java.io.IOException;

import oneric.importer.obj.Model;
import oneric.importer.obj.OBJLoader;
import oneric.util.GLHelper;


//import org.lwjgl.opengl.GL11;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;

import static org.lwjgl.opengl.GL11.*;

public class Main {

	private static Level level;
	
	static int[] ids;
	static int length;
	static int textureID;
	
	public static void main(String[] args) {
		
		setUpDisplay();
		setUpOpenGL();
		
		level = loadLevel("res/Level.lev"); //NIcht wichtig, ist noch nicht gecoded
		
		
		try {
			Model mod = OBJLoader.loadModel(new File("res/Landscape.obj")); // Wird auch noch nicht verwendet
			ids = OBJLoader.createVBO(mod);
			length = mod.faces.size() * 3;

			textureID = GLHelper.loadImage("res/16.png");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		while(!Display.isCloseRequested())
		{
			render();
			
			Display.update();
			Display.sync(120);
		}

	}
	
	
	public static Level loadLevel(String location)
	{
		return null;
	}
	
	
	/**
	 * Sets up the Display
	 * */
	private static void setUpDisplay() {
		
        try {
        	
            Display.setDisplayMode(/*Display.getDesktopDisplayMode()*/new DisplayMode(640, 360));
            Display.setVSyncEnabled(true);
            Display.setTitle("Level: ");
            //Display.setFullscreen(true);
            Display.create();
        } catch (LWJGLException e) {
            System.err.println("The display wasn't initialized correctly. :(");
            Display.destroy();
            System.exit(1);
        }
    }
	
	/**
	 * Sets up OpenGl so it's ready to use
	 * */
	private static void setUpOpenGL()
    {
    	
    	GL11.glShadeModel(GL11.GL_SMOOTH);
    	GL11.glEnable(GL11.GL_DEPTH_TEST);
    	GL11.glEnable(GL11.GL_LIGHTING);
    	GL11.glEnable(GL11.GL_LIGHT0);
    	
    	//GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, asFlippedFloatBuffer(new float[]{0.05f, 0.05f, 0.05f, 1f}));
    	//GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, asFlippedFloatBuffer(new float[]{1.0F, 1.0F, 1.0F,1F}));
    	GL11.glEnable(GL11.GL_CULL_FACE);
    	GL11.glCullFace(GL11.GL_BACK);
    	GL11.glEnable(GL11.GL_COLOR_MATERIAL);
    	GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE);
    	
    	glEnable(GL_TEXTURE_2D);
    	
    }
	
	
	private static void render()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        
        glEnable(GL_TEXTURE_2D);
        
        
        glBindTexture(GL_TEXTURE_2D, textureID);
		GL11.glBegin(GL11.GL_QUADS);
		//glColor3f(1F, 0, 0);
		glTexCoord2f(0, 0);
		glVertex2f(-1F, -1F);
		
		//glColor3f(0, 1F, 0);
		glTexCoord2f(1, 0);
		glVertex2f(1F, -1F);
		
		//glColor3f(0, 0, 1F);
		glTexCoord2f(1, 1);
		glVertex2f(1F, 1F);
		
		//glColor3f(0, 1, 1F);
		glTexCoord2f(0, 1);
		glVertex2f(-1, 1);
		
		GL11.glEnd();
        
        
	}
	
	
	
	

}
```




Und hier die "GLHelper" Klasse:


Spoiler: Code





```
package oneric.util;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;



import java.nio.ByteBuffer;
import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL12;

import static org.lwjgl.opengl.GL11.*;

public class GLHelper {
	
	public static int loadImage(BufferedImage img)
	{
		long l;
		System.out.println((l = System.currentTimeMillis()));
		/**byte[] imgData = ((DataBufferByte)img.getRaster().getDataBuffer()).getData();
		byte[] buffer =  new byte[(img.getWidth() * img.getHeight() * 4) + 1];
		System.out.println("Width: "+ img.getWidth() + " --- Height:  " + img.getHeight());		
		for(int i = 0; i < imgData.length; i+=4)
		{
			buffer[i] = imgData[i+2];   // Rot
			buffer[i+1] = imgData[i+1]; // Gruen
			buffer[i+2] = imgData[i];   // Blau
			buffer[i+3] = (byte) 255;    // Alpha
		}
		
		ByteBuffer textureData = ByteBuffer.allocateDirect(buffer.length); 
        textureData.order(ByteOrder.nativeOrder()); 
        textureData.put(buffer, 0, buffer.length); 
        textureData.flip();*/

		 
		int[] pixels = new int[img.getWidth() * img.getHeight()];
		    img.getRGB(0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth());

		    ByteBuffer buffer = BufferUtils.createByteBuffer(img.getWidth() * img.getHeight() * 4);
		    Color c;

		    for (int y = 0; y < img.getHeight(); y++) {
		        for (int x = 0; x < img.getWidth(); x++) {
		            c = new Color(img.getRGB(x, y));
		            buffer.put((byte) c.getRed());     // Red component
		            buffer.put((byte) c.getGreen());      // Green component
		            buffer.put((byte) c.getBlue());               // Blue component
		            buffer.put((byte) c.getAlpha());    // Alpha component. Only for RGBA
		        }
		    }

        buffer.flip();
        
        
        int id = glGenTextures(); //Generate texture ID
        glBindTexture(GL_TEXTURE_2D, id); //Bind texture ID

        //Setup wrap mode
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);

        //Setup texture scaling filtering
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        //Send texel data to OpenGL
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.getWidth(), img.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

        
        long l2;
        System.out.println((l2 = System.currentTimeMillis()) + "  diference = " + (l2 - l));
        
        return id;
		
	}
	
	public static int loadImage(File f) throws IOException
	{
		return loadImage(ImageIO.read(f));
	}
	
	public static int loadImage(String path) throws IOException
	{
		return loadImage(new File(path));
	}

}
```




AUßerdem habe ich in Erinnerung das im moderenen OpenGL eigentlich keine Wrap-Modes und Scaling Modes mehr einzeln für jedes Bild festgelegt werden. Also das der "//Setup wrap mode" und der "//Setup texture scaling filtering" eigentlich weg könnte. wenn ich diese aber weglasse funktioniert nichts.
Täusche ich mich da ?

Mfg,

Oneric


----------



## Hestalon (6. Okt 2013)

Wird denke daran liegen, dass Texturen immer mit der linken oberen Ecke (0,0) und rechte untere Ecke (1,1) angegeben werden.
Im Gegensatz dazu dein Quadrat so wies aussieht mit der linken unteren Ecke (-1,-1) und rechts oben (1,1), wie man es aus einem normalen KO-System kennt.

Gruß


----------



## Oneric (6. Okt 2013)

Hestalon hat gesagt.:


> Wird denke daran liegen, dass Texturen immer mit der linken oberen Ecke (0,0) und rechte untere Ecke (1,1) angegeben werden.
> Im Gegensatz dazu dein Quadrat so wies aussieht mit der linken unteren Ecke (-1,-1) und rechts oben (1,1), wie man es aus einem normalen KO-System kennt.
> 
> Gruß



Laut den Tuts und Bildern, die ich bei Google gefunden habe ist (0|0) die Untere linke Ecke der Textur.
Aber bei Direct X ist es glaube ich die linke obere Ecke.


----------



## Oneric (7. Okt 2013)

Also ich habe mir das jetzt mal auf der Website von LWJGL angeschaut und dort ist tatsächlich (0|0) oben links. :O
Weshalb es anscheinend bei manchen anderen OpenGL Libarys anders ist, ist mir schleierhaft.

Egal, ich würde sagen das Thema ist erledigt 

MfG,

~Oneric


----------

