New to lwjgl, help with textures

hi guys,
Im new to lwjgl and have been havin problems loading in png’s. I have tryed using slick and a pngdecoder(think it was called fastpng) but they both had the same outcome. The displayed texture wasnt correct as it changed all of the colors from the original png to greenish shades.
Do you know why this might be happening? have been using 256 png8s for these tests.

What i want to do is load pngs of size 256 or 512 idealy greater than png8 so i can have more use of transparency and not just clear or not(hope ive phased that well enough)
Do you know of a good way of doing this or just for png8s? or do you know of any good librarys that will take care of this for me?

Any help would be appreciated,

thanks, dano

both the above libraries should be able to load the png file correctly. Either there is a bug in your code or something wrong with your image.

Can you post your code or the image?

thanks

here is the code

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import net.sourceforge.fastpng.PNGDecoder;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;


public class Main {
  public static final int DISPLAY_HEIGHT = 800;
  public static final int DISPLAY_WIDTH = 800;
  public static final Logger LOGGER = Logger.getLogger(Main.class.getName());

  private int squareSize;
  private int squareX;
  private int squareY;
  private int squareZ;

  private int tex01=0;//first texture

  static {
    try {
      LOGGER.addHandler(new FileHandler("errors.log",true));
    }
    catch(IOException ex) {
      LOGGER.log(Level.WARNING,ex.toString(),ex);
    }
  }

  public static void main(String[] args) {
    Main main = null;
    try {
      System.out.println("Keys:");
      System.out.println("down  - Shrink");
      System.out.println("up    - Grow");
      System.out.println("left  - Rotate left");
      System.out.println("right - Rotate right");
      System.out.println("esc   - Exit");

      

      main = new Main();
      main.create();
      main.run();
    }
    catch(Exception ex) {
      LOGGER.log(Level.SEVERE,ex.toString(),ex);
    }
    finally {
      if(main != null) {
        main.destroy();
      }
    }
  }

  public Main() throws IOException {
    squareSize = 100;
    squareX = 0;
    squareY = 0;
    squareZ = 0;
    
  }

  public void create() throws LWJGLException, FileNotFoundException {
        try {
            //Display
            Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH, DISPLAY_HEIGHT));
            Display.setFullscreen(false);
            Display.setTitle("Hello LWJGL World!");
            Display.create();
            
            //Keyboard
            Keyboard.create();
            //Mouse
            Mouse.setGrabbed(false);
            Mouse.create();
            //OpenGL
            initGL();
            resizeGL();
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
  }

  public void destroy() {
    //Methods already check if created before destroying.
    Mouse.destroy();
    Keyboard.destroy();
    Display.destroy();
  }

  public void initGL() throws FileNotFoundException, IOException {
    //2D Initialization
   glEnable(GL_TEXTURE_2D);

		

		glDisable(GL_DEPTH_TEST);
		glDisable(GL_LIGHTING);

		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClearDepth(1);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glViewport(0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
		glMatrixMode(GL_MODELVIEW);

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, DISPLAY_WIDTH,DISPLAY_HEIGHT, 0, 1, -1);
		glMatrixMode(GL_MODELVIEW);
                glEnable(GL_RGBA8);
                
                
                tex01=setupTextures("test2.png");
            

    
  }

  private int setupTextures(String filename){
IntBuffer tmp=BufferUtils.createIntBuffer(1);
GL11.glGenTextures(tmp);
tmp.rewind();
try {
InputStream in = new FileInputStream(filename);
PNGDecoder decoder=new PNGDecoder(in);
ByteBuffer
data=ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
decoder.decode(data, decoder.getWidth()*4, PNGDecoder.TextureFormat.RGBA);
data.rewind();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, tmp.get(0));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
GL11.GL_NEAREST);

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA,
decoder.getWidth(), decoder.getHeight(), 0, GL11.GL_RGBA,
GL11.GL_UNSIGNED_BYTE, data);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4);
} catch (FileNotFoundException ex) {
System.out.println("Error " + filename + " not found");
}catch(IOException e){
System.out.println("Error decoding " + filename );
}
tmp.rewind();
return tmp.get(0);
    }

  public void processKeyboard() {
    //Square's Size
    if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
      --squareSize;
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_UP)) {
      ++squareSize;
    }

    //Square's Z
    if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
      ++squareZ;
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
      --squareZ;
    }
  }

  public void processMouse() {
    squareX = Mouse.getX();
    squareY = Mouse.getY();
  }

  public void render() {
      
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();


glBindTexture(GL_TEXTURE_2D, tex01);
    glBegin(GL_QUADS);
      glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,0.0f);
      glTexCoord2f(1.0f,0.0f); glVertex2f(squareSize,0.0f);
      glTexCoord2f(1.0f,1.0f); glVertex2f(squareSize,squareSize);
      glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f,squareSize);
    glEnd();


    //Draw a basic square
    glTranslatef(squareX,squareY,0.0f);
    glRotatef(squareZ,0.0f,0.0f,1.0f);
    glTranslatef(-(squareSize >> 1),-(squareSize >> 1),0.0f);
    glColor3f(0.0f,0.5f,0.5f);
    
    glBegin(GL_QUADS);
      glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,0.0f);
      glTexCoord2f(1.0f,0.0f); glVertex2f(squareSize,0.0f);
      glTexCoord2f(1.0f,1.0f); glVertex2f(squareSize,squareSize);
      glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f,squareSize);
    glEnd();
    
    
  }

  public void resizeGL() {
    //2D Scene
    glViewport(0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
    glEnable(GL_TEXTURE_2D);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0f,DISPLAY_WIDTH,0.0f,DISPLAY_HEIGHT);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
  }

  public void run() {
    while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
      if(Display.isVisible()) {
        processKeyboard();
        processMouse();
        update();
        render();
      }
      else {
        if(Display.isDirty()) {
          render();
        }
        try {
          Thread.sleep(100);
        }
        catch(InterruptedException ex) {
        }
      }
      Display.update();
      Display.sync(60);
    }
  }

  public void update() {
    if(squareSize < 5) {
      squareSize = 5;
    }
    else if(squareSize >= DISPLAY_HEIGHT) {
      squareSize = DISPLAY_HEIGHT;
    }
  }
}

