]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a Texturing class to encapsulate the state of multiple texturing units
authorMikko Rasa <tdb@tdb.fi>
Thu, 15 Jul 2010 12:11:59 +0000 (12:11 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 15 Jul 2010 12:11:59 +0000 (12:11 +0000)
Make TexEnv::bind const
Propagate changes to GL when changing the currently bound TexEnv
Restore default TexEnv state on unbind
Take GL version into account in TexUnit::get_n_units

source/texenv.cpp
source/texenv.h
source/texturing.cpp [new file with mode: 0644]
source/texturing.h [new file with mode: 0644]
source/texunit.cpp

index e6c06bcbbbcebbf2af37b25d9fe58ce02609e481..3730a7e188606e85bab9e501730665c33eb42cab 100644 (file)
@@ -18,14 +18,18 @@ TexEnv::TexEnv():
 void TexEnv::set_mode(TexEnvMode m)
 {
        mode = m;
+       if(current()==this)
+               glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
 }
 
 void TexEnv::set_color(const Color &c)
 {
        color = c;
+       if(current()==this)
+               glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color.r);
 }
 
-void TexEnv::bind()
+void TexEnv::bind() const
 {
        if(TexUnit::current().set_texenv(this))
        {
@@ -36,7 +40,12 @@ void TexEnv::bind()
 
 void TexEnv::unbind()
 {
-       TexUnit::current().set_texenv(0);
+       if(TexUnit::current().set_texenv(0))
+       {
+               Color black(0, 0, 0, 0);
+               glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, MODULATE);
+               glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &black.r);
+       }
 }
 
 } // namespace GL
index b5fee448d64e5cce152ca4eaa3566e3d4f0c9370..01e4a556b0431cc6ace9e9b3a16d70c60b6b3037 100644 (file)
@@ -36,7 +36,7 @@ public:
        void set_color(const Color &);
        TexEnvMode get_mode() const { return mode; }
        const Color &get_color() const { return color; }
-       void bind();
+       void bind() const;
 
        static void unbind();
 };
diff --git a/source/texturing.cpp b/source/texturing.cpp
new file mode 100644 (file)
index 0000000..69c2b3c
--- /dev/null
@@ -0,0 +1,105 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "texenv.h"
+#include "texture.h"
+#include "texturing.h"
+#include "texunit.h"
+
+namespace Msp {
+namespace GL {
+
+Texturing::~Texturing()
+{
+       if(current()==this)
+               unbind();
+}
+
+void Texturing::attach(unsigned attch, const Texture &tex)
+{
+       set_attachment(attch, &tex, 0);
+}
+
+void Texturing::attach(unsigned attch, const Texture &tex, const TexEnv &env)
+{
+       set_attachment(attch, &tex, &env);
+}
+
+void Texturing::detach(unsigned attch)
+{
+       set_attachment(attch, 0, 0);
+}
+
+void Texturing::set_attachment(unsigned attch, const Texture *tex, const TexEnv *env)
+{
+       if(attch>=TexUnit::get_n_units())
+               throw InvalidParameterValue("Invalid texture attachment");
+
+       if(attachments.size()<=attch)
+               attachments.resize(attch+1);
+
+       attachments[attch].tex = tex;
+       attachments[attch].env = env;
+
+       if(current()==this)
+               bind_attachment(attch);
+}
+
+void Texturing::bind_attachment(unsigned i) const
+{
+       const Attachment &attch = attachments[i];
+       TexUnit::activate(i);
+       if(attch.tex)
+               attch.tex->bind();
+       else
+               Texture::unbind();
+       if(attch.env)
+               attch.env->bind();
+       else
+               TexEnv::unbind();
+}
+
+void Texturing::unbind_attachment(unsigned i)
+{
+       TexUnit::activate(i);
+       Texture::unbind();
+       TexEnv::unbind();
+}
+
+void Texturing::bind() const
+{
+       const Texturing *old = current();
+       if(set_current(this))
+       {
+               for(unsigned i=0; i<attachments.size(); ++i)
+                       bind_attachment(i);
+               if(old)
+               {
+                       for(unsigned i=attachments.size(); i<old->attachments.size(); ++i)
+                               unbind_attachment(i);
+               }
+       }
+}
+
+void Texturing::unbind()
+{
+       const Texturing *old = current();
+       if(set_current(0))
+       {
+               for(unsigned i=old->attachments.size(); i--;)
+                       unbind_attachment(i);
+       }
+}
+
+
+Texturing::Attachment::Attachment():
+       tex(0),
+       env(0)
+{ }
+
+} // namespace GL
+} // namespace Msp;
diff --git a/source/texturing.h b/source/texturing.h
new file mode 100644 (file)
index 0000000..c51782b
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_TEXTURING_H_
+#define MSP_GL_TEXTURING_H_
+
+#include <vector>
+#include "bindable.h"
+
+namespace Msp {
+namespace GL {
+
+class TexEnv;
+class Texture;
+
+class Texturing: public Bindable<Texturing>
+{
+private:
+       struct Attachment
+       {
+               const Texture *tex;
+               const TexEnv *env;
+
+               Attachment();
+       };
+
+       std::vector<Attachment> attachments;
+
+public:
+       ~Texturing();
+
+       void attach(unsigned, const Texture &);
+       void attach(unsigned, const Texture &, const TexEnv &);
+       void detach(unsigned);
+private:
+       void set_attachment(unsigned, const Texture *, const TexEnv *);
+       void bind_attachment(unsigned) const;
+
+       static void unbind_attachment(unsigned);
+
+public:
+       void bind() const;
+
+       static void unbind();
+};
+
+} // namespace GL
+} // namespace Msp;
+
+#endif
index a542796548f0ae120bc9037b81bf0e2e3071c0fd..4d5ff81a297dc9f4d3b1f5dfb564111a3257ecbb 100644 (file)
@@ -41,19 +41,21 @@ unsigned TexUnit::get_n_units()
 {
        static int count = -1;
        if(count<0)
-               // XXX Should use GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS since GL 2.0
-               glGetIntegerv(GL_MAX_TEXTURE_UNITS, &count);
+       {
+               if(is_version_at_least(2, 0) || is_supported("ARB_vertex_shader"))
+                       glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &count);
+               else if(is_version_at_least(1, 3))
+                       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &count);
+               else
+                       count = 1;
+       }
        return count;
 }
 
 TexUnit &TexUnit::activate(unsigned n)
 {
-       if(n>0)
-       {
-               static RequireVersion _ver(1, 3);
-               if(n>=get_n_units())
-                       throw InvalidParameterValue("Invalid texture unit number");
-       }
+       if(n>=get_n_units())
+               throw InvalidParameterValue("Invalid texture unit number");
 
        if(units.size()<=n)
                units.resize(n+1);