38 int mipmaps_changed_start_bit)
39 : sub_images_changed_(sub_image_changed_bit, false, texture),
40 sub_images_(*texture),
41 mipmaps_(mipmaps_changed_start_bit, kMipmapSlotCount, texture) {
43 for (
size_t i = 0; i < kMipmapSlotCount; ++i)
50 SetSubImage(level, math::Point3ui(offset[0], offset[1], 0), image);
56 sub_images_.push_back(
SubImage(level, offset, image));
58 sub_images_changed_.Set(
false);
59 sub_images_changed_.Set(
true);
64 if (level < kMipmapSlotCount) {
65 if (
Image* img = mipmaps_.Get(level).Get())
66 img->RemoveReceiver(texture);
67 mipmaps_.Set(level, image_in);
69 img->AddReceiver(texture);
70 mipmaps_set_.set(level);
72 mipmaps_set_.reset(level);
100 if (
Sampler* sampler = sampler_.Get().Get())
101 sampler->RemoveReceiver(
this);
105 if (
Sampler* old_sampler = sampler_.Get().Get())
106 old_sampler->RemoveReceiver(
this);
107 sampler_.Set(sampler);
108 if (
Sampler* new_sampler = sampler_.Get().Get())
109 new_sampler->AddReceiver(
this);
114 if (immutable_image_.Get().Get()) {
115 LOG(
ERROR) <<
"ION: SetImmutableImage() called on an already immutable "
116 "texture; SetImmutableImage() can only be called once.";
117 }
else if (levels == 0) {
118 LOG(
ERROR) <<
"ION: SetImmutableImage() called with levels == 0. A "
119 "texture must have at least one level (the 0th level).";
121 immutable_levels_ = levels;
122 immutable_image_.Set(image);
137 face_(this, kSubImageChanged, kMipmapChanged) {
141 const uint32 mipmap_height,
142 const uint32 mipmap_level,
143 const uint32 base_width,
144 const uint32 base_height,
145 uint32* expected_width,
146 uint32* expected_height) {
150 *expected_height = 0;
153 if (mipmap_width != 1 && (mipmap_width & (mipmap_width - 1))) {
154 LOG(
ERROR) <<
"Mipmap width: " << mipmap_width <<
" is not a power of 2.";
157 if (mipmap_height != 1 && (mipmap_height & (mipmap_height - 1))) {
158 LOG(
ERROR) <<
"Mipmap height: " << mipmap_height <<
" is not a power of 2.";
164 if (mipmap_width != 1 && mipmap_height != 1) {
165 const float base_ratio =
166 static_cast<float>(base_width) / static_cast<float>(base_height);
167 const float mipmap_ratio =
168 static_cast<float>(mipmap_width) / static_cast<float>(mipmap_height);
169 if (base_ratio != mipmap_ratio) {
170 LOG(
ERROR) <<
"Bad aspect ratio for mipmap.";
176 const uint32 max_dimension = std::max(base_width, base_height);
177 const uint32 max_level =
static_cast<uint32
>(
math::Log2(max_dimension));
178 if (mipmap_level > max_level) {
179 LOG(
ERROR) <<
"Mipmap level is: " << mipmap_level <<
180 " but maximum level is: " << max_level <<
".";
184 *expected_width = base_width >> mipmap_level;
185 *expected_height = base_height >> mipmap_level;
190 if (base_width != base_height) {
191 *expected_width = std::max(*expected_width, 1U);
192 *expected_height = std::max(*expected_height, 1U);
195 if (!((mipmap_width == *expected_width) &&
196 (mipmap_height == *expected_height))) {
197 LOG(
ERROR) <<
"***ION: Mipmap level " << mipmap_level <<
" has incorrect"
198 <<
" dimensions [" << mipmap_width <<
"x"
199 << mipmap_height <<
"], expected [" << *expected_width <<
"x"
200 << *expected_height <<
"]. Base dimensions: ("
201 << base_width <<
", " << base_height <<
"). Ignoring.\n";
209 for (
size_t i = 0; i < kMipmapSlotCount; ++i) {
219 for (
size_t i = 0; i < kMipmapSlotCount; ++i) {
235 const EnumHelper::EnumData<Texture::Swizzle> EnumHelper::GetEnumData() {
236 static const GLenum kValues[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
237 static const char* kStrings[] = {
"Red",
"Green",
"Blue",
"Alpha" };
239 "EnumHelper size mismatch");
240 return EnumData<Texture::Swizzle>(
const ImagePtr GetImage(size_t level) const
Returns the image at the specified mipmap level, or NULL if this is not mipmapped.
void SetImage(size_t level, const ImagePtr &image_in, TextureBase *texture)
Sets the image to use for the texture at the specified mipmap level.
T Log2(T n)
Returns the base-2 logarithm of n.
void SetImmutableImage(const ImagePtr &image, size_t levels)
Sets this texture to be fully allocated and made immutable by OpenGL, in the sense that it cannot cha...
const SamplerPtr & GetSampler() const
TextureBase(TextureType type)
The constructor is protected since this is a base class.
Wrapper around a sub-image, which is defined as an image, the xy offset of where it should be placed ...
#define LOG(severity)
Logs the streamed message unconditionally with a severity of severity.
A Notifier both sends notifications to and receives notifications from other Notifiers.
~TextureBase() override
The destructor is protected because all base::Referent classes must have protected or private destruc...
void OnChanged(int bit) const
Forwards OnChanged to all resources.
void SetSubImage(size_t level, const math::Point2ui offset, const ImagePtr &image)
Sets the area of the texture starting from the passed xy offset and having the dimensions of the pass...
An Image represents 2D image data that can be used in a texture supplied to a shader.
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
This template class can be used to map between two kinds of indices when the following assumptions ap...
const Grid & image
The original monochrome image data, as doubles (0 - 1).
TexturePtr texture
The Texture to add sub-image data to.
This is an internal base class for all texture types.
static bool ExpectedDimensionsForMipmap(const uint32 mipmap_width, const uint32 mipmap_height, const uint32 mipmap_level, const uint32 base_width, const uint32 base_height, uint32 *expected_width, uint32 *expected_height)
Tests mipmap dimensions to see that they are proportional and in range with respect to base_width and...
~Texture() override
The destructor is protected because all base::Referent classes must have protected or private destruc...
int GetResourceCount() const
Returns the number of resources that this holder holds.
#define ION_STATIC_ASSERT(expr, message)
Copyright 2016 Google Inc.
Face(TextureBase *texture, int sub_image_changed_bit, int mipmaps_changed_start_bit)
TextureBase::Face.
kMipmapChanged must be last since it is a range of slots.
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
void SetSampler(const SamplerPtr &sampler)
Sets/returns the Sampler to use for this. This is NULL by default.
A Sampler object represents texture parameters that control how texture data is accessed in shaders...