this code is for the fastpng lib code for that is in setupTexture and initgl

And here is the pic i have been using, all colors go to a greenish color http://dl.dropbox.com/u/3978815/test2.png

cheers

Everything green or pink = byte order is wrong.

Cas :slight_smile:

Do you mean when its loaded in its not in rgba format?
what would be the best way to fix this?

cheers

edit:

done some tests and the first number of every pixal is wrong in the buffer e.g put red corner on pic so the first pixal should of been 186,44,38,0 but when i looked it was read in as -70,44,38,-1 the alpha being -1 i dont think is a problem but the red number is 256 off.

Has anyone else experienced this problem with fastpng lib? or could offer a solution to this?

cheers

void really did a great job with fastpng, eh? :smiley:

FWIW, this is the PNG decoder to use.

There is also a simple working example on using the slick-util library here. It shows you how to load an image and you should try it to see if the problem is with the library or your code.

Probably good to try slick-util as it will most likely work, but AFAIK Slick uses an old version of PNGDecoder. fastpng is also an old version.

Keep in mind that it’s loading unsigned byte data into a signed byte (since Java can’t do unsigned). When you make the opengl texture calls, you correctly say UNSIGNED_BYTE, it’s only that printing it in Java is incorrect. To see the unsigned value, do:


int unsigned = (byteValue & 0xff);

Cheers, cleared that up, did what you said and yeah comes out right. So its not a problem with reading it in.

Tryed using this one but same outcome

Have already tryed this, followed tut but didnt work.

Have tryed messing around with my code abit but cannot get anything to work, still getting shades of green instead of colored texture.
Also tryed it on different comp and still had the same outcome.

this is the my code using lwjgl 2.7 and pngdecoder that Nate linked to afew posts up.
Im stuck and dont know what to try now. any help?


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import de.matthiasmann.twl.utils.PNGDecoder;
import de.matthiasmann.twl.utils.PNGDecoder.Format;

public class Main {

    public static final int DISPLAY_HEIGHT = 800;
    public static final int DISPLAY_WIDTH = 800;
    public static final Logger LOGGER = Logger.getLogger(Main.class.getName());
    private int squareSize;
    private int squareX;
    private int squareY;
    private int squareZ;
    private int tex01 = 0;//first texture

    static {
        try {
            LOGGER.addHandler(new FileHandler("errors.log", true));
        } catch (IOException ex) {
            LOGGER.log(Level.WARNING, ex.toString(), ex);
        }
    }

