Support sampler states in tinyGL renderer

This commit is contained in:
rdb 2014-12-12 20:32:36 +01:00
parent 89031b4e48
commit 8a5452b0b6
2 changed files with 65 additions and 46 deletions

View File

@ -34,6 +34,7 @@
#include "lightAttrib.h" #include "lightAttrib.h"
#include "scissorAttrib.h" #include "scissorAttrib.h"
#include "bitMask.h" #include "bitMask.h"
#include "samplerState.h"
#include "zgl.h" #include "zgl.h"
#include "zmath.h" #include "zmath.h"
#include "ztriangle_table.h" #include "ztriangle_table.h"
@ -1717,10 +1718,11 @@ update_texture(TextureContext *tc, bool force) {
if (gtc->was_image_modified() || gltex->num_levels == 0) { if (gtc->was_image_modified() || gltex->num_levels == 0) {
// If the texture image was modified, reload the texture. // If the texture image was modified, reload the texture.
bool okflag = upload_texture(gtc, force); Texture *tex = gtc->get_texture();
bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
if (!okflag) { if (!okflag) {
tinydisplay_cat.error() tinydisplay_cat.error()
<< "Could not load " << *gtc->get_texture() << "\n"; << "Could not load " << *tex << "\n";
return false; return false;
} }
} }
@ -1746,7 +1748,7 @@ update_texture(TextureContext *tc, bool force) {
// true). // true).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool TinyGraphicsStateGuardian:: bool TinyGraphicsStateGuardian::
update_texture(TextureContext *tc, bool force, int stage_index) { update_texture(TextureContext *tc, bool force, int stage_index, bool uses_mipmaps) {
if (!update_texture(tc, force)) { if (!update_texture(tc, force)) {
return false; return false;
} }
@ -1754,6 +1756,17 @@ update_texture(TextureContext *tc, bool force, int stage_index) {
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc); TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
GLTexture *gltex = &gtc->_gltex; GLTexture *gltex = &gtc->_gltex;
if (uses_mipmaps && gltex->num_levels <= 1) {
// We don't have mipmaps, yet we are sampling with mipmaps.
Texture *tex = gtc->get_texture();
bool okflag = upload_texture(gtc, force, true);
if (!okflag) {
tinydisplay_cat.error()
<< "Could not load " << *tex << "\n";
return false;
}
}
_c->current_textures[stage_index] = gltex; _c->current_textures[stage_index] = gltex;
ZTextureDef *texture_def = &_c->zb->current_textures[stage_index]; ZTextureDef *texture_def = &_c->zb->current_textures[stage_index];
@ -2275,8 +2288,11 @@ do_issue_texture() {
return; return;
} }
// Get the sampler state that we are supposed to use.
const SamplerState &sampler = _target_texture->get_on_sampler(stage);
// Then, turn on the current texture mode. // Then, turn on the current texture mode.
if (!update_texture(tc, false, si)) { if (!update_texture(tc, false, si, sampler.uses_mipmaps())) {
return; return;
} }
@ -2300,10 +2316,10 @@ do_issue_texture() {
// Fill in the filter func pointers. These may not actually get // Fill in the filter func pointers. These may not actually get
// called, if we decide below we can inline the filters. // called, if we decide below we can inline the filters.
SamplerState::FilterType minfilter = texture->get_minfilter(); SamplerState::FilterType minfilter = sampler.get_minfilter();
SamplerState::FilterType magfilter = texture->get_magfilter(); SamplerState::FilterType magfilter = sampler.get_magfilter();
if (td_ignore_mipmaps && Texture::is_mipmap(minfilter)) { if (td_ignore_mipmaps && SamplerState::is_mipmap(minfilter)) {
// Downgrade mipmaps. // Downgrade mipmaps.
if (minfilter == SamplerState::FT_nearest_mipmap_nearest) { if (minfilter == SamplerState::FT_nearest_mipmap_nearest) {
minfilter = SamplerState::FT_nearest; minfilter = SamplerState::FT_nearest;
@ -2319,7 +2335,7 @@ do_issue_texture() {
magfilter = SamplerState::FT_nearest; magfilter = SamplerState::FT_nearest;
} else if (quality_level == Texture::QL_normal) { } else if (quality_level == Texture::QL_normal) {
if (Texture::is_mipmap(minfilter)) { if (SamplerState::is_mipmap(minfilter)) {
minfilter = SamplerState::FT_nearest_mipmap_nearest; minfilter = SamplerState::FT_nearest_mipmap_nearest;
} else { } else {
minfilter = SamplerState::FT_nearest; minfilter = SamplerState::FT_nearest;
@ -2327,15 +2343,15 @@ do_issue_texture() {
magfilter = SamplerState::FT_nearest; magfilter = SamplerState::FT_nearest;
} else if (quality_level == Texture::QL_best) { } else if (quality_level == Texture::QL_best) {
minfilter = texture->get_effective_minfilter(); minfilter = sampler.get_effective_minfilter();
magfilter = texture->get_effective_magfilter(); magfilter = sampler.get_effective_magfilter();
} }
texture_def->tex_minfilter_func = get_tex_filter_func(minfilter); texture_def->tex_minfilter_func = get_tex_filter_func(minfilter);
texture_def->tex_magfilter_func = get_tex_filter_func(magfilter); texture_def->tex_magfilter_func = get_tex_filter_func(magfilter);
SamplerState::WrapMode wrap_u = texture->get_wrap_u(); SamplerState::WrapMode wrap_u = sampler.get_wrap_u();
SamplerState::WrapMode wrap_v = texture->get_wrap_v(); SamplerState::WrapMode wrap_v = sampler.get_wrap_v();
if (td_ignore_clamp) { if (td_ignore_clamp) {
wrap_u = SamplerState::WM_repeat; wrap_u = SamplerState::WM_repeat;
wrap_v = SamplerState::WM_repeat; wrap_v = SamplerState::WM_repeat;
@ -2382,7 +2398,7 @@ do_issue_texture() {
all_mipmap_nearest = false; all_mipmap_nearest = false;
} }
if (Texture::is_mipmap(minfilter)) { if (SamplerState::is_mipmap(minfilter)) {
any_mipmap = true; any_mipmap = true;
} }
} }
@ -2500,7 +2516,7 @@ apply_texture(TextureContext *tc) {
// the texture has no image. // the texture has no image.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool TinyGraphicsStateGuardian:: bool TinyGraphicsStateGuardian::
upload_texture(TinyTextureContext *gtc, bool force) { upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps) {
Texture *tex = gtc->get_texture(); Texture *tex = gtc->get_texture();
if (_effective_incomplete_render && !force) { if (_effective_incomplete_render && !force) {
@ -2525,21 +2541,24 @@ upload_texture(TinyTextureContext *gtc, bool force) {
return false; return false;
} }
if (tinydisplay_cat.is_debug()) {
tinydisplay_cat.debug()
<< "loading texture " << tex->get_name() << "\n";
}
#ifdef DO_PSTATS #ifdef DO_PSTATS
_data_transferred_pcollector.add_level(tex->get_ram_image_size()); _data_transferred_pcollector.add_level(tex->get_ram_image_size());
#endif #endif
GLTexture *gltex = &gtc->_gltex; GLTexture *gltex = &gtc->_gltex;
int num_levels = 1; int num_levels = 1;
if (tex->uses_mipmaps()) { if (uses_mipmaps) {
if (!tex->has_all_ram_mipmap_images()) { num_levels = tex->get_expected_num_mipmap_levels();
if (tex->get_num_ram_mipmap_images() < num_levels) {
tex->generate_ram_mipmap_images(); tex->generate_ram_mipmap_images();
} }
num_levels = tex->get_num_ram_mipmap_images(); }
if (tinydisplay_cat.is_debug()) {
tinydisplay_cat.debug()
<< "loading texture " << tex->get_name() << ", "
<< tex->get_x_size() << " x " << tex->get_y_size() << ", mipmaps = "
<< num_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
} }
if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), num_levels)) { if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), num_levels)) {

View File

@ -91,7 +91,7 @@ public:
virtual TextureContext *prepare_texture(Texture *tex, int view); virtual TextureContext *prepare_texture(Texture *tex, int view);
virtual bool update_texture(TextureContext *tc, bool force); virtual bool update_texture(TextureContext *tc, bool force);
bool update_texture(TextureContext *tc, bool force, int stage_index); bool update_texture(TextureContext *tc, bool force, int stage_index, bool uses_mipmaps);
virtual void release_texture(TextureContext *tc); virtual void release_texture(TextureContext *tc);
virtual void do_issue_light(); virtual void do_issue_light();
@ -115,7 +115,7 @@ private:
void set_scissor(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top); void set_scissor(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top);
bool apply_texture(TextureContext *tc); bool apply_texture(TextureContext *tc);
bool upload_texture(TinyTextureContext *gtc, bool force); bool upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps);
bool upload_simple_texture(TinyTextureContext *gtc); bool upload_simple_texture(TinyTextureContext *gtc);
bool setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels); bool setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels);
int get_tex_shift(int orig_size); int get_tex_shift(int orig_size);