+++ /dev/null
-extension MSP_legacy_features
+++ /dev/null
-extension NV_primitive_restart
+++ /dev/null
-extension SGIS_generate_mipmap
extension. -->
<extensions>
- <extension name="GL_MSP_legacy_features" supported="gl">
- <require>
- <command name="glEnableClientState" />
- <command name="glDisableClientState" />
-
- <enum name="GL_QUADS" />
- <enum name="GL_QUAD_STRIP" />
- <enum name="GL_LUMINANCE8" />
- <enum name="GL_LUMINANCE8_ALPHA8" />
-
- <enum name="GL_AMBIENT" />
- <enum name="GL_DIFFUSE" />
- <enum name="GL_SPECULAR" />
- <enum name="GL_EMISSION" />
- <enum name="GL_SHININESS" />
- <enum name="GL_LIGHTING" />
- <enum name="GL_LIGHT_MODEL_AMBIENT" />
- <enum name="GL_LIGHT0" />
- <enum name="GL_MAX_LIGHTS" />
- <enum name="GL_POSITION" />
- <enum name="GL_SPOT_DIRECTION" />
- <enum name="GL_SPOT_EXPONENT" />
- <enum name="GL_SPOT_CUTOFF" />
- <enum name="GL_CONSTANT_ATTENUATION" />
- <enum name="GL_LINEAR_ATTENUATION" />
- <enum name="GL_QUADRATIC_ATTENUATION" />
- <command name="glLightModelfv" />
- <command name="glLightf" />
- <command name="glLightfv" />
- <command name="glMaterialf" />
- <command name="glMaterialfv" />
-
- <enum name="GL_FOG" />
- <enum name="GL_FOG_MODE" />
- <enum name="GL_FOG_DENSITY" />
- <enum name="GL_FOG_COLOR" />
- <enum name="GL_EXP" />
- <command name="glFogi" />
- <command name="glFogf" />
- <command name="glFogfv" />
-
- <enum name="GL_MODELVIEW" />
- <enum name="GL_PROJECTION" />
- <command name="glMatrixMode" />
- <command name="glLoadMatrixf" />
-
- <!-- Can't reuse EXT_vertex_array for these, as the functions
- defined there have different signatures. -->
- <enum name="GL_VERTEX_ARRAY" />
- <enum name="GL_NORMAL_ARRAY" />
- <enum name="GL_COLOR_ARRAY" />
- <enum name="GL_TEXTURE_COORD_ARRAY" />
- <command name="glVertexPointer" />
- <command name="glNormalPointer" />
- <command name="glColorPointer" />
- <command name="glTexCoordPointer" />
-
- <command name="glClipPlane" />
- </require>
- </extension>
-
<!-- OpenGL ES does not have glDrawBuffer. -->
<extension name="GL_MSP_buffer_control" supported="gl">
<require>
#include <msp/gl/extensions/arb_draw_instanced.h>
#include <msp/gl/extensions/ext_draw_range_elements.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/gl/extensions/msp_primitive_restart.h>
-#include <msp/gl/extensions/nv_primitive_restart.h>
#include "batch.h"
#include "bindable.h"
#include "buffer.h"
if(other_type!=prim_type)
return false;
else if(prim_type==LINE_STRIP || prim_type==LINE_LOOP || prim_type==TRIANGLE_FAN)
- return MSP_primitive_restart || NV_primitive_restart;
+ return MSP_primitive_restart;
else
return true;
}
if(other.prim_type!=prim_type)
throw invalid_argument("Batch::append");
if(prim_type==LINE_STRIP || prim_type==LINE_LOOP || prim_type==TRIANGLE_FAN)
- {
- if(!MSP_primitive_restart)
- {
- static Require _req(NV_primitive_restart);
- // Make sure we have glEnable/DisableClientState as well
- static Require _req2(MSP_legacy_features);
- }
- }
+ static Require _req(MSP_primitive_restart);
if(other.data.empty())
return *this;
- if(prim_type==POINTS || prim_type==LINES || prim_type==TRIANGLES || prim_type==QUADS)
+ if(prim_type==POINTS || prim_type==LINES || prim_type==TRIANGLES)
;
- else if(MSP_primitive_restart || NV_primitive_restart)
+ else if(MSP_primitive_restart)
{
restart = true;
if(data_type==UNSIGNED_SHORT)
if(size()&1)
append(other.get_index(0));
}
- else if(prim_type==QUAD_STRIP)
- {
- append(get_index(size()-1));
- append(get_index(size()-1));
- append(other.get_index(0));
- append(other.get_index(0));
- }
unsigned count = other.size();
for(unsigned i=0; i<count; ++i)
void Batch::set_restart_index(unsigned index)
{
- if(MSP_primitive_restart)
+ if(index>0)
{
- if(index>0)
- {
- if(!restart_index)
- glEnable(GL_PRIMITIVE_RESTART);
- glPrimitiveRestartIndex(index);
- }
- else
- glDisable(GL_PRIMITIVE_RESTART);
+ if(!restart_index)
+ glEnable(GL_PRIMITIVE_RESTART);
+ glPrimitiveRestartIndex(index);
}
else
- {
- if(index>0)
- {
- if(!restart_index)
- glEnableClientState(GL_PRIMITIVE_RESTART_NV);
- glPrimitiveRestartIndexNV(index);
- }
- else
- glDisableClientState(GL_PRIMITIVE_RESTART_NV);
- }
+ glDisable(GL_PRIMITIVE_RESTART);
restart_index = index;
}
return unproject(Vector4(p.x, p.y, p.z, 1.0f)).slice<3>(0);
}
-void Camera::apply() const
-{
- MatrixStack::projection() = proj_matrix;
- MatrixStack::modelview() = view_matrix;
-}
-
void Camera::update_projection_matrix()
{
float frustum_h = (fov!=Geometry::Angle<float>::zero() ? tan(fov/2.0f)*clip_near : height/2);
Vector4 unproject(const Vector4 &) const;
Vector3 unproject(const Vector3 &) const;
- void apply() const;
-
private:
void update_projection_matrix();
void update_object_matrix();
#include <msp/gl/extensions/msp_clipping.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "clipping.h"
#include "clipplane.h"
-#include "clipunit.h"
#include "matrix.h"
#include "misc.h"
namespace Msp {
namespace GL {
-bool Clipping::bound_with_legacy = false;
+unsigned Clipping::get_n_attach_points()
+{
+ static Require _req(MSP_clipping);
+ static int count = get_i(GL_MAX_CLIP_PLANES);
+ return count;
+}
void Clipping::attach(unsigned i, const ClipPlane &p)
{
- if(i>=ClipUnit::get_n_units())
+ if(i>=get_n_attach_points())
throw out_of_range("Clipping::attach");
if(i>=planes.size())
planes[i] = &p;
if(current()==this)
- {
- if(bound_with_legacy)
- p.bind_to(i);
- else
- glEnable(GL_CLIP_PLANE0+i);
- }
+ glEnable(GL_CLIP_PLANE0+i);
}
void Clipping::detach(unsigned i)
planes[i] = 0;
if(current()==this)
- {
- if(bound_with_legacy)
- ClipPlane::unbind_from(i);
- else
- disable(GL_CLIP_PLANE0+i);
- }
+ disable(GL_CLIP_PLANE0+i);
}
void Clipping::update_shader_data(ProgramData &shdata, const Matrix &view_matrix) const
planes[i]->update_shader_data(shdata, view_inverse, i);
}
-void Clipping::bind(bool legacy) const
+void Clipping::bind() const
{
static Require _req(MSP_clipping);
- if(legacy)
- static Require _req2(MSP_legacy_features);
-
- if(legacy!=bound_with_legacy)
- unbind();
const Clipping *old = current();
if(!set_current(this))
return;
- bound_with_legacy = legacy;
- if(legacy)
+ for(unsigned i=0; i<planes.size(); ++i)
{
- for(unsigned i=0; i<planes.size(); ++i)
- {
- if(planes[i])
- planes[i]->bind_to(i);
- else
- ClipPlane::unbind_from(i);
- }
-
- if(old)
- {
- for(unsigned i=planes.size(); i<old->planes.size(); ++i)
- ClipPlane::unbind_from(i);
- }
+ if(planes[i])
+ enable(GL_CLIP_PLANE0+i);
+ else
+ disable(GL_CLIP_PLANE0+i);
}
- else
+
+ if(old)
{
- for(unsigned i=0; i<planes.size(); ++i)
- {
- if(planes[i])
- enable(GL_CLIP_PLANE0+i);
- else
- disable(GL_CLIP_PLANE0+i);
- }
-
- if(old)
- {
- for(unsigned i=planes.size(); i<old->planes.size(); ++i)
- disable(GL_CLIP_PLANE0+i);
- }
+ for(unsigned i=planes.size(); i<old->planes.size(); ++i)
+ disable(GL_CLIP_PLANE0+i);
}
}
if(!set_current(0))
return;
- if(bound_with_legacy)
- {
- for(unsigned i=0; i<old->planes.size(); ++i)
- if(old->planes[i])
- ClipPlane::unbind_from(i);
- }
- else
- {
- for(unsigned i=0; i<old->planes.size(); ++i)
- if(old->planes[i])
- disable(GL_CLIP_PLANE0+i);
- }
+ for(unsigned i=0; i<old->planes.size(); ++i)
+ if(old->planes[i])
+ disable(GL_CLIP_PLANE0+i);
}
} // namespace GL
private:
std::vector<const ClipPlane *> planes;
- static bool bound_with_legacy;
-
public:
+ static unsigned get_n_attach_points();
+
void attach(unsigned, const ClipPlane &);
void detach(unsigned);
void update_shader_data(ProgramData &, const Matrix &) const;
- void bind(bool legacy = true) const;
+ void bind() const;
static void unbind();
};
-#include <msp/gl/extensions/msp_clipping.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/strings/format.h>
#include "clipplane.h"
-#include "clipunit.h"
#include "gl.h"
#include "matrix.h"
#include "misc.h"
eq(compose(d, -dot(p, d)))
{ }
-void ClipPlane::update(unsigned index) const
-{
- double deq[4];
- for(unsigned i=0; i<4; ++i)
- deq[i] = eq[i];
- glClipPlane(GL_CLIP_PLANE0+index, deq);
-}
-
void ClipPlane::set_equation(const Vector4 &e)
{
eq = e;
- if(ClipUnit *unit = ClipUnit::find_unit(this))
- update(unit->get_index());
}
void ClipPlane::set_plane(const Vector3 &p, const Vector3 &d)
shdata.uniform(format("clip_planes[%d].equation", i), eq*view_inverse);
}
-void ClipPlane::bind_to(unsigned i) const
-{
- Require _req(MSP_clipping);
- Require _req2(MSP_legacy_features);
-
- ClipUnit &unit = ClipUnit::get_unit(i);
- if(unit.set_plane(this))
- {
- enable(GL_CLIP_PLANE0+unit.get_index());
- update(unit.get_index());
- }
-}
-
-void ClipPlane::unbind_from(unsigned i)
-{
- ClipUnit &unit = ClipUnit::get_unit(i);
- if(unit.set_plane(0))
- disable(GL_CLIP_PLANE0+unit.get_index());
-}
-
} // namespace GL
} // namespace Msp
ClipPlane(const Vector4 &);
ClipPlane(const Vector3 &, const Vector3 &);
-private:
- void update(unsigned) const;
-public:
void set_equation(const Vector4 &);
void set_plane(const Vector3 &, const Vector3 &);
void update_shader_data(ProgramData &, const Matrix &, unsigned) const;
-
- void bind_to(unsigned) const;
-
- static void unbind_from(unsigned);
};
} // namespace GL
+++ /dev/null
-#include <msp/gl/extensions/msp_clipping.h>
-#include <stdexcept>
-#include "clipunit.h"
-#include "gl.h"
-#include "misc.h"
-
-using namespace std;
-
-namespace Msp {
-namespace GL {
-
-vector<ClipUnit> ClipUnit::units;
-
-ClipUnit::ClipUnit():
- index(0),
- plane(0)
-{ }
-
-bool ClipUnit::set_plane(const ClipPlane *p)
-{
- bool result = (p!=plane);
- plane = p;
- return result;
-}
-
-unsigned ClipUnit::get_n_units()
-{
- static Require _req(MSP_clipping);
- static int count = get_i(GL_MAX_CLIP_PLANES);
- return count;
-}
-
-ClipUnit &ClipUnit::get_unit(unsigned i)
-{
- if(i>=get_n_units())
- throw out_of_range("ClipUnit::get_unit");
-
- if(units.size()<=i)
- {
- unsigned j = units.size();
- units.resize(i+1, ClipUnit());
- for(; j<units.size(); ++j)
- units[j].index = j;
- }
-
- return units[i];
-}
-
-ClipUnit *ClipUnit::find_unit(const ClipPlane *p)
-{
- for(vector<ClipUnit>::iterator i=units.begin(); i!=units.end(); ++i)
- if(i->plane==p)
- return &*i;
- return 0;
-}
-
-} // namespace GL
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_GL_CLIPUNIT_H_
-#define MSP_GL_CLIPUNIT_H_
-
-#include <vector>
-
-namespace Msp {
-namespace GL {
-
-class ClipPlane;
-
-class ClipUnit
-{
-private:
- unsigned index;
- const ClipPlane *plane;
-
- static std::vector<ClipUnit> units;
-
- ClipUnit();
-
-public:
- unsigned get_index() const { return index; }
- bool set_plane(const ClipPlane *);
- const ClipPlane *get_plane() const { return plane; }
-
- static unsigned get_n_units();
- static ClipUnit &get_unit(unsigned);
- static ClipUnit *find_unit(const ClipPlane *);
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
string renderer = renderer_ptr;
if(renderer.find("Radeon")!=string::npos || renderer.find("AMD")!=string::npos)
{
- /* Radeon doesn't process NV_primitive_restart correctly and treats
- the restart index as a normal element if the indices are stored in a
- buffer. */
- disabled_exts.insert("GL_NV_primitive_restart");
-
// The core primitive restart feature does not work either.
disabled_exts.insert("GL_MSP_primitive_restart");
void Font::build_string(const string &str, StringCodec::Decoder &dec, PrimitiveBuilder &bld) const
{
- MatrixStack::Push push_mtx(bld.matrix());
+ VertexBuilder::PushMatrix push_mtx(bld);
unsigned prev = 0;
unsigned next = 0;
continue;
if(prev)
- bld.matrix() *= Matrix::translation(get_glyph_advance(prev, c), 0, 0);
+ bld.transform(Matrix::translation(get_glyph_advance(prev, c), 0, 0));
create_glyph_quad(j->second, bld);
prev = c;
#include <stdexcept>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/strings/format.h>
#include "light.h"
-#include "lightunit.h"
#include "matrix.h"
#include "misc.h"
#include "programdata.h"
attenuation[2] = 0;
}
-Light::~Light()
-{
- while(LightUnit *unit = LightUnit::find_unit(this))
- unbind_from(unit->get_index());
-}
-
-void Light::update_parameter(int mask, int index) const
-{
- if(index<0)
- {
- LightUnit *unit = LightUnit::find_unit(this);
- if(!unit)
- return;
-
- index = unit->get_index();
- }
-
- GLenum l = GL_LIGHT0+index;
- if(mask&DIFFUSE)
- glLightfv(l, GL_DIFFUSE, &diffuse.r);
- if(mask&SPECULAR)
- glLightfv(l, GL_SPECULAR, &specular.r);
- if(mask&POSITION)
- glLightfv(l, GL_POSITION, &position.x);
- if(mask&SPOT_DIR)
- glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x);
- if(mask&SPOT_EXP)
- glLightf(l, GL_SPOT_EXPONENT, spot_exp);
- if(mask&SPOT_CUTOFF)
- glLightf(l, GL_SPOT_CUTOFF, spot_cutoff.degrees());
- if(mask&ATTENUATION)
- {
- glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
- glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]);
- glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]);
- }
-}
-
void Light::update_matrix()
{
Vector3 up_dir;
void Light::set_diffuse(const Color &c)
{
diffuse = c;
- update_parameter(DIFFUSE);
}
void Light::set_specular(const Color &c)
{
specular = c;
- update_parameter(SPECULAR);
}
void Light::set_matrix(const Matrix &m)
position = matrix.column(3);
spot_dir = normalize(-matrix.column(2).slice<3>(0));
direction = (position.w ? spot_dir : normalize(-position.slice<3>(0)));
- update_parameter(POSITION|SPOT_DIR);
update_matrix();
}
void Light::set_position(const Vector4 &p)
{
position = p;
- update_parameter(POSITION);
if(!position.w)
direction = normalize(-position.slice<3>(0));
update_matrix();
spot_dir = normalize(d);
if(position.w)
direction = spot_dir;
- update_parameter(SPOT_DIR);
update_matrix();
}
throw invalid_argument("Light::set_spot_exponent");
spot_exp = e;
- update_parameter(SPOT_EXP);
}
void Light::set_spot_cutoff(float c)
throw invalid_argument("Light::set_spot_cutoff");
spot_cutoff = c;
- update_parameter(SPOT_CUTOFF);
}
void Light::disable_spot_cutoff()
attenuation[0] = c;
attenuation[1] = l;
attenuation[2] = q;
- update_parameter(ATTENUATION);
}
void Light::update_shader_data(ProgramData &shdata, const Matrix &view_matrix, unsigned i) const
shdata.uniform(base+".specular", specular);
}
-void Light::bind_to(unsigned i) const
-{
- static Require _req(MSP_legacy_features);
-
- LightUnit &unit = LightUnit::get_unit(i);
- if(unit.set_light(this))
- {
- enable(GL_LIGHT0+unit.get_index());
- update_parameter(-1, unit.get_index());
- }
-}
-
-const Light *Light::current(unsigned i)
-{
- return LightUnit::get_unit(i).get_light();
-}
-
-void Light::unbind_from(unsigned i)
-{
- LightUnit &unit = LightUnit::get_unit(i);
- if(unit.set_light(0))
- disable(GL_LIGHT0+unit.get_index());
-}
-
Light::Loader::Loader(Light &l):
DataFile::ObjectLoader<Light>(l)
};
private:
- enum ParameterMask
- {
- DIFFUSE = 1,
- SPECULAR = 2,
- POSITION = 4,
- SPOT_DIR = 8,
- SPOT_EXP = 16,
- SPOT_CUTOFF = 32,
- ATTENUATION = 64
- };
-
Color diffuse;
Color specular;
Vector4 position;
public:
Light();
- ~Light();
private:
- void update_parameter(int, int = -1) const;
void update_matrix();
public:
/** Updates a ProgramData object with the uniforms for the Light. A view
matrix and light source index must be passed in. */
void update_shader_data(ProgramData &, const Matrix &, unsigned) const;
-
- void bind() const { return bind_to(0); }
- void bind_to(unsigned) const;
-
- static const Light *current(unsigned = 0);
- static void unbind() { return unbind_from(0); }
- static void unbind_from(unsigned);
};
} // namespace GL
#include <stdexcept>
#include <cmath>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "error.h"
#include "light.h"
#include "lighting.h"
-#include "lightunit.h"
#include "matrix.h"
#include "misc.h"
lights.resize(i+1);
lights[i] = &l;
- if(current()==this)
- l.bind_to(i);
}
void Lighting::detach(unsigned i)
return;
lights[i] = 0;
- if(current()==this)
- Light::unbind_from(i);
}
const Light *Lighting::get_attached_light(unsigned i) const
lights[i]->update_shader_data(shdata, view_matrix, i);
}
-void Lighting::bind() const
-{
- static Require _req(MSP_legacy_features);
- if(lights.size()>LightUnit::get_n_units())
- throw invalid_operation("Lighting::bind");
-
- const Lighting *old = current();
- if(!set_current(this))
- return;
-
- enable(GL_LIGHTING);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &ambient.r);
- for(unsigned i=0; i<lights.size(); ++i)
- {
- if(lights[i])
- lights[i]->bind_to(i);
- else
- Light::unbind_from(i);
- }
-
- if(old)
- {
- for(unsigned i=lights.size(); i<old->lights.size(); ++i)
- Light::unbind_from(i);
- }
-
- if(fog_density)
- {
- enable(GL_FOG);
- glFogi(GL_FOG_MODE, GL_EXP);
- glFogf(GL_FOG_DENSITY, fog_density);
- glFogfv(GL_FOG_COLOR, &fog_color.r);
- }
-}
-
-void Lighting::unbind()
-{
- const Lighting *old = current();
- if(!set_current(0))
- return;
-
- for(unsigned i=0; i<old->lights.size(); ++i)
- if(old->lights[i])
- Light::unbind_from(i);
-
- disable(GL_LIGHTING);
- if(old->fog_density)
- disable(GL_FOG);
-}
-
Lighting::Loader::Loader(Lighting &l):
DataFile::ObjectLoader<Lighting>(l)
Encapsulates global lighting parameters and any number of individual light
sources.
*/
-class Lighting: public Bindable<Lighting>
+class Lighting
{
public:
class Loader: public DataFile::ObjectLoader<Lighting>
distance is 50%. */
void set_fog_half_distance(float);
- /** Attaches a light source. If the attachment index is greater than
- LightUnit::get_n_units, the Lighting can't be bound for legacy mode. */
+ /** Attaches a light source. */
void attach(unsigned, const Light &);
/** Detaches a light source. */
/** Updates a ProgramData object with the uniforms for the Lighting,
including all attached light sources. A view matrix must be passed in. */
void update_shader_data(ProgramData &, const Matrix &) const;
-
- void bind() const;
-
- static void unbind();
};
} // namespace GL
+++ /dev/null
-#include <stdexcept>
-#include <msp/gl/extensions/msp_legacy_features.h>
-#include "gl.h"
-#include "misc.h"
-#include "lightunit.h"
-
-using namespace std;
-
-namespace Msp {
-namespace GL {
-
-vector<LightUnit> LightUnit::units;
-
-LightUnit::LightUnit():
- light(0)
-{ }
-
-bool LightUnit::set_light(const Light *l)
-{
- bool result = (l!=light);
- light = l;
- return result;
-}
-
-unsigned LightUnit::get_n_units()
-{
- static int count = (MSP_legacy_features ? get_i(GL_MAX_LIGHTS) : 0);
- return count;
-}
-
-LightUnit &LightUnit::get_unit(unsigned n)
-{
- if(n>=get_n_units())
- throw out_of_range("LightUnit::get_unit");
-
- if(units.size()<=n)
- {
- unsigned i = units.size();
- units.resize(n+1, LightUnit());
- for(; i<units.size(); ++i)
- units[i].index = i;
- }
-
- return units[n];
-}
-
-LightUnit *LightUnit::find_unit(const Light *l)
-{
- for(vector<LightUnit>::iterator i=units.begin(); i!=units.end(); ++i)
- if(i->light==l)
- return &*i;
- return 0;
-}
-
-} // namespace GL
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_GL_LIGHTUNIT_H_
-#define MSP_GL_LIGHTUNIT_H_
-
-#include <vector>
-
-namespace Msp {
-namespace GL {
-
-class Light;
-
-class LightUnit
-{
-private:
- unsigned index;
- const Light *light;
-
- static std::vector<LightUnit> units;
-
- LightUnit();
-
-public:
- unsigned get_index() const { return index; }
- bool set_light(const Light *);
- const Light *get_light() const { return light; }
-
- static unsigned get_n_units();
- static LightUnit &get_unit(unsigned i);
- static LightUnit *find_unit(const Light *);
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
#include "material.h"
#include "resources.h"
set_reflectivity(0);
}
-void Material::update_parameter(int mask) const
-{
- if(cur_obj!=this)
- return;
-
- if(mask&AMBIENT)
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r);
- if(mask&DIFFUSE)
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r);
- if(mask&SPECULAR)
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r);
- if(mask&EMISSION)
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &emission.r);
- if(mask&SHININESS)
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
-}
-
void Material::set_ambient(const Color &a)
{
ambient = a;
shdata.uniform("material.ambient", ambient);
- update_parameter(AMBIENT);
}
void Material::set_diffuse(const Color &d)
{
diffuse = d;
shdata.uniform("material.diffuse", diffuse);
- update_parameter(DIFFUSE);
}
void Material::set_specular(const Color &s)
{
specular = s;
shdata.uniform("material.specular", specular);
- update_parameter(SPECULAR);
}
void Material::set_emission(const Color &e)
{
emission = e;
shdata.uniform("material.emission", emission);
- update_parameter(EMISSION);
}
void Material::set_shininess(float s)
{
shininess = s;
shdata.uniform("material.shininess", shininess);
- update_parameter(SHININESS);
}
void Material::set_reflectivity(float r)
shdata.uniform("reflectivity", reflectivity);
}
-void Material::bind() const
-{
- static Require _req(MSP_legacy_features);
-
- if(set_current(this))
- update_parameter(-1);
-}
-
Material::Loader::Loader(Material &m):
DataFile::CollectionObjectLoader<Material>(m, 0)
soucres and ambient lighting to produce the base color of a surface. Textures
can be used to add detail.
-Material provides a set of uniform variables for use with shaders. Standard
-shaders generated by ProgramBuilder only use it when legacy mode is disabled.
-
-In legacy mode, materials are applied with several calls to glMaterial.
+Material provides a set of uniform variables for use with shaders.
*/
-class Material: public BindableWithDefault<Material>
+class Material
{
public:
class Loader: public DataFile::CollectionObjectLoader<Material>
};
private:
- enum ParameterMask
- {
- AMBIENT = 1,
- DIFFUSE = 2,
- SPECULAR = 4,
- EMISSION = 8,
- SHININESS = 16
- };
-
Color ambient;
Color diffuse;
Color specular;
public:
Material();
-private:
- void update_parameter(int) const;
-
-public:
/** Sets the ambient color of the material. Provided to shaders with the
name material.ambient. */
void set_ambient(const Color &);
float get_shininess() const { return shininess; }
float get_reflectivity() const { return reflectivity; }
- /** Returns the uniforms for the material. Not needed for shaders that use
- the legacy built-in uniform gl_FrontMaterial and have no reflections. */
+ /** Returns the uniforms for the material. */
const ProgramData &get_shader_data() const { return shdata; }
-
- void bind() const;
};
} // namespace GL
#include <algorithm>
#include <cmath>
#include <msp/geometry/affinetransformation.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "error.h"
#include "matrix.h"
return frustum(-hh*a, hh*a, -hh, hh, n, f);
}
-
-GLenum MatrixStack::current_mode = GL_MODELVIEW;
-
-MatrixStack::MatrixStack(GLenum m):
- mode(m)
-{
- matrices.reserve(mode==GL_MODELVIEW ? 32 : 4);
- matrices.push_back(Matrix());
-}
-
-MatrixStack::MatrixStack():
- mode(0)
-{
- matrices.reserve(32);
- matrices.push_back(Matrix());
-}
-
-const Matrix &MatrixStack::top() const
-{
- return matrices.back();
-}
-
-void MatrixStack::load(const Matrix &m)
-{
- matrices.back() = m;
- update();
-}
-
-void MatrixStack::multiply(const Matrix &m)
-{
- matrices.back() *= m;
- update();
-}
-
-void MatrixStack::push()
-{
- matrices.push_back(top());
-}
-
-void MatrixStack::pop()
-{
- if(matrices.size()==1)
- throw stack_underflow("MatrixStack::pop()");
-
- matrices.pop_back();
- update();
-}
-
-void MatrixStack::update()
-{
- if(!mode)
- return;
-
- static Require _req(MSP_legacy_features);
-
- if(mode!=current_mode)
- {
- glMatrixMode(mode);
- current_mode = mode;
- }
-
- glLoadMatrixf(matrices.back().data());
-}
-
-MatrixStack &MatrixStack::operator=(const Matrix &m)
-{
- load(m);
- return *this;
-}
-
-MatrixStack &MatrixStack::operator*=(const Matrix &m)
-{
- multiply(m);
- return *this;
-}
-
-MatrixStack &MatrixStack::modelview()
-{
- static MatrixStack ms(GL_MODELVIEW);
- return ms;
-}
-
-MatrixStack &MatrixStack::projection()
-{
- static MatrixStack ms(GL_PROJECTION);
- return ms;
-}
-
} // namespace GL
} // namespace Msp
static Matrix perspective(const Angle &, float, float, float);
};
-class MatrixStack
-{
-public:
- class Push
- {
- private:
- MatrixStack &stack;
-
- public:
- Push(MatrixStack &s): stack(s) { stack.push(); }
- ~Push() { stack.pop(); }
- };
-
-private:
- GLenum mode;
- std::vector<Matrix> matrices;
-
- static GLenum current_mode;
-
- MatrixStack(const MatrixStack &);
- MatrixStack &operator=(const MatrixStack &);
- MatrixStack(GLenum);
-public:
- MatrixStack();
-
- const Matrix &top() const;
- void load(const Matrix &);
- void multiply(const Matrix &);
- void push();
- void pop();
-private:
- virtual void update();
-
-public:
- MatrixStack &operator=(const Matrix &);
- MatrixStack &operator*=(const Matrix &);
-
- static MatrixStack &modelview();
- static MatrixStack &projection();
-};
-
} // namespace GL
} // namespace Msp
#include <msp/gl/extensions/arb_vertex_array_object.h>
#include <msp/gl/extensions/arb_vertex_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
-#include <msp/gl/extensions/nv_primitive_restart.h>
#include "buffer.h"
#include "error.h"
#include "mesh.h"
if(!vtx_setup)
{
unbind();
- vertices.apply(false);
+ vertices.apply();
}
else if(set_current(this))
{
index_updater(0),
phase(0)
{
- // Make sure the extension is initialized in the rendering thread.
- (void)(bool)NV_primitive_restart;
-
mesh.disallow_rendering = true;
if(mesh.defer_buffers)
mesh.create_buffers();
fmt = LUMINANCE;
else if(conv.get()=="LUMINANCE_ALPHA")
fmt = LUMINANCE_ALPHA;
- else if(conv.get()=="SLUMINANCE")
- fmt = SLUMINANCE;
- else if(conv.get()=="SLUMINANCE_ALPHA")
- fmt = SLUMINANCE_ALPHA;
else
throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get()));
}
{
case SRGB: return RGB;
case SRGB_ALPHA: return RGBA;
- case SLUMINANCE: return LUMINANCE;
- case SLUMINANCE_ALPHA: return LUMINANCE_ALPHA;
default: return unsized;
}
}
case RGBA32F: return RGBA;
case SRGB8_ALPHA8: return SRGB_ALPHA;
case LUMINANCE8: return LUMINANCE;
- case SLUMINANCE8: return SLUMINANCE;
- case LUMINANCE_ALPHA8: return LUMINANCE_ALPHA;
- case SLUMINANCE8_ALPHA8: return SLUMINANCE_ALPHA;
+ case LUMINANCE8_ALPHA8: return LUMINANCE_ALPHA;
case DEPTH_COMPONENT16:
case DEPTH_COMPONENT24:
case DEPTH_COMPONENT32:
case SRGB: return SRGB8;
case SRGB_ALPHA: return SRGB8_ALPHA8;
case LUMINANCE: return LUMINANCE8;
- case SLUMINANCE: return SLUMINANCE8;
case LUMINANCE_ALPHA: return LUMINANCE8_ALPHA8;
- case SLUMINANCE_ALPHA: return SLUMINANCE8_ALPHA8;
default: throw invalid_argument("get_sized_pixelformat");
}
case 2:
case RGBA: return SRGB_ALPHA;
case RGB8: return SRGB8;
case RGBA8: return SRGB8_ALPHA8;
- case LUMINANCE: return SLUMINANCE;
- case LUMINANCE8: return SLUMINANCE8;
- case LUMINANCE_ALPHA: return SLUMINANCE_ALPHA;
- case LUMINANCE_ALPHA8: return SLUMINANCE8_ALPHA8;
default: return pf;
}
}
case DEPTH_COMPONENT:
case RED:
case LUMINANCE:
- case SLUMINANCE:
return 1;
case RG:
case LUMINANCE_ALPHA:
- case SLUMINANCE_ALPHA:
return 2;
case RGB:
case BGR:
case SRGB8_ALPHA8:
case LUMINANCE8:
case LUMINANCE8_ALPHA8:
- case SLUMINANCE8:
- case SLUMINANCE8_ALPHA8:
return 1;
case R16F:
case RG16F:
case SRGB8:
case SRGB_ALPHA:
case SRGB8_ALPHA8:
- case SLUMINANCE:
- case SLUMINANCE8:
- case SLUMINANCE_ALPHA:
- case SLUMINANCE8_ALPHA8:
{ static Require _req(EXT_texture_sRGB); }
break;
case BGR:
#include <msp/gl/extensions/arb_texture_rg.h>
#include <msp/gl/extensions/ext_bgra.h>
#include <msp/gl/extensions/ext_texture_srgb.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/gl/extensions/oes_required_internalformat.h>
#include <msp/gl/extensions/oes_texture_stencil8.h>
LUMINANCE = GL_LUMINANCE,
LUMINANCE8 = GL_LUMINANCE8,
LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
- LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8,
-
- // Deprecated
- SLUMINANCE = GL_SLUMINANCE,
- SLUMINANCE8 = GL_SLUMINANCE8,
- SLUMINANCE_ALPHA = GL_SLUMINANCE_ALPHA,
- SLUMINANCE8_ALPHA8 = GL_SLUMINANCE8_ALPHA8,
-
- // Typo, deprecated
- LUMINANCE_ALPHA8 = GL_LUMINANCE8_ALPHA8
+ LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8
};
void operator>>(const LexicalConverter &, PixelFormat &);
pt = TRIANGLE_STRIP;
else if(conv.get()=="TRIANGLE_FAN")
pt = TRIANGLE_FAN;
- else if(conv.get()=="QUADS")
- pt = QUADS;
- else if(conv.get()=="QUAD_STRIP")
- pt = QUAD_STRIP;
else
throw lexical_error(format("conversion of '%s' to PrimitiveType", conv.get()));
}
-void require_primitive_type(PrimitiveType type)
-{
- if(type==QUADS || type==QUAD_STRIP)
- static Require _req(MSP_legacy_features);
-}
-
} // namespace GL
} // namespace Msp
#define MSP_GL_PRIMITIVETYPE_H_
#include <msp/strings/lexicalcast.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
namespace Msp {
LINE_LOOP = GL_LINE_LOOP,
TRIANGLES = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
- TRIANGLE_FAN = GL_TRIANGLE_FAN,
- QUADS = GL_QUADS,
- QUAD_STRIP = GL_QUAD_STRIP
+ TRIANGLE_FAN = GL_TRIANGLE_FAN
};
void operator>>(const LexicalConverter &, PrimitiveType &);
-void require_primitive_type(PrimitiveType);
-
} // namespace GL
} // namespace Msp
(*i)->compile();
uniforms.clear();
- legacy_vars = false;
glLinkProgram(id);
linked = get_program_i(id, GL_LINK_STATUS);
info.type = type;
uniforms_by_index[i] = &info;
}
- else
- legacy_vars = true;
}
if(ARB_uniform_buffer_object)
info.size = size;
info.type = type;
}
- else
- legacy_vars = true;
}
}
UniformMap uniforms;
LayoutHash uniform_layout_hash;
AttributeMap attributes;
- bool legacy_vars;
public:
/// Constructs an empty Program with no Shaders attached.
const AttributeInfo &get_attribute_info(const std::string &) const;
int get_attribute_location(const std::string &) const;
- bool uses_legacy_variables() const { return legacy_vars; }
-
void bind() const;
static void unbind();
};
Renderer::Renderer(const Camera *c):
default_camera(c),
changed(0),
- matrices_loaded(false),
state_stack(1)
{
state_stack.reserve(16);
state->camera = &c;
standard_shdata.uniform("projection_matrix", state->camera->get_projection_matrix());
standard_shdata.uniform("eye_world_matrix", state->camera->get_view_matrix());
- changed |= STANDARD_SHDATA|LEGACY_PROJECTION;
+ changed |= STANDARD_SHDATA;
set_matrix(state->camera->get_view_matrix());
}
l->update_shader_data(standard_shdata, state->lighting_matrix);
changed |= STANDARD_SHDATA;
}
- changed |= LEGACY_LIGHTING;
}
void Renderer::set_clipping(const Clipping *c)
c->update_shader_data(standard_shdata, state->clipping_matrix);
changed |= STANDARD_SHDATA;
}
- changed |= LEGACY_CLIPPING;
}
void Renderer::set_shader_program(const Program *p, const ProgramData *d)
standard_shdata.uniform("projection_matrix", Matrix());
standard_shdata.uniform("eye_world_matrix", Matrix());
}
- changed |= STANDARD_SHDATA|LEGACY_PROJECTION;
+ changed |= STANDARD_SHDATA;
}
/* This actually should compare the relevant matrices rather than check for
camera, but in practice lighting and clipping is set right after the camera
state->lighting->update_shader_data(standard_shdata, state->lighting_matrix);
changed |= STANDARD_SHDATA;
}
- changed |= LEGACY_LIGHTING;
}
if(state->clipping!=old_clipping || camera_changed)
{
state->clipping->update_shader_data(standard_shdata, state->clipping_matrix);
changed |= STANDARD_SHDATA;
}
- changed |= LEGACY_CLIPPING;
}
}
Mesh::unbind();
Texturing::unbind();
Texture::unbind_from(0);
- Material::unbind();
- Lighting::unbind();
Clipping::unbind();
Program::unbind();
VertexSetup::unbind();
Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
WindingTest::unbind();
-
- if(matrices_loaded)
- {
- MatrixStack::projection().pop();
- MatrixStack::modelview().pop();
- matrices_loaded = false;
- }
}
void Renderer::exclude(const Renderable &renderable)
/* We (mostly) let the objects themselves figure out if the binding has
changed */
- bool legacy_bindings = (!state->shprog || state->shprog->uses_legacy_variables());
- bool legacy_textures = !state->shprog;
-
if(state->texturing)
- state->texturing->bind(legacy_textures);
+ state->texturing->bind();
else
{
Texturing::unbind();
if(state->texture)
- state->texture->bind_to(0, legacy_textures);
+ state->texture->bind_to(0);
else
Texture::unbind_from(0);
}
- if(legacy_bindings)
- {
- if(state->material)
- state->material->bind();
- else
- Material::unbind();
-
- if(changed&LEGACY_LIGHTING)
- {
- if(state->lighting)
- {
- MatrixStack::modelview() = state->lighting_matrix;
- state->lighting->bind();
- changed = (changed&~LEGACY_LIGHTING)|LEGACY_MATRIX;
- }
- else
- Lighting::unbind();
- }
- }
-
if(state->clipping)
- {
- if(legacy_bindings)
- {
- if(changed&LEGACY_CLIPPING)
- {
- MatrixStack::modelview() = state->clipping_matrix;
- state->clipping->bind(true);
- changed = (changed&~LEGACY_CLIPPING)|LEGACY_MATRIX;
- }
- }
- else
- state->clipping->bind(false);
- }
+ state->clipping->bind();
else
Clipping::unbind();
bool shprog_changed = (state->shprog!=Program::current());
state->shprog->bind();
- if(!legacy_bindings)
+ if(changed&MATRIX)
+ {
+ standard_shdata.uniform("eye_obj_matrix", state->modelview_matrix);
+ LinAl::SquareMatrix<float, 3> nm = state->modelview_matrix.block<3, 3>(0, 0);
+ nm = transpose(invert(nm));
+ standard_shdata.uniform_matrix3("eye_obj_normal_matrix", &nm(0, 0));
+ changed = (changed&~MATRIX)|STANDARD_SHDATA;
+ }
+
+ if(state->material && ((changed&MATERIAL_SHDATA) || shprog_changed))
{
- if(changed&MODERN_MATRIX)
- {
- standard_shdata.uniform("eye_obj_matrix", state->modelview_matrix);
- LinAl::SquareMatrix<float, 3> nm = state->modelview_matrix.block<3, 3>(0, 0);
- nm = transpose(invert(nm));
- standard_shdata.uniform_matrix3("eye_obj_normal_matrix", &nm(0, 0));
- changed = (changed&~MODERN_MATRIX)|STANDARD_SHDATA;
- }
-
- if(state->material && ((changed&MATERIAL_SHDATA) || shprog_changed))
- {
- state->material->get_shader_data().apply();
- changed &= ~MATERIAL_SHDATA;
- }
-
- if((changed&STANDARD_SHDATA) || shprog_changed)
- {
- standard_shdata.apply();
- changed &= ~STANDARD_SHDATA;
- }
+ state->material->get_shader_data().apply();
+ changed &= ~MATERIAL_SHDATA;
+ }
+
+ if((changed&STANDARD_SHDATA) || shprog_changed)
+ {
+ standard_shdata.apply();
+ changed &= ~STANDARD_SHDATA;
}
bool extra_shdata = (shdata_stack.size()>state->shdata_count);
Program::unbind();
if(state->mesh)
- {
- if(legacy_bindings)
- {
- Mesh::unbind();
- state->mesh->get_vertices().apply();
- if(const Buffer *ibuf = state->mesh->get_index_buffer())
- ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
- else
- Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
- }
- else
- state->mesh->bind();
- }
+ state->mesh->bind();
else
{
Mesh::unbind();
}
else
WindingTest::unbind();
-
- if(legacy_bindings)
- {
- if(!matrices_loaded)
- {
- MatrixStack::modelview().push();
- MatrixStack::projection().push();
- matrices_loaded = true;
- }
-
- if(changed&LEGACY_PROJECTION)
- {
- MatrixStack::projection() = state->camera->get_projection_matrix();
- changed &= ~LEGACY_PROJECTION;
- }
-
- if(changed&LEGACY_MATRIX)
- {
- MatrixStack::modelview() = state->modelview_matrix;
- changed &= ~LEGACY_MATRIX;
- }
- }
}
enum ChangeMask
{
- LEGACY_MATRIX = 1,
- MODERN_MATRIX = 2,
- MATRIX = LEGACY_MATRIX|MODERN_MATRIX,
- LEGACY_LIGHTING = 4,
- LEGACY_CLIPPING = 8,
+ MATRIX = 2,
SHADER_DATA = 16,
MATERIAL_SHDATA = 32,
- STANDARD_SHDATA = 64,
- LEGACY_PROJECTION = 128
+ STANDARD_SHDATA = 64
};
const Camera *default_camera;
unsigned char changed;
- bool matrices_loaded;
std::vector<State> state_stack;
State *state;
ProgramData standard_shdata;
clear();
width = font.get_string_width(text, dec);
MeshBuilder bld(mesh);
- bld.matrix() *= Matrix::translation(Vector3(-horz_align*width, vert_offset, 0.0f));
+ bld.transform(Matrix::translation(Vector3(-horz_align*width, vert_offset, 0.0f)));
font.build_string(text, dec, bld);
}
#include <msp/gl/extensions/ext_framebuffer_object.h>
#include <msp/gl/extensions/ext_texture3d.h>
#include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
-#include <msp/gl/extensions/sgis_generate_mipmap.h>
#include <msp/io/memory.h>
#include <msp/strings/format.h>
#include "bindable.h"
wrap_s(REPEAT),
wrap_t(REPEAT),
wrap_r(REPEAT),
- auto_gen_mipmap(0),
+ auto_gen_mipmap(false),
compare(false),
cmp_func(LEQUAL),
dirty_params(0)
FormatSwizzle swiz = NO_SWIZZLE;
if(ARB_texture_rg && ARB_texture_swizzle)
{
- if(fmt==LUMINANCE8 || fmt==SLUMINANCE8)
+ if(fmt==LUMINANCE8)
{
fmt = R8;
swiz = R_TO_LUMINANCE;
}
- else if(fmt==LUMINANCE8_ALPHA8 || fmt==SLUMINANCE8_ALPHA8)
+ else if(fmt==LUMINANCE8_ALPHA8)
{
fmt = RG8;
swiz = RG_TO_LUMINANCE_ALPHA;
set_parameter_i(GL_TEXTURE_WRAP_T, wrap_t);
if(mask&WRAP_R)
set_parameter_i(GL_TEXTURE_WRAP_R, wrap_r);
- if(mask&GENERATE_MIPMAP)
- set_parameter_i(GL_GENERATE_MIPMAP, auto_gen_mipmap!=0);
if(mask&COMPARE)
set_parameter_i(GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
if(mask&COMPARE_FUNC)
bool Texture::can_generate_mipmap()
{
- return (EXT_framebuffer_object || SGIS_generate_mipmap);
+ return EXT_framebuffer_object;
}
void Texture::generate_mipmap()
void Texture::set_auto_generate_mipmap(bool gm)
{
- if(EXT_framebuffer_object)
- auto_gen_mipmap = gm;
- else
- {
- if(gm)
- static Require _req(SGIS_generate_mipmap);
+ if(gm)
+ static Require _req(EXT_framebuffer_object);
- auto_gen_mipmap = gm*2;
- update_parameter(GENERATE_MIPMAP);
- }
+ auto_gen_mipmap = gm;
}
void Texture::set_compare_enabled(bool c)
image(img, srgb);
}
-void Texture::bind_to(unsigned i, bool legacy) const
+void Texture::bind_to(unsigned i) const
{
if(!id)
{
}
}
- legacy = (legacy && is_legacy_target(target));
-
TexUnit &unit = TexUnit::get_unit(i);
- const Texture *old = unit.get_texture();
- bool old_legacy = unit.get_texture_legacy();
- if(unit.set_texture(this, legacy))
+ if(unit.set_texture(this))
{
if(manager)
manager->resource_used(*this);
- if(ARB_direct_state_access && !old_legacy && (!unit.supports_legacy() || !legacy))
+ if(ARB_direct_state_access)
glBindTextureUnit(i, id);
else
{
unit.bind();
- if(unit.supports_legacy())
- {
- if(old && old->target!=target && old_legacy)
- glDisable(old->target);
- if((!old || old->target!=target) && legacy)
- glEnable(target);
- }
glBindTexture(target, id);
}
{
TexUnit &unit = TexUnit::get_unit(i);
const Texture *cur = unit.get_texture();
- bool legacy = unit.get_texture_legacy();
if(unit.set_texture(0))
{
- if(ARB_direct_state_access && !legacy)
+ if(ARB_direct_state_access)
glBindTextureUnit(i, 0);
else
{
unit.bind();
glBindTexture(cur->target, 0);
- if(unit.supports_legacy() && legacy)
- glDisable(cur->target);
}
}
}
-bool Texture::is_legacy_target(GLenum target)
-{
- return target<GL_TEXTURE_1D_ARRAY;
-}
-
Texture::Loader::Loader(Texture &t):
DataFile::CollectionObjectLoader<Texture>(t, 0)
WRAP_S = 4,
WRAP_T = 8,
WRAP_R = 16,
- GENERATE_MIPMAP = 32,
COMPARE = 64,
COMPARE_FUNC = 128,
MAX_ANISOTROPY = 256,
TextureWrap wrap_s;
TextureWrap wrap_t;
TextureWrap wrap_r;
- Msp::UInt8 auto_gen_mipmap;
+ bool auto_gen_mipmap;
bool compare;
Predicate cmp_func;
mutable int dirty_params;
GLenum get_target() const { return target; }
unsigned get_id() const { return id; }
- void bind(bool legacy = true) const { bind_to(0, legacy); }
- void bind_to(unsigned, bool = true) const;
+ void bind() const { bind_to(0); }
+ void bind_to(unsigned) const;
static const Texture *current(unsigned = 0);
static void unbind() { unbind_from(0); }
static void unbind_from(unsigned);
-private:
- static bool is_legacy_target(GLenum);
-public:
virtual UInt64 get_data_size() const { return 0; }
};
glTexImage1D(target, level, ifmt, w, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
{
generate_mipmap();
allocated |= (1<<get_n_levels())-1;
else
glTexSubImage1D(target, level, x, wd, fmt, type, data);
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
generate_mipmap();
}
glTexImage2D(target, level, ifmt, w, h, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
{
generate_mipmap();
allocated |= (1<<get_n_levels())-1;
else
glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data);
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
generate_mipmap();
}
glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
{
generate_mipmap();
allocated |= (1<<get_n_levels())-1;
else
glTexSubImage3D(target, level, x, y, z, wd, ht, dp, fmt, type, data);
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
generate_mipmap();
}
// XXX Allocation should be tracked per-face, but we'll run out of bits
allocated |= 1<<level;
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
{
// TODO Only do this once all faces are created
generate_mipmap();
glTexSubImage2D(face, level, x, y, wd, ht, get_upload_format(fmt), type, data);
- if(auto_gen_mipmap==1 && level==0)
+ if(auto_gen_mipmap && level==0)
generate_mipmap();
}
namespace Msp {
namespace GL {
-bool Texturing::legacy_used = true;
-
Texturing::~Texturing()
{
if(current()==this)
attachments[attch] = tex;
if(current()==this)
- bind_attachment(attch, legacy_used);
+ bind_attachment(attch);
}
const Texture *Texturing::get_attached_texture(unsigned i) const
return i<attachments.size() ? attachments[i] : 0;
}
-void Texturing::bind_attachment(unsigned i, bool legacy) const
+void Texturing::bind_attachment(unsigned i) const
{
if(const Texture *tex = attachments[i])
- tex->bind_to(i, legacy);
+ tex->bind_to(i);
else
Texture::unbind_from(i);
}
Texture::unbind_from(i);
}
-void Texturing::bind(bool legacy) const
+void Texturing::bind() const
{
const Texturing *old = current();
- if(set_current(this) || legacy!=legacy_used)
+ if(set_current(this))
{
- legacy_used = legacy;
for(unsigned i=0; i<attachments.size(); ++i)
- bind_attachment(i, legacy);
+ bind_attachment(i);
if(old)
{
for(unsigned i=attachments.size(); i<old->attachments.size(); ++i)
private:
std::vector<const Texture *> attachments;
- static bool legacy_used;
-
public:
~Texturing();
const Texture *get_attached_texture(unsigned) const;
private:
- void bind_attachment(unsigned, bool) const;
+ void bind_attachment(unsigned) const;
static void unbind_attachment(unsigned);
public:
- void bind(bool = true) const;
+ void bind() const;
static void unbind();
};
#include <stdexcept>
#include <msp/gl/extensions/arb_multitexture.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
#include "misc.h"
#include "texunit.h"
TexUnit *TexUnit::cur_unit = 0;
TexUnit::TexUnit():
- legacy(false),
- texture(0),
- tex_legacy(false)
+ texture(0)
{ }
-bool TexUnit::set_texture(const Texture *tex, bool lgc)
+bool TexUnit::set_texture(const Texture *tex)
{
- lgc = (lgc && legacy && tex);
- bool result = (tex!=texture || lgc!=tex_legacy);
+ bool result = (tex!=texture);
texture = tex;
- tex_legacy = lgc;
return result;
}
return count;
}
-unsigned TexUnit::get_n_legacy_units()
-{
- static int count = -1;
- if(count<0)
- {
- if(MSP_legacy_features)
- count = get_i(GL_MAX_TEXTURE_UNITS);
- else
- count = 0;
- }
- return count;
-}
-
TexUnit &TexUnit::get_unit(unsigned n)
{
if(n>0)
if(units.size()<=n)
{
unsigned i = units.size();
- unsigned n_legacy = get_n_legacy_units();
units.resize(n+1, TexUnit());
for(; i<units.size(); ++i)
- {
units[i].index = i;
- units[i].legacy = (i<n_legacy);
- }
}
return units[n];
{
private:
unsigned index;
- bool legacy;
const Texture *texture;
- bool tex_legacy;
static std::vector<TexUnit> units;
static TexUnit *cur_unit;
public:
unsigned get_index() const { return index; }
- bool supports_legacy() const { return legacy; }
- bool set_texture(const Texture *, bool = true);
+ bool set_texture(const Texture *);
const Texture *get_texture() const { return texture; }
- bool get_texture_legacy() const { return tex_legacy; }
void bind();
static unsigned get_n_units();
- static unsigned get_n_legacy_units();
static TexUnit &get_unit(unsigned);
static TexUnit ¤t();
static TexUnit *find_unit(const Texture *);
#include <msp/gl/extensions/arb_multitexture.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
-#include <msp/gl/extensions/msp_legacy_features.h>
#include "buffer.h"
#include "error.h"
#include "gl.h"
namespace Msp {
namespace GL {
-bool VertexArray::legacy_used = false;
-
VertexArray::VertexArray(const VertexFormat &f)
{
reset(f);
clear();
format = f;
stride = get_stride(format);
- legacy = false;
arrays.clear();
arr.component = *c;
arr.offset = offs;
- if(*c<ATTRIB1)
- legacy = true;
-
offs += get_component_size(*c);
}
}
return data.size()*sizeof(float);
}
-void VertexArray::apply(bool use_legacy) const
+void VertexArray::apply() const
{
if(format.empty())
throw invalid_operation("VertexArray::apply");
if(Mesh::current())
throw invalid_operation("VertexArray::apply");
- /* Unbind first if the legacy flag changes. The logic for supporting it
- directly in apply_arrays would get too complicated, and this also allows
- rebinding the same array with different legacy setting. */
- if(legacy_used!=use_legacy)
- unbind();
-
- if(!use_legacy)
- static Require _req(ARB_vertex_shader);
- else if(legacy)
- static Require _req(MSP_legacy_features);
+ static Require _req(ARB_vertex_shader);
const VertexArray *old = current();
/* If the array has been modified, apply it even if it was the last one to
const float *base = (vbuf ? reinterpret_cast<float *>(get_offset()) : &data[0]);
unsigned stride_bytes = stride*sizeof(float);
- apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes, use_legacy);
+ apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes);
}
-void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes, bool use_legacy)
+void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes)
{
- unsigned active_tex = 0;
unsigned n_arrays = arrays ? arrays->size() : 0;
if(old_arrays)
n_arrays = max<unsigned>(n_arrays, old_arrays->size());
unsigned char comp = (arr ? arr->component : old_arr->component);
unsigned sz = get_component_size(comp);
unsigned t = get_component_type(comp);
- if(use_legacy)
- {
- GLenum array_type = 0;
- if(t==get_component_type(VERTEX3))
- {
- if(arr)
- glVertexPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
- array_type = GL_VERTEX_ARRAY;
- }
- else if(t==get_component_type(NORMAL3))
- {
- if(arr)
- glNormalPointer(GL_FLOAT, stride_bytes, base+arr->offset);
- array_type = GL_NORMAL_ARRAY;
- }
- else if(t==get_component_type(COLOR4_FLOAT))
- {
- if(arr)
- {
- if(sz==1)
- glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset);
- else
- glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
- }
- array_type = GL_COLOR_ARRAY;
- }
- else if(comp>=TEXCOORD1 && comp<=TEXCOORD4+12)
- {
- t -= get_component_type(TEXCOORD1);
- if(t>0 || active_tex)
- {
- glClientActiveTexture(GL_TEXTURE0+t);
- active_tex = t;
- }
- if(arr)
- glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
- array_type = GL_TEXTURE_COORD_ARRAY;
- }
-
- if(array_type)
- {
- // Only change enable state if needed
- if(arr && !old_arr)
- glEnableClientState(array_type);
- else if(old_arr && !arr)
- glDisableClientState(array_type);
-
- continue;
- }
- }
if(t>=get_component_type(ATTRIB1))
t -= get_component_type(ATTRIB1);
else if(old_arr && !arr)
glDisableVertexAttribArray(t);
}
-
- if(active_tex)
- glClientActiveTexture(GL_TEXTURE0);
-
- legacy_used = use_legacy;
}
void VertexArray::unbind()
{
const VertexArray *old = current();
if(set_current(0))
- apply_arrays(0, &old->arrays, 0, 0, legacy_used);
+ apply_arrays(0, &old->arrays, 0, 0);
}
class Buffer;
/**
-Stores vertex data. Both legacy and generic attributes are supported. Mixing
-the two is possible but discouraged, as driver-specific issues may arise.
+Stores vertex data.
The array's contents can be modified with the append and modify methods. To
obtain the location of an individual component within the vertex, use
std::vector<float> data;
unsigned stride;
std::vector<Array> arrays;
- bool legacy;
-
- static bool legacy_used;
VertexArray(const VertexArray &);
VertexArray &operator=(const VertexArray &);
const std::vector<float> &get_data() const { return data; }
const float *operator[](unsigned i) const { return &data[0]+i*stride; }
- /** Equivalent to apply(true). For compatibility with the Bindable
- interface. */
+ /// Equivalent to apply(). For compatibility with the Bindable interface.
void bind() const { apply(); }
- /** Applies component arrays to the GL. If legacy is true, they are applied
- as is. If legacy is false, any legacy attributes are converted to generic
- attributes. */
- void apply(bool legacy = true) const;
+ /// Applies component arrays to the GL.
+ void apply() const;
private:
- static void apply_arrays(const std::vector<Array> *, const std::vector<Array> *, const float *, unsigned, bool);
+ static void apply_arrays(const std::vector<Array> *, const std::vector<Array> *, const float *, unsigned);
public:
static void unbind();
};
*/
class VertexBuilder
{
+public:
+ class PushMatrix
+ {
+ private:
+ VertexBuilder &bld;
+ Matrix mtx;
+
+ public:
+ PushMatrix(VertexBuilder &b): bld(b), mtx(bld.mtx) { }
+ ~PushMatrix() { bld.mtx = mtx; }
+ };
+
protected:
- MatrixStack mtx;
+ Matrix mtx;
Vector3 nor;
Color col;
std::map<unsigned, Vector4> texc;
{ mtx *= m; }
const Matrix &get_matrix() const
- { return mtx.top(); }
-
- // Deprecated
- MatrixStack &matrix()
{ return mtx; }
void vertex(float x, float y)
{ vertex(Vector4(v.x, v.y, v.z, 1)); }
void vertex(const Vector4 &v)
- { vertex_(mtx.top()*v); }
+ { vertex_(mtx*v); }
protected:
virtual void vertex_(const Vector4 &) = 0;
void normal(const Vector3 &n)
{
- Vector4 tn = mtx.top()*Vector4(n.x, n.y, n.z, 0);
+ Vector4 tn = mtx*Vector4(n.x, n.y, n.z, 0);
nor = Vector3(tn.x, tn.y, tn.z);
}
void tangent(const Vector3 &t)
{
- Vector4 tt = mtx.top()*Vector4(t.x, t.y, t.z, 0);
+ Vector4 tt = mtx*Vector4(t.x, t.y, t.z, 0);
attrib(get_component_type(TANGENT3), tt);
}
void binormal(const Vector3 &b)
{
- Vector4 tb = mtx.top()*Vector4(b.x, b.y, b.z, 0);
+ Vector4 tb = mtx*Vector4(b.x, b.y, b.z, 0);
attrib(get_component_type(BINORMAL3), tb);
}
namespace Msp {
namespace GL {
-/** A single vertex component. Nvidia drivers have aliasing between the
-fixed-functions and generic vertex attributes, despite the standard not
-allowing it. We use the same attribute indices here to avoid problems. */
+/** A single vertex component. Symbolic names are provided for commonly used
+attributes. These are aliased with with generic attributes, so be careful when
+picking your attribute indices. */
enum VertexComponent
{
VERTEX2 = 1,