    public static void main(String[] args) {
        Main main = null;
        try {
            System.out.println("Keys:");
            System.out.println("down  - Shrink");
            System.out.println("up    - Grow");
            System.out.println("left  - Rotate left");
            System.out.println("right - Rotate right");
            System.out.println("esc   - Exit");



            main = new Main();
            main.create();
            main.run();
        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, ex.toString(), ex);
        } finally {
            if (main != null) {
                main.destroy();
            }
        }
    }

    public Main() throws IOException {
        squareSize = 100;
        squareX = 0;
        squareY = 0;
        squareZ = 0;

    }

    public void create() throws LWJGLException, FileNotFoundException {
        try {
            //Display
            Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH, DISPLAY_HEIGHT));
            Display.setFullscreen(false);
            Display.setTitle("Hello LWJGL World!");
            Display.create();

            //Keyboard
            Keyboard.create();
            //Mouse
            Mouse.setGrabbed(false);
            Mouse.create();
            //OpenGL
            initGL();
            resizeGL();
            tex01 = setupTextures("test2.png");
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void destroy() {
        //Methods already check if created before destroying.
        Mouse.destroy();
        Keyboard.destroy();
       Display.destroy();
    }

    public void initGL() throws FileNotFoundException, IOException {
        //2D Initialization
        GL11.glEnable(GL_TEXTURE_2D);



       GL11.glDisable(GL_DEPTH_TEST);
        GL11.glDisable(GL_LIGHTING);

        GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        //glClearDepth(1);

        GL11.glEnable(GL_BLEND);
        GL11.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        GL11.glViewport(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
        GL11.glMatrixMode(GL_MODELVIEW);

        //glMatrixMode(GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, 1, -1);
        



        



    }

    private int setupTextures(String filename) {
        IntBuffer tmp = BufferUtils.createIntBuffer(1);
        GL11.glGenTextures(tmp);
        tmp.rewind();
        
        try {
            InputStream in = new FileInputStream(filename);
   PNGDecoder decoder = new PNGDecoder(in);

   System.out.println("width="+decoder.getWidth());
   System.out.println("height="+decoder.getHeight());

   ByteBuffer buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
   decoder.decode(buf, decoder.getWidth()*4, Format.RGBA);
   buf.flip();
   
GL11.glBindTexture(GL11.GL_TEXTURE_2D, tmp.get(0));
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
                    GL11.GL_NEAREST);
           GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
                    GL11.GL_NEAREST);
           GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
          
            

  int unsigned = (buf.get(0) & 0xff);
            System.out.println(unsigned);
            System.out.println(buf.get(1));
            System.out.println(buf.get(2));
           System.out.println(buf.get(3));

} catch (FileNotFoundException ex) {
            System.out.println("Error " + filename + " not found");
        } catch (IOException e) {
           System.out.println("Error decoding " + filename);
        }
    
            
           

        tmp.rewind();
        return tmp.get(0);
    }

    public void processKeyboard() {
        //Square's Size
        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
            --squareSize;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
            ++squareSize;
        }

        //Square's Z
        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
            ++squareZ;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
            --squareZ;
        }
    }

    public void processMouse() {
        squareX = Mouse.getX();
        squareY = Mouse.getY();
    }

    public void render() {

        GL11.glClear(GL_COLOR_BUFFER_BIT);
        
        GL11.glLoadIdentity();


        GL11.glBindTexture(GL_TEXTURE_2D, tex01);
        GL11.glBegin(GL_QUADS);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex2f(0.0f, 0.0f);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex2f(squareSize, 0.0f);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex2f(squareSize, squareSize);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex2f(0.0f, squareSize);
        GL11.glEnd();


        //Draw a basic square
        GL11.glTranslatef(squareX, squareY, 0.0f);
        GL11.glRotatef(squareZ, 0.0f, 0.0f, 1.0f);
        GL11.glTranslatef(-(squareSize >> 1), -(squareSize >> 1), 0.0f);
        GL11.glColor3f(0.0f, 0.5f, 0.5f);

        GL11.glBegin(GL_QUADS);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex2f(0.0f, 0.0f);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex2f(squareSize, 0.0f);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex2f(squareSize, squareSize);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex2f(0.0f, squareSize);
        GL11.glEnd();


    }

    public void resizeGL() {
        //2D Scene
        glViewport(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_RGBA);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0f, DISPLAY_WIDTH, 0.0f, DISPLAY_HEIGHT);
        glPushMatrix();

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glPushMatrix();
    }

    public void run() {
        while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
            if (Display.isVisible()) {
                processKeyboard();
                processMouse();
                update();
                render();
            } else {
                if (Display.isDirty()) {
                    render();
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
            }
            Display.update();
            Display.sync(60);
        }
    }

    public void update() {
        if (squareSize < 5) {
            squareSize = 5;
        } else if (squareSize >= DISPLAY_HEIGHT) {
            squareSize = DISPLAY_HEIGHT;
        }
    }
}

Would anyone be willing to give me an example of working code, just loading and displaying texture. so i can compare it with mine and so i can actually see it working. would be much appreciated.

Did you try the code in the link on my post above?

Yeah, i went through that tutorial but had the same out come

edit:

Thanks kappa, last post got me to relook at that tutorial, found what i did wrong. Actually no idea y this line of code was ever in there but taken it out and its fixed.

this was the line: GL11.glColor3f(0.0f, 0.5f, 0.5f); very stupid mistake!

Cheers for the help guys but i was just being a noob :slight_smile:

LOL :smiley:

So… ran into another problem, textures flipped in y axis. just read that opengl stores textures backwards so that would explain it. What is the best way to flip the byte buffer before i load it into opengl as a texture?

Flip your texture coords.