Java, LWJGL, OpenGL 1.1, decoding BufferedImage to Bytebuffer and binding to OpenGL across classes -


i've been attempting solve problem without luck. have 4 classes, main class, object class, sprite class , image loader class.

i'm attempting load png using image loader , using method found here: http://www.java-gaming.org/topics/bufferedimage-to-lwjgl-texture/25516/msg/220280/view.html#msg220280 convert bytebuffer, , bind opengl.

the image in it's own seperate resource folder. should being drawn this: (http://i.imgur.com/j8gbu4c.png) (32x32), i'm seeing white box has dimensions of image, not actual texture.

if has idea of go fix i'd appreciate it. i'm new opengl , looking avoid using external library in order learn how actual code works. thanks.

updated!

to following, implemented suggestion provided vallentin, quad taking color of first pixel in image. i've attempted implementing image loader provided c.s here. i'm receiving error:

javax.imageio.iioexception: error reading png image data @ com.sun.imageio.plugins.png.pngimagereader.readimage(pngimagereader.java:1291) @ com.sun.imageio.plugins.png.pngimagereader.read(pngimagereader.java:1560) @ pimageloader.loadbin(pimageloader.java:60) @ monkeybars.main(monkeybars.java:35) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) @ java.lang.reflect.method.invoke(method.java:597) @ com.intellij.rt.execution.application.appmain.main(appmain.java:120)  caused by: javax.imageio.iioexception: destination type imagereadparam not match! @ javax.imageio.imagereader.getdestination(imagereader.java:2862) @ com.sun.imageio.plugins.png.pngimagereader.readimage(pngimagereader.java:1263) ... 8 more  exception in thread "main" java.lang.nullpointerexception @ pimageloader.loadpsprite(pimageloader.java:75) @ monkeybars.main(monkeybars.java:35) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) @     sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) @ java.lang.reflect.method.invoke(method.java:597) @ com.intellij.rt.execution.application.appmain.main(appmain.java:120) 

i'm using intellij 12 on windows 7, using java 6. image i'm trying load linked above. if has ideas, i'm open suggestions.

main block:

   public static void main(string[] args){     system.out.println("sup!");     int width = 800 ;     int height = 600;     try{         display.setdisplaymode(new displaymode(width,height));         display.settitle("the playground");         display.create();     }catch (lwjglexception e){         e.printstacktrace();         display.destroy();         system.exit(1);     }       //initialize opengl     gl11.glmatrixmode(gl11.gl_projection);     gl11.glloadidentity();     gl11.glortho(0, width, height, 0f, 1f, -1f);      gl11.glmatrixmode(gl11.gl_modelview);     gl11.glloadidentity();     gl11.glenable(gl11.gl_texture_2d);     gl11.gldisable(gl11.gl_depth_test);     gl11.glenable(gl11.gl_blend);        pobject mrredsquare = new pobject(300f,300f,pimageloader.loadpsprite(pimageloader.loadbin("test.png")));      while(!display.iscloserequested()){          gl11.glclear(gl11.gl_color_buffer_bit | gl11.gl_depth_buffer_bit);         gl11.glblendfunc(gl11.gl_src_alpha, gl11.gl_one_minus_src_alpha);         mrredsquare.drawme();         display.sync(60);         display.update();     } } } 

texture loader, new method.

public static bufferedimage loadbin(string filepath){      bufferedimage image;     // reader     imagereader ir = imageio.getimagereadersbyformatname("png").next();      // default param     imagereadparam p = ir.getdefaultreadparam();     p.setdestinationtype(             // define image type return if supported             imagetypespecifier.createinterleaved(                     colorspace.getinstance(colorspace.cs_srgb),                     new int[] {0, 1, 2, 3},    // <-- order of color bands return bytes in desired order                     databuffer.type_byte,                     true, false)     );      try{         inputstream stream = pimageloader.class.getclassloader().getresourceasstream(filepath);         imageinputstream imagestream = imageio.createimageinputstream(stream);         ir.setinput(imagestream);         image = ir.read(0, p);     }catch(exception e){         system.out.print("imageloader cannot obtain asset");         e.printstacktrace();         return null;      }     return image;  } 

older code, kept archival purposes

main:

public static void main(string[] args){     system.out.println("sup!");     try{         display.setdisplaymode(new displaymode(800,600));         display.settitle("the playground");         display.create();     }catch (lwjglexception e){         e.printstacktrace();         display.destroy();         system.exit(1);     }       //initialize opengl     gl11.glmatrixmode(gl11.gl_projection);     gl11.glloadidentity();     gl11.glortho(0, 800, 0, 600, 1, -1);     gl11.glmatrixmode(gl11.gl_modelview);       pobject mrredsquare = new pobject(300,300,pimageloader.loadpsprite(pimageloader.loadbi("square.png")));      while(!display.iscloserequested()){         gl11.glclear(gl11.gl_color_buffer_bit | gl11.gl_depth_buffer_bit);         mrredsquare.drawme();         display.sync(60);         display.update();     } } 

object (draw code):

    public void drawme(){      // store current model matrix     gl11.glpushmatrix();      // bind appropriate texture sprite     texture.bind();      // translate right location , prepare draw     gl11.gltranslatef(x, y, 0);      // draw quad textured match sprite     gl11.glbegin(gl11.gl_quads);     {         gl11.gltexcoord2f(0, 0);         gl11.glvertex2f(0, 0);          gl11.gltexcoord2f(0, texture.getheight());         gl11.glvertex2f(0, height);          gl11.gltexcoord2f(texture.getwidth(), texture.getheight());         gl11.glvertex2f(width,height);          gl11.gltexcoord2f(texture.getwidth(), 0);         gl11.glvertex2f(width,0);     }     gl11.glend();      // restore model view matrix prevent contamination     gl11.glpopmatrix();  }  

texture:

public class psprite {  protected bytebuffer spritedata; protected bufferedimage spriteimage; protected int id;  protected int width; protected int height;  //--------------------------------------------------------------------------------------- //constructors:  psprite(bufferedimage si, bytebuffer s, int i){     spriteimage = si;     spritedata = s;     id = i;      width = spriteimage.getwidth();     height = spriteimage.getheight(); } //--------------------------------------------------------------------------------------- //methods: public void bind(){     gl11.glbindtexture(gl11.gl_texture_2d, id); }  

imageloader:

public class pimageloader {  public static bufferedimage loadbi(string filepath){     bufferedimage image;     try{         inputstream input = pimageloader.class.getresourceasstream(filepath);         image = imageio.read(input);     }catch (exception e){         system.out.print("imageloader: cannot obtain asset.");         e.printstacktrace();         return null;     }     return image; }  public static psprite loadpsprite(bufferedimage image){      //http://www.java-gaming.org/topics/bufferedimage-to-lwjgl-texture/25516/msg/220280/view.html#msg220280      int pixels[] = new int[image.getwidth() * image.getheight()];     image.getrgb(0, 0, image.getwidth(), image.getheight(), pixels, 0, image.getwidth());     bytebuffer buffer = bufferutils.createbytebuffer(image.getwidth() * image.getheight() * 4); // <-- 4 rgba, 3 rgb      for(int y = 0; y < image.getheight(); y++){         for(int x = 0; x < image.getwidth(); x++){             int pixel = pixels[y * image.getwidth() + x];             buffer.put((byte) ((pixel >> 16) & 0xff));     // red component             buffer.put((byte) ((pixel >> 8) & 0xff));      // green component             buffer.put((byte) (pixel & 0xff));               // blue component             buffer.put((byte) ((pixel >> 24) & 0xff));    // alpha component. rgba         }     }      buffer.flip();      int textureid = glgentextures(); //generate texture id     glbindtexture(gl_texture_2d, textureid);      // 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_linear);     gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_linear);      //send texel data opengl     glteximage2d(gl_texture_2d, 0, gl_rgba8, image.getwidth(), image.getheight(), 0, gl_rgba, gl_unsigned_byte, buffer);      return new psprite(image, buffer, textureid);     } } 

there lot of problems code. important issues have found are:

1) problems of yours, start fact not using 32-bit image (i.e. rgba) using 24-bit image (i.e. rgb).

so code have used specifying image type wrong. should use following:

p.setdestinationtype(     // define image type return if supported     imagetypespecifier.createinterleaved(                     colorspace.getinstance(colorspace.cs_srgb),                     new int[] {0, 1, 2}, // <-- expecting 3 color bands since image rgb                      databuffer.type_byte,                     false,   //<-- alpha, image doesn't have                     false) ); 

2) per comments instrunctions of image converting process, supposed use bytebuffer of size width * height * 3. in general true. seems lwjgl not let (it forces rectangular dimensions?) should leave value 4 , modify alpha like:

buffer.put((byte) 0xff);    // alpha 1.0 i.e. opaque 

this should load image correctly. please note additional problem in original code (other forgetting use glenable(gl_texture_2d)) not setting blend function (btw can set once not need set in every frame). if have used 32-bit texture transparent areas appear black.

3) third problem when giving texture coordinates use gltexcoord2f(texture.getwidth(), texture.getheight()); wrong because texture coordinates can range [0, 1]. way work, if had setup texture parameters gl_texture_wrap_s, gl_texture_wrap_t both use gl_repeat (the default). setting gl_clamp_to_edge. if give texture values greater 1 final image have color of image border.

so should modify code below:

gl11.glbegin(gl11.gl_quads); {     gl11.gltexcoord2f(0, 0);   // <--     gl11.glvertex2f(0, 0);      gl11.gltexcoord2f(0, 1);   // <--     gl11.glvertex2f(0, height);      gl11.gltexcoord2f(1, 1);   // <--     gl11.glvertex2f(width, height);      gl11.gltexcoord2f(1, 0);   // <--     gl11.glvertex2f(width,0); } 

my advice when experimenting textures, use large simple image can see what's happenning (correct alpha, upside-down etc) e.g. red rectangle inner blue rectangle or that, able identify problem texture other "it not work".

i hope helps


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -