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))
{
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
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();
};
--- /dev/null
+/* $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;
--- /dev/null
+/* $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
{
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);