internal_format(0)
{ }
+void TexImageState::set_1d(GLenum ifmt, unsigned wd)
+{
+ set_3d(ifmt, wd, 0, 0);
+}
+
void TexImageState::set_2d(GLenum ifmt, unsigned wd, unsigned ht)
+{
+ set_3d(ifmt, wd, ht, 0);
+}
+
+void TexImageState::set_3d(GLenum ifmt, unsigned wd, unsigned ht, unsigned dp)
{
width = wd;
height = ht;
- depth = 0;
+ depth = dp;
internal_format = ifmt;
}
}
+GLenum texture_cube_faces[6] =
+{
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+};
+
TextureState::TextureState():
id(0),
target(0),
generate_mipmap(false)
{ }
+TexImageState &TextureState::get_image(unsigned level)
+{
+ if(images.size()<=level)
+ images.resize(level+1);
+ return images[level];
+}
+
+void TextureState::set_image_1d(unsigned level, GLenum ifmt, unsigned wd)
+{
+ get_image(level).set_1d(ifmt, wd);
+ if(level==0 && generate_mipmap)
+ create_mipmaps();
+}
+
void TextureState::set_image_2d(unsigned level, GLenum ifmt, unsigned wd, unsigned ht)
{
- while(1)
+ get_image(level).set_2d(ifmt, wd, ht);
+ if(level==0 && generate_mipmap)
+ create_mipmaps();
+}
+
+void TextureState::set_face_image_2d(GLenum face, unsigned level, GLenum ifmt, unsigned wd, unsigned ht)
+{
+ unsigned index = 0;
+ for(; (index<6 && texture_cube_faces[index]!=face); ++index) ;
+ if(index>=6)
+ return;
+
+ set_image_2d(level*6+index, ifmt, wd, ht);
+}
+
+void TextureState::set_image_3d(unsigned level, GLenum ifmt, unsigned wd, unsigned ht, unsigned dp)
+{
+ get_image(level).set_3d(ifmt, wd, ht, dp);
+ if(level==0 && generate_mipmap)
+ create_mipmaps();
+}
+
+void TextureState::create_mipmaps(unsigned face)
+{
+ unsigned stride = (target==GL_TEXTURE_CUBE_MAP ? 6 : 1);
+ if(face>=stride)
+ face = 0;
+
+ unsigned wd = images[face].width;
+ unsigned ht = images[face].height;
+ unsigned dp = images[face].depth;
+ for(unsigned i=1;; ++i)
{
- if(images.size()<=level)
- images.resize(level+1);
- images[level].set_2d(ifmt, wd, ht);
-
- if(generate_mipmap)
- {
- if(wd==1 && ht==1)
- break;
- ++level;
- if(wd>1)
- wd /= 2;
- if(ht>1)
- ht /= 2;
- }
- else
+ if(wd<=1 && ht<=1 && dp<=1)
break;
+
+ if(wd>1)
+ wd /= 2;
+ if(ht>1)
+ ht /= 2;
+ if(dp>1)
+ dp /= 2;
+
+ get_image(i*stride+face).set_3d(images[0].internal_format, wd, ht, dp);
}
}
string descr = describe_enum(target, "TextureTarget");
if(images.empty())
descr += ", undefined";
+ else if(target==GL_TEXTURE_CUBE_MAP)
+ {
+ bool homogeneous = true;
+ for(unsigned i=1; (homogeneous && i<6); ++i)
+ homogeneous = (images[i].width==images[0].width && images[i].height==images[0].height &&
+ images[i].internal_format==images[0].internal_format);
+ if(homogeneous)
+ descr += ", "+images.front().describe();
+ else
+ descr += ", heterogeneous faces";
+ }
else
descr += ", "+images.front().describe();
return descr;
}
-TexUnitState::TexUnitState():
- current_2d(0),
- current_3d(0)
-{ }
+TexUnitState::Binding *TexUnitState::get_binding(GLenum target)
+{
+ if(target==GL_TEXTURE_1D)
+ return &binding_1d;
+ else if(target==GL_TEXTURE_2D)
+ return &binding_2d;
+ else if(target==GL_TEXTURE_3D)
+ return &binding_3d;
+ else if(target==GL_TEXTURE_CUBE_MAP)
+ return &binding_cube;
+ else
+ return 0;
+}
+
+const TexUnitState::Binding *TexUnitState::get_binding(GLenum target) const
+{
+ return const_cast<TexUnitState *>(this)->get_binding(target);
+}
void TexUnitState::set_current_texture(GLenum target, TextureState *tex)
{
- if(target==GL_TEXTURE_2D)
- current_2d = tex;
- else if(target==GL_TEXTURE_3D)
- current_3d = tex;
+ if(Binding *binding = get_binding(target))
+ binding->current = tex;
}
TextureState *TexUnitState::get_current_texture(GLenum target)
{
- if(target==GL_TEXTURE_2D)
- return current_2d;
- else if(target==GL_TEXTURE_3D)
- return current_3d;
+ if(Binding *binding = get_binding(target))
+ return binding->current;
else
return 0;
}
return const_cast<TexUnitState *>(this)->get_current_texture(target);
}
+bool TexUnitState::is_enabled(GLenum target) const
+{
+ if(const Binding *binding = get_binding(target))
+ return binding->enabled;
+ else
+ return false;
+}
+
string TexUnitState::describe_binding(GLenum target) const
{
- if(const TextureState *tex = get_current_texture(target))
+ if(const Binding *binding = get_binding(target))
+ return binding->describe();
+ else
+ return "None";
+}
+
+
+TexUnitState::Binding::Binding():
+ enabled(false),
+ current(0)
+{ }
+
+string TexUnitState::Binding::describe() const
+{
+ if(current)
{
- string descr = strformat("%d ", tex->id);
- if(tex->images.empty())
+ string descr = strformat("%d ", current->id);
+ if(current->images.empty())
descr += "(undefined)";
else
- descr += "("+tex->images.front().describe()+")";
+ descr += "("+current->images.front().describe()+")";
+ if(enabled)
+ descr += ", enabled";
return descr;
}
+ else if(enabled)
+ return "None, enabled";
else
return "None";
}