Hello Guest

Image to ByteBuffer

  • 13 Replies
  • 9766 Views
Image to ByteBuffer
« on: August 23, 2015, 16:30:02 »
I need to convert an image to a ByteBuffer for openGL.
Code: [Select]
private static final int BYTES_PER_PIXEL = 4;

public static ByteBuffer convertImage(BufferedImage image)
{     
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() * BYTES_PER_PIXEL);

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. Only for RGBA
            }
        }

        buffer.flip();

return buffer;
}
When I do glGenTextures(textureID, convertImage(image)) then draw it onto the screen it seems to come out white. Is this a problem with the convertImage function.

*

Offline abcdef

  • ****
  • 320
Re: Image to ByteBuffer
« Reply #1 on: August 23, 2015, 19:26:02 »
glGenTextures is only used to generate the texture buffer. glTexImage2D is what is used to define the data that the buffer points to

glGenTextures(textureID, convertImage(image))

this should actually be

glGenTextures(number of texture buffers to create, a byte buffer that will be full of these texture buffers once the method returns)

Go read up a  bit more of the opengl functions used to upload texture data to the graphics card

Re: Image to ByteBuffer
« Reply #2 on: August 23, 2015, 23:26:40 »
Ok, I look through many tutorials I just can't find the right one for me. By the, I'm using lwjgl 3. Can some one help me. :(

*

Offline abcdef

  • ****
  • 320
Re: Image to ByteBuffer
« Reply #3 on: August 24, 2015, 08:23:57 »
You don't need a LWJGL 3 tutorial, any tutorial on textures will explain things. Example below

https://open.gl/textures

You just need to then convert the opengl calls to from a c++ format to a java format (as the mirror 1-1).

Re: Image to ByteBuffer
« Reply #4 on: August 24, 2015, 21:07:25 »
Yes I saw that page befor but the code from there does dosen't work and I can't figure it out. And what do you mean
You just need to then convert the opengl calls to from a c++ format to a java format (as the mirror 1-1).

*

Offline abcdef

  • ****
  • 320
Re: Image to ByteBuffer
« Reply #5 on: August 25, 2015, 08:02:28 »
LWJGL mirrors the function calls of the c libraries, the only difference is when you pass a reference (or arrays as they are essentially pointers) to opengl in c, you can't do this in java so the equivalent is to pass a buffer.

Here are some examples to get you going (I haven't tested this code as I am not at a PC with a dev env on so apologies if there are typo's)...

*** Generate textures ***

Code: [Select]
GLuint tex;
glGenTextures(1, &tex);

becomes (check the java doc, there are other more convenient helper methods)

Code: [Select]
ByteBuffer textureBuffer = BufferUtils.createByteBuffer((Integer.SIZE/Byte.SIZE));
GL11.glGenTextures(1,textureBuffer);

*** Bind Buffer ***

Code: [Select]
glBindTexture(GL_TEXTURE_2D, tex);

becomes

Code: [Select]
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureBuffer.getInt());

*** load the data ***

Code: [Select]
float pixels[] = {
    0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);

Code: [Select]
float pixels[] = {
    0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f
};
FloatBuffer pixelData = BufferUtils.createFloatBuffer(12);
pixelData.put(pixels);
pixelData.flip();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 2, 2, 0, GL11.GL_RGB, GL11.GL_FLOAT, pixelData);

This should get you going. Just read lots of tutorials and if you are having trouble post specific code you can't covert to java with the original code and your attempt.

Re: Image to ByteBuffer
« Reply #6 on: August 26, 2015, 10:46:49 »
Ok so since my preves code was correcrt what's wrong with how tell openGL the textures and then draw.
Code: [Select]
i = ImageIO.read(new File("/home/dennis/Black Hole Breakers/Graphics/test.png"));
glGenTextures(textureID, convertImage(i));
Code: [Select]
              glPushMatrix();

glBindTexture(GL_TEXTURE_2D, textureID);

glBegin(GL_QUADS);

glTexCoord2f(0,0);
glVertex2f(0,0);

glTexCoord2f(1,0);
glVertex2f(800,0);

glTexCoord2f(1,1);
glVertex2f(800,600);

glTexCoord2f(0,1);
glVertex2f(0,600);

glEnd();

glPopMatrix();
I do swap buffers.

*

Offline abcdef

  • ****
  • 320
Re: Image to ByteBuffer
« Reply #7 on: August 26, 2015, 14:31:54 »
No!! Your previous code was totally incorrect for the reasons I said. You really do have no idea what you are doing.

Re: Image to ByteBuffer
« Reply #8 on: August 26, 2015, 21:29:50 »
I'm sorry.  :'( I'm new, especially to openGL. But I've bin trying to make
Code: [Select]
float pixels[] = {
    0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f
};
FloatBuffer pixelData = BufferUtils.createFloatBuffer(12);
pixelData.put(pixels);
pixelData.flip();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 2, 2, 0, GL11.GL_RGB, GL11.GL_FLOAT, pixelData);
work. That should mke checkerboard pattern. I read throught open.gl/textures and other help too. So far I found out that I should use something like glGenTextures then glBindTexture and finaly glTexImage2D to load textures into openGL. It doesn't work. So is that not what I should use or could I be mising something. And by the way if you put
Code: [Select]
import static org.lwjgl.opengl.GL11.*;you don't need GL11.
How I'm not terribly wrong this time.  ::)

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Image to ByteBuffer
« Reply #9 on: August 26, 2015, 21:56:28 »
OK, here's a quick rundown of textures in OpenGL.

glGenTexture() gives you the ID of an OpenGL texture object. The texture will be empty to start with. (which doesn't mean blank image, it means there is nothing)

glBindTexture() binds a particular OpenGL texture object to a particular target (the target is the type of the texture. GL_TEXTURE_2D is a "regular" texture). Most functions operate on the currently bound texture and when drawing, the currently bound texture will be used as a source.

glTexImage2D() fills the OpenGL texture object currently bound to the target you specify in the parameters with image data.

It's a simple setup that any OpenGL tutorial would have taught you. And a tutorial is what you need to read now. There are plenty out there.

Re: Image to ByteBuffer
« Reply #10 on: August 29, 2015, 01:36:11 »
So about the only tutorials for openGL in java use slick2D which is not in lwjgl3 and I use lwjgl3. Instead I fallowed a c++ tutorial, but I'm have trouble puting it into java. (I also tryed to use what quew8 posted.) What would be wrong here.
Code: [Select]
              ByteBuffer BB = BufferUtils.createByteBuffer(12);

float pixels[] = {ge(image);

    0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f
};
FloatBuffer pixelData = BufferUtils.createFloatBuffer(12);
pixelData.put(pixels);
pixelData.flip();

glGenTextures(ID, BB);

glBindTexture(GL_TEXTURE_2D, ID);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_FLOAT, pixelData);
I don't know much. ???

*

Offline abcdef

  • ****
  • 320
Re: Image to ByteBuffer
« Reply #11 on: August 29, 2015, 10:32:56 »
I'm going to say this one more time, your glGenTextures is completely wrong!! The answers are already in this post.

Re: Image to ByteBuffer
« Reply #12 on: August 29, 2015, 18:01:40 »
I finally got it to work!!! :o ;D Here's my code...
Code: [Select]
        private static int loadTex(String loc)
{
BufferedImage image = null;

try
{
image = ImageIO.read(new File(loc));
}
catch(Exception a) {}

ByteBuffer BB = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL);

BB = convertImage(image);

int ID = glGenTextures();

glBindTexture(GL_TEXTURE_2D, ID);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, BB);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

return ID;
}

Code: [Select]
        private static final int BYTES_PER_PIXEL = 4;

public static ByteBuffer convertImage(BufferedImage image)
{     
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() * BYTES_PER_PIXEL);

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. Only for RGBA
            }
        }

        buffer.flip();

return buffer;
}

By the way can somone tell me what
Code: [Select]
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);does?

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Image to ByteBuffer
« Reply #13 on: August 29, 2015, 18:31:00 »
By the way can somone tell me what
Code: [Select]
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);does?

That tells OpenGL what to do if it is trying to draw the texture at a smaller resolution to the texture's resolution. Eg drawing one pixel for every 4 in the texture. GL_NEAREST means just use the pixel closest to the desired point. You could also have GL_LINEAR which gives you linear interpolation of all the near pixels.

Here's a tip. Whenever you don't know what a function does, check the reference pages https://www.opengl.org/sdk/docs/man2/