throw invalid_operation("TextureCube::allocate");
if(level>=levels)
throw invalid_argument("TextureCube::allocate");
- if(allocated&(1<<level))
+ if(allocated&(64<<level))
return;
if(ARB_texture_storage)
return sub_image(face, level, 0, 0, s, s, fmt, type, data);
BindRestore _bind(this);
+
+ if(!allocated)
+ glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
glTexImage2D(face, level, ifmt, s, s, 0, get_upload_format(fmt), type, data);
- // XXX Allocation should be tracked per-face, but we'll run out of bits
- allocated |= 1<<level;
- if(auto_gen_mipmap==1 && level==0)
+ if(level==0)
{
- // TODO Only do this once all faces are created
- generate_mipmap();
- allocated |= (1<<get_n_levels())-1;
+ allocated |= 1<<get_face_index(face);
+ if((allocated&63)==63)
+ {
+ allocated |= 64;
+ if(auto_gen_mipmap)
+ {
+ generate_mipmap();
+ allocated |= (64<<levels)-1;
+ }
+ }
+ }
+ else if(!(allocated&(64<<level)))
+ {
+ for(unsigned i=0; i<6; ++i)
+ if(enumerate_faces(i)!=face)
+ glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, get_upload_format(fmt), type, 0);
+
+ allocated |= 64<<level;
}
}
glTexSubImage2D(face, level, x, y, wd, ht, get_upload_format(fmt), type, data);
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
generate_mipmap();
}
image(face, 0, fmt, UNSIGNED_BYTE, img.get_data());
}
-void TextureCube::image(const Graphics::Image &img, bool srgb)
+void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
{
unsigned w = img.get_width();
unsigned h = img.get_height();
PixelFormat fmt = pixelformat_from_graphics(img.get_format());
if(size==0)
- {
- unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l);
- }
+ storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, lv);
else if(w!=size || h!=size)
throw incompatible_data("TextureCube::image");
add("image_data", &Loader::image_data);
add("raw_data", &Loader::raw_data);
add("storage", &Loader::storage);
+ add("storage", &Loader::storage_levels);
}
void TextureCube::Loader::external_image(TextureCubeFace face, const string &fn)
obj.storage(fmt, s);
}
+void TextureCube::Loader::storage_levels(PixelFormat fmt, unsigned s, unsigned l)
+{
+ obj.storage(fmt, s, l);
+}
+
void operator>>(const LexicalConverter &conv, TextureCubeFace &face)
{