load cubemap with one bytebuffer

If i save a cubemap texture in an image like so:

Positive_x
Negative_X
positive_y
negative_y
positive_z
negative_z

could i load it with the code:



int subheight=img_height/6;
ByteBuffer buf = ByteBuffer.allocate(img_width*img_height*bpp);

//load image into buf here

public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,0,format,img_width,subheight,0,format,datatype,buf);
public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,0,format,img_width,subheight,0,format,datatype,buf);
public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,0,format,img_width,subheight,0,format,datatype,buf);
public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,0,format,img_width,subheight,0,format,datatype,buf);
public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,0,format,img_width,subheight,0,format,datatype,buf);
public static void glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,0,format,img_width,subheight,0,format,datatype,buf);


Or will i have to use separate buffers?

All of your pixels for a single image need to be aligned, e.g.

 { 
    all pixels of image 1,
    all pixels of image 2,
    all pixels of image 3,
    etc }

Here is an example of using a single buffer which contains multiple image data:

int width = 1, height = 1;
int bpp = 4;
int count = 2;

tex1 = new Texture(width, height, Texture.NEAREST);
tex2 = new Texture(width, height, Texture.NEAREST);

ByteBuffer buf = BufferUtils.createByteBuffer(width*height*bpp*count);
final byte FF = (byte)0xFF;

//tex one (white)
buf.put(FF).put(FF).put(FF).put(FF);

//tex two (red)
buf.put(FF).put((byte)0x00).put((byte)0x00).put(FF);

//flip the buffer
buf.flip();

//set buffer to image position 0
//(not necessary since we just flipped; only included for clarity)
buf.position( width*height*bpp * 0 ); //image 0

//glTexImage2D with same width, height
tex1.upload(GL_RGBA, buf);

//set buffer to image position 1
buf.position( width*height*bpp * 1 );

//glTexImage2D with same width, height
tex2.upload(GL_RGBA, buf);

So in theory it should work if you ensure each image is aligned after the other.

For more reading on textures and buffers:


glteximage starts from the current buffer position, correct?

I thought so too but my above code only worked with buffer.position(x). ???

I’ve looked through the lwjgl code and it appears that using glteximage2d doesn’t actually change the buffer position.

I’d suggest trying out PBOs. You can upload your data directly to the OpenGL driver in one go, after that you can define your textures from that buffer however you like. Its faster since you upload to OpenGL directly, you don’t have to deal with the direct ByteBuffer becoming garbage at some point since the upload memory is provided by the OGL driver itself, you can upload all your data as one chunk and split it up later as you like. Its also available since OGL 1.5, so it should work even on older cards.

Thank You. I will do that.

If i map a PBO and get a buffer from the driver, can it be written to from another thread?

Yes, after you map the buffer, you can hand it over to another thread to fill it. After filling it, hand it back to the first thread to unmap and glTeximage it. I suggest the following loop:

Step 1: unmap PBO and glTeximage loaded textures
Step 2: update the scene, collect the list of textures to be loaded
Step 3: map the PBO buffer(s), hand them to the second thread
Step 4: draw the scene
Step 5: repeat

This way the GPU will asynchronously upload textures while the program is doing CPU heavy work (updating the scene).