From: Mikko Rasa Date: Sat, 25 Aug 2012 16:47:11 +0000 (+0300) Subject: More complete support for textures X-Git-Url: http://git.tdb.fi/?p=gldbg.git;a=commitdiff_plain;h=8ac18c1745c64441dbbdc130b1c396dcde9b21a7 More complete support for textures Trace 1D, 3D and cube map texture images, as well as texture enable state. --- diff --git a/flavors/gl/source/glstate.cpp b/flavors/gl/source/glstate.cpp index 750d703..fc355c7 100644 --- a/flavors/gl/source/glstate.cpp +++ b/flavors/gl/source/glstate.cpp @@ -80,6 +80,8 @@ GlState::GlState(): decoder->glGetIntegerv = glGetIntegerv; + decoder->glEnable = glEnable; + decoder->glDisable = glDisable; decoder->glEnableClientState = glEnableClientState; decoder->glDisableClientState = glDisableClientState; @@ -197,6 +199,21 @@ void GlState::glGetIntegerv(void *user_data, GLenum pname, int *param) // Boolean state bool &GlState::get_boolean_state(GLenum state) +{ + if(state==GL_TEXTURE_1D) + return texunits[active_tex].binding_1d.enabled; + else if(state==GL_TEXTURE_2D) + return texunits[active_tex].binding_2d.enabled; + else if(state==GL_TEXTURE_3D) + return texunits[active_tex].binding_3d.enabled; + else if(state==GL_TEXTURE_CUBE_MAP) + return texunits[active_tex].binding_cube.enabled; + + static bool dummy; + return dummy; +} + +bool &GlState::get_boolean_client_state(GLenum state) { if(state==GL_VERTEX_ARRAY) return vertex_array.enabled; @@ -211,16 +228,26 @@ bool &GlState::get_boolean_state(GLenum state) return dummy; } -void GlState::glEnableClientState(void *user_data, GLenum state) +void GlState::glEnable(void *user_data, GLenum state) { reinterpret_cast(user_data)->get_boolean_state(state) = true; } -void GlState::glDisableClientState(void *user_data, GLenum state) +void GlState::glDisable(void *user_data, GLenum state) { reinterpret_cast(user_data)->get_boolean_state(state) = false; } +void GlState::glEnableClientState(void *user_data, GLenum state) +{ + reinterpret_cast(user_data)->get_boolean_client_state(state) = true; +} + +void GlState::glDisableClientState(void *user_data, GLenum state) +{ + reinterpret_cast(user_data)->get_boolean_client_state(state) = false; +} + // Vertex attributes void GlState::glColor3f(void *user_data, float r, float g, float b) @@ -499,10 +526,36 @@ void GlState::glBindTexture(void *user_data, GLenum target, unsigned id) reinterpret_cast(user_data)->set_current_texture(target, id); } +void GlState::glTexImage1D(void *user_data, GLenum target, int level, int ifmt, int width, int, GLenum, GLenum, const void *) +{ + if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) + tex->set_image_1d(level, ifmt, width); +} + void GlState::glTexImage2D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int, GLenum, GLenum, const void *) +{ + GLenum face = 0; + for(unsigned i=0; i<6; ++i) + if(texture_cube_faces[i]==target) + { + face = target; + target = GL_TEXTURE_CUBE_MAP; + break; + } + + if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) + { + if(face) + tex->set_face_image_2d(face, level, ifmt, width, height); + else + tex->set_image_2d(level, ifmt, width, height); + } +} + +void GlState::glTexImage3D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int depth, int, GLenum, GLenum, const void *) { if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) - tex->set_image_2d(level, ifmt, width, height); + tex->set_image_3d(level, ifmt, width, height, depth); } void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value) diff --git a/flavors/gl/source/glstate.h b/flavors/gl/source/glstate.h index 1119195..ae16deb 100644 --- a/flavors/gl/source/glstate.h +++ b/flavors/gl/source/glstate.h @@ -76,6 +76,10 @@ public: private: bool &get_boolean_state(GLenum); + bool &get_boolean_client_state(GLenum); + + static void glEnable(void *, GLenum); + static void glDisable(void *, GLenum); static void glEnableClientState(void *, GLenum); static void glDisableClientState(void *, GLenum); @@ -136,7 +140,9 @@ private: static void glActiveTexture(void *, unsigned); static void glBindTexture(void *, GLenum, unsigned); + static void glTexImage1D(void *, GLenum, int, int, int, int, GLenum, GLenum, const void *); static void glTexImage2D(void *, GLenum, int, int, int, int, int, GLenum, GLenum, const void *); + static void glTexImage3D(void *, GLenum, int, int, int, int, int, int, GLenum, GLenum, const void *); static void glTexParameteri(void *, GLenum, GLenum, int); static void glTexParameteriv(void *, GLenum, GLenum, const int *); static void glDeleteTextures(void *, int, const unsigned *); diff --git a/flavors/gl/source/inspector.cpp b/flavors/gl/source/inspector.cpp index de8031b..b6456ce 100644 --- a/flavors/gl/source/inspector.cpp +++ b/flavors/gl/source/inspector.cpp @@ -150,10 +150,14 @@ void Inspector::cmd_state(const string &args) { printf(" Texture unit %d:\n", i); const TexUnitState &unit = glstate.get_texture_unit(i); - string descr = unit.describe_binding(GL_TEXTURE_2D); - printf(" GL_TEXTURE_2D: %s\n", descr.c_str()); + string descr = unit.describe_binding(GL_TEXTURE_1D); + printf(" GL_TEXTURE_1D: %s\n", descr.c_str()); + descr = unit.describe_binding(GL_TEXTURE_2D); + printf(" GL_TEXTURE_2D: %s\n", descr.c_str()); descr = unit.describe_binding(GL_TEXTURE_3D); - printf(" GL_TEXTURE_3D: %s\n", descr.c_str()); + printf(" GL_TEXTURE_3D: %s\n", descr.c_str()); + descr = unit.describe_binding(GL_TEXTURE_CUBE_MAP); + printf(" GL_TEXTURE_CUBE_MAP: %s\n", descr.c_str()); } printf(" Buffers:\n"); const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER); @@ -198,15 +202,33 @@ void Inspector::cmd_texture(const string &args) printf("Texture object %d\n", id); printf(" Target: %s\n", describe_enum(tex.target, "TextureTarget")); printf(" Images:\n"); - for(unsigned i=0; i=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); } } @@ -94,31 +154,52 @@ string TextureState::describe() const 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(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; } @@ -128,17 +209,43 @@ const TextureState *TexUnitState::get_current_texture(GLenum target) const return const_cast(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"; } diff --git a/flavors/gl/source/texturestate.h b/flavors/gl/source/texturestate.h index 9bc739b..c340f4b 100644 --- a/flavors/gl/source/texturestate.h +++ b/flavors/gl/source/texturestate.h @@ -14,10 +14,15 @@ struct TexImageState GLenum internal_format; TexImageState(); + + void set_1d(GLenum, unsigned); void set_2d(GLenum, unsigned, unsigned); + void set_3d(GLenum, unsigned, unsigned, unsigned); std::string describe() const; }; +extern GLenum texture_cube_faces[6]; + struct TextureState { unsigned id; @@ -33,21 +38,39 @@ struct TextureState bool generate_mipmap; TextureState(); + + TexImageState &get_image(unsigned); + void set_image_1d(unsigned, GLenum, unsigned); void set_image_2d(unsigned, GLenum, unsigned, unsigned); + void set_face_image_2d(GLenum, unsigned, GLenum, unsigned, unsigned); + void set_image_3d(unsigned, GLenum, unsigned, unsigned, unsigned); + void create_mipmaps(unsigned = 0); void set_parameter(GLenum, const int *); std::string describe() const; }; struct TexUnitState { - AutoConstPtr current_2d; - AutoConstPtr current_3d; + struct Binding + { + bool enabled; + AutoConstPtr current; + + Binding(); + std::string describe() const; + }; - TexUnitState(); + Binding binding_1d; + Binding binding_2d; + Binding binding_3d; + Binding binding_cube; + Binding *get_binding(GLenum); + const Binding *get_binding(GLenum) const; void set_current_texture(GLenum, TextureState *); TextureState *get_current_texture(GLenum); const TextureState *get_current_texture(GLenum) const; + bool is_enabled(GLenum) const; std::string describe_binding(GLenum) const; };