Skip to content

Instantly share code, notes, and snippets.

@tilkinsc
Last active June 4, 2024 03:12
Show Gist options
  • Save tilkinsc/63fe3905e139c43a013b6c6996d068ba to your computer and use it in GitHub Desktop.
Save tilkinsc/63fe3905e139c43a013b6c6996d068ba to your computer and use it in GitHub Desktop.
OpenGL Texture Atlas Array Texture Example
// tiles_x the amount of tiles in the image in the x dimension
// tiles_y the amount of tiles in the image in the y dimension
void Texture::finalizeArray(GLsizei tiles_x, GLsizei tiles_y) {
// read in file data
Material* mat = new Material("file.bmp"); // MUST be power of 2
mat->mips = 1; // !single image!
// defines ogl parameters
TextureData* tdata = new TextureData;
tdata->min_filter = GL_LINEAR;
tdata->mag_filter = GL_LINEAR;
tdata->wrapping = GL_CLAMP_TO_EDGE;
// create ogl texture handle
GLuint texid = 0;
glGenTextures(1, &texid);
tdata->tid = texid;
// bind ogl texture handle
glBindTexture(GL_TEXTURE_2D_ARRAY, tdata->tid);
// set up texture handle parameters
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); // !single image!
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mat->mips); // !single image! mat->mips == 1
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, tdata->min_filter); // GL_LINEAR
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, tdata->mag_filter); // GL_LINEAR
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, tdata->wrapping); // GL_CLAMP_TO_EDGE
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, tdata->wrapping); // GL_CLAMP_TO_EDGE
// do some calculation
size_t p_dx = mat->width / tiles_x; // pixels of each tile in x
size_t p_dy = mat->height / tiles_y; // pixels of each tile in y
size_t tiles = tiles_x * tiles_y; // number of tiles total
// defines boundaries of a single sub image
// target (GL_TEXTURE_2D_ARRAY)
// !miplevels 1 single image!
// pformat
// tile_width
// tile_height
// number of tiles
// http://docs.gl/gl4/glTexStorage3D
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, p_dx, p_dy, tiles); // mips, format, width/tiles_x, height/tiles_y, total_tiles
// alignment
// GL_UNPACK_ROW_LENGTH defines the number of pixels in a row
// GL_UNPACK_IMAGE_HEIGHT defines the number of pixels in a column
// http://docs.gl/gl4/glPixelStore
glPixelStorei(GL_UNPACK_ROW_LENGTH, mat->width); // width
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, mat->height); // height
// fills `tiles_x * tiles_y` boundaries with sub image data
// reads all tiles row by row as opposed to column by column i.e. 1x1 2x1 1x2 2x2
for (GLsizei x=0; x<tiles_x; x++) {
for (GLsizei y=0; y<tiles_y; y++) {
// target (GL_TEXTURE_2D_ARRAY)
// miplevels 0 for just single image
// 0 (const)
// 0 (const)
// x * tiles_x + y
// tile_width
// tiles_height
// 1 (const)
// pformat (GL_BGR)
// iformat (GL_UNSIGNED_BYTE)
// pixels + (x * tile_height * width + y * tile_width) * components
// http://docs.gl/gl4/glTexSubImage3D
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, x * tiles_x + y, p_dx, p_dy, 1, GL_BGR, GL_UNSIGNED_BYTE, mat->pixels + (x * p_dy * mat->width + y * p_dx) * 3);
}
}
// unbind texture handle
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment