Alright, lets go:
1. Pretty trivial class I wrote out there: public final class Texture { private int[] pixels; private int width; private int height; public int getHeight() { return height; } private void setHeight(int height) { this.height = height; } public int[] getPixels() { return pixels; } public ByteBuffer getPixelsAsByteBuffer() { ByteBuffer pixelByteBuffer = ByteBuffer.allocateDirect(pixels.length * 3).order( ByteOrder.nativeOrder()); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { int currentPixel = pixels[x + (y * width)]; pixelByteBuffer.put((byte)((currentPixel >> 16) & 0xFF)); pixelByteBuffer.put((byte)((currentPixel >> 8) & 0xFF)); pixelByteBuffer.put((byte)(currentPixel & 0xFF)); } } pixelByteBuffer.rewind(); return pixelByteBuffer; } private void setPixels(int[] pixels) { this.pixels = pixels; } public int getWidth() { return width; } private void setWidth(int width) { this.width = width; } public void load(FileInputStream fileInputStream) throws Exception { BufferedImage bufferedImage = ImageIO.read(fileInputStream); fileInputStream.close(); setWidth(bufferedImage.getWidth()); setHeight(bufferedImage.getHeight()); setPixels(new int[width * height]); PixelGrabber pixelGrabber = new PixelGrabber(bufferedImage, 0, 0, width, height, pixels, 0, width); pixelGrabber.setColorModel(ColorModel.getRGBdefault()); pixelGrabber.grabPixels(); if((pixelGrabber.getStatus() & ImageObserver.ABORT) != 0) { System.err.println("image fetch aborted or errored"); setPixels(null); } } public void load(String filePath) throws Exception { load(new FileInputStream(filePath)); } public void load(File file) throws Exception { load(new FileInputStream(file)); } } 2. So, its usage, again trivial: texture = new Texture(); try { texture.load("resource/terrain/2.jpg"); } catch(Exception ex) { System.out.println(ex); } 3. And here (as you have probably guessed) we engage it to OpenGL: gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, 1); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); SimpleScene.java:266 gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixelsAsByteBuffer()); 4. Now the story: All the above seems to be cool right? Well, I wish it was :) If I am loading a regular image (64x64, 128x128, 1024x1024 and etc.) everything works ok. If I am loading something like 1020x1020 or maybe 700x900 it MIGHT be ok, but not 100% (for instance, 1010x1010 doesnt load). Finally, if I try 129x129 or maybe 65x65 (or any other combination with numbers, which cannot be divided by 2), it fails 100%! Horrible... 5. Exception Here I provided you with the exception thrown by glTexImage2D, you can notice that here I was trying to load 1023x1023 image, because 1023 * 1023 * 3 = 3139587 bytes, which prooves that ByteBuffer was assembled right, but in some case JOGL wants me too pass him 3142653 bytes... uhm..? And again: if I am loading a regular image (64x64, 128x128, 1024x1024 and etc.) everything works ok. Caused by: java.lang.IndexOutOfBoundsException: Required 3142653 remaining bytes in buffer, only had 3139587 at com.jogamp.common.nio.Buffers.rangeCheckBytes(Buffers.java:749) at com.jogamp.opengl.impl.gl4.GL4bcImpl.glTexImage2D(GL4bcImpl.java:23826) at javax.media.opengl.DebugGL2.glTexImage2D(DebugGL2.java:18956) at ru.haroogan.SimpleScene.init(SimpleScene.java:266) |
Administrator
|
U may have a look here: http://jogamp.762907.n3.nabble.com/Loading-texture-error-tp942252p942252.html
... and specifically here: http://jogamp.762907.n3.nabble.com/Loading-texture-error-tp942252p1637419.html ... also this could be interesting too: http://jogamp.762907.n3.nabble.com/1D-Texture-with-OpenGL-or-Cg-Shader-tp1398178p1398178.html I guess this should resolve ur issue in no time :) |
The first two references are to guys who didnt rewind their ByteBuffers... My ByteBuffer is rewinded. My problem is that I am doing everything right, but somehow JOGL wants more bytes from me on irregular size images. Also I have noticed that when I was creating ByteBuffer with alpha channel and specifing GL_RGBA in glTexImage2D like that, the problem was gone:
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, texture.getPixelsAsByteBuffer()); But why would I do that? What if I want to keep my ByteBuffer without alpha channel component..? |
Administrator
|
try changing ++y and ++x to y++ and x++ ... as far as I can see u are ignoring the 0th element/y-line ...
|
Free forum by Nabble | Edit this page |