TextureArray::TextureArray(std::vector<std::string> path, bool mipmap) : TextureBase() , _num(path.size()) , _texture(0) { if ( path.size() == 0 ){ fprintf(stderr, "TextureArray must have at least one image, got 0.\n"); path.push_back("default.jpg"); _num++; } /* hack to get size */ { SDL_Surface* surface = load_image(path[0], &size); SDL_FreeSurface(surface); } fprintf(verbose, "Creating TextureArray with %zd images at %dx%d\n", path.size(), size.x, size.y); glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D_ARRAY, _texture); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); if ( mipmap ){ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_TRUE); } else { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_FALSE); } glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, size.x, size.y, num_textures(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); int n = 0; for ( const std::string& filename: path) { glm::ivec2 cur_size; SDL_Surface* surface = load_image(filename, &cur_size); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, n++, cur_size.x, cur_size.y, 1, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); checkForGLErrors(("Texture2DArray: glTexSubImage3D ( " + filename + ")").c_str()); SDL_FreeSurface(surface); } glBindTexture(GL_TEXTURE_2D_ARRAY, 0); checkForGLErrors("Texture2DArray: Create"); }
StringId64 get_texture_id(const PackageResource* pr, uint32_t i) { CE_ASSERT(i < num_textures(pr), "Index out of bounds"); StringId64* begin = (StringId64*) ((char*)pr + pr->textures_offset); return begin[i]; }