Fix mipmapping with sampler state

This commit is contained in:
rdb 2014-12-12 20:27:08 +01:00
parent fe3f4a6d2a
commit 89031b4e48
7 changed files with 62 additions and 35 deletions

View File

@ -4268,14 +4268,15 @@ update_texture(TextureContext *tc, bool force) {
// If the texture image was modified, reload the texture.
apply_texture(tc);
Texture *tex = tc->get_texture();
if (gtc->was_properties_modified()) {
Texture *tex = tc->get_texture();
specify_texture(gtc, tex->get_default_sampler());
}
bool okflag = upload_texture(gtc, force);
bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
if (!okflag) {
GLCAT.error()
<< "Could not load " << *gtc->get_texture() << "\n";
<< "Could not load " << *tex << "\n";
return false;
}
@ -4290,7 +4291,7 @@ update_texture(TextureContext *tc, bool force) {
if (specify_texture(gtc, tex->get_default_sampler())) {
// Actually, looks like the texture *does* need to be reloaded.
gtc->mark_needs_reload();
bool okflag = upload_texture(gtc, force);
bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
if (!okflag) {
GLCAT.error()
<< "Could not load " << *tex << "\n";
@ -4398,7 +4399,7 @@ prepare_sampler(const SamplerState &sampler) {
SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
bool uses_mipmaps = Texture::is_mipmap(minfilter) && !gl_ignore_mipmaps;
bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
#ifndef NDEBUG
if (gl_force_mipmaps) {
@ -9837,7 +9838,7 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
bool uses_mipmaps = Texture::is_mipmap(minfilter) && !gl_ignore_mipmaps;
bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
#ifndef NDEBUG
if (gl_force_mipmaps) {
@ -9948,6 +9949,8 @@ apply_texture(TextureContext *tc) {
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
if (_supports_sampler_objects) {
// We support sampler objects. Prepare the sampler object and
// bind it to the indicated texture unit.
@ -9965,8 +9968,6 @@ apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
}
} else {
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
// We don't support sampler objects. We'll have to bind the
// texture and change the texture parameters if they don't match.
if (gtc->_active_sampler != sampler) {
@ -9976,6 +9977,19 @@ apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
}
}
if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps) {
// The texture wasn't created with mipmaps, but we are trying
// to sample it with mipmaps. We will need to reload it.
apply_texture(tc);
gtc->mark_needs_reload();
bool okflag = upload_texture(gtc, false, true);
if (!okflag) {
GLCAT.error()
<< "Could not load " << *gtc->get_texture() << "\n";
return false;
}
}
report_my_gl_errors();
return true;
}
@ -9990,7 +10004,7 @@ apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
// the texture has no image.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
upload_texture(CLP(TextureContext) *gtc, bool force) {
upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
PStatGPUTimer timer(this, _load_texture_pcollector);
Texture *tex = gtc->get_texture();
@ -10161,7 +10175,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLenum target = get_texture_target(tex->get_texture_type());
bool uses_mipmaps = (tex->uses_mipmaps() && !gl_ignore_mipmaps) || gl_force_mipmaps;
uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
bool needs_reload = false;
if (!gtc->_has_storage ||
gtc->_uses_mipmaps != uses_mipmaps ||
@ -11453,7 +11467,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
tex->set_ram_image(image, compression, page_size);
if (tex->uses_mipmaps()) {
if (gtc->_uses_mipmaps) {
// Also get the mipmap levels.
GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
GLint highest_level = num_expected_levels;

View File

@ -490,7 +490,7 @@ protected:
bool specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler);
bool apply_texture(TextureContext *tc);
bool apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc);
bool upload_texture(CLP(TextureContext) *gtc, bool force);
bool upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps);
bool upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
bool uses_mipmaps, int mipmap_bias,
GLenum texture_target, GLenum page_target,

View File

@ -307,6 +307,38 @@ get_lod_bias() const {
return _lod_bias;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::uses_mipmaps
// Access: Public
// Description: Returns true if the minfilter settings on this
// sampler indicate the use of mipmapping, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
uses_mipmaps() const {
return is_mipmap(get_effective_minfilter());
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::is_mipmap
// Access: Published, Static
// Description: Returns true if the indicated filter type requires
// the use of mipmaps, or false if it does not.
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
is_mipmap(FilterType filter_type) {
switch (filter_type) {
case SamplerState::FT_nearest_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::operator ==
// Access: Published

View File

@ -110,6 +110,9 @@ PUBLISHED:
INLINE PN_stdfloat get_max_lod() const;
INLINE PN_stdfloat get_lod_bias() const;
INLINE bool uses_mipmaps() const;
INLINE static bool is_mipmap(FilterType type);
static string format_filter_type(FilterType ft);
static FilterType string_filter_type(const string &str);

View File

@ -1223,7 +1223,7 @@ get_render_to_texture() const {
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
uses_mipmaps() const {
return is_mipmap(get_effective_minfilter());
return SamplerState::is_mipmap(get_effective_minfilter());
}
////////////////////////////////////////////////////////////////////

View File

@ -1804,26 +1804,6 @@ set_orig_file_size(int x, int y, int z) {
nassertv(z == cdata->_z_size);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::is_mipmap
// Access: Published, Static
// Description: Returns true if the indicated filter type requires
// the use of mipmaps, or false if it does not.
////////////////////////////////////////////////////////////////////
bool Texture::
is_mipmap(FilterType filter_type) {
switch (filter_type) {
case SamplerState::FT_nearest_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::prepare_now
// Access: Published

View File

@ -458,8 +458,6 @@ PUBLISHED:
INLINE void set_loaded_from_txo();
INLINE bool get_loaded_from_txo() const;
static bool is_mipmap(FilterType type);
INLINE bool get_match_framebuffer_format() const;
INLINE void set_match_framebuffer_format(bool flag);