#include "batch.h"
#include "bindable.h"
#include "buffer.h"
+#include "error.h"
#include "extension.h"
#include "nv_primitive_restart.h"
#include "vertexarray.h"
void Batch::set_data_type(DataType t)
{
if(t!=UNSIGNED_BYTE && t!=UNSIGNED_SHORT && t!=UNSIGNED_INT)
- throw InvalidParameterValue("Batch data type must be an unsigned integer");
+ throw invalid_argument("Batch::set_data_type");
if(t==UNSIGNED_BYTE && max_index>0xFE)
- throw InvalidState("UNSIGNED_BYTE can't hold all indices in Batch");
+ throw invalid_operation("Batch::set_data_type");
else if(t==UNSIGNED_SHORT && max_index>0xFFFE)
- throw InvalidState("UNSIGNED_SHORT can't hold all indices in Batch");
+ throw invalid_operation("Batch::set_data_type");
if(data_type==UNSIGNED_BYTE && t==UNSIGNED_SHORT)
expand_data<unsigned char, unsigned short>();
void Batch::use_index_buffer(Buffer *buf, Batch *prev)
{
if(buf && prev && prev->ibuf!=buf)
- throw InvalidParameterValue("Previous batch is not in the same buffer");
+ throw invalid_argument("Batch::use_index_buffer");
if(!buf)
{
void Batch::append(const Batch &other)
{
if(other.prim_type!=prim_type)
- throw InvalidParameterValue("Can't concatenate batches with different primitive types");
+ throw invalid_argument("Batch::append");
if(prim_type==LINE_STRIP || prim_type==LINE_LOOP)
- throw InvalidState("Can't concatenate line strips or loops");
+ throw incompatible_data("Batch::append");
else if(prim_type==POLYGON)
- throw InvalidState("Can't concatenate polygons");
+ throw incompatible_data("Batch::append");
else if(prim_type==TRIANGLE_FAN)
static RequireExtension _ext("GL_NV_primitive_restart");
void Bloom::set_radius(float r)
{
if(r<=0.0f)
- throw InvalidParameterValue("Radius must be positive");
+ throw out_of_range("Bloom::set_radius");
int size = min(static_cast<int>(r*3.0f), 9);
blur_shdata_common.uniform("size", size);
void Bloom::set_strength(float s)
{
if(s<0.0f || s>1.0f)
- throw InvalidParameterValue("Strength must be in the range [0.0, 1.0]");
+ throw out_of_range("Bloom::set_strength");
combine_shdata.uniform("strength", s);
}
+#include <stdexcept>
#include "arb_vertex_buffer_object.h"
#include "extension.h"
#include "buffer.h"
+using namespace std;
+
namespace Msp {
namespace GL {
case ELEMENT_ARRAY_BUFFER: return bound[1];
case PIXEL_PACK_BUFFER: return bound[2];
case PIXEL_UNPACK_BUFFER: return bound[3];
- default: throw InvalidParameterValue("Invalid buffer type");
+ default: throw invalid_argument("Buffer::binding");
}
}
--- /dev/null
+#ifndef MSP_GL_ERROR_H_
+#define MSP_GL_ERROR_H_
+
+#include <stdexcept>
+
+namespace Msp {
+namespace GL {
+
+class unsupported_extension: public std::runtime_error
+{
+public:
+ unsupported_extension(const std::string &w): std::runtime_error(w) { }
+ virtual ~unsupported_extension() throw() { }
+};
+
+class invalid_operation: public std::logic_error
+{
+public:
+ invalid_operation(const std::string &w): std::logic_error(w) { }
+ virtual ~invalid_operation() throw() { }
+};
+
+class stack_underflow: public std::logic_error
+{
+public:
+ stack_underflow(const std::string &w): std::logic_error(w) { }
+ virtual ~stack_underflow() throw() { }
+};
+
+class incompatible_data: public std::logic_error
+{
+public:
+ incompatible_data(const std::string &w): std::logic_error(w) { }
+ virtual ~incompatible_data() throw() { }
+};
+
+class compile_error: public std::runtime_error
+{
+public:
+ compile_error(const std::string &w): std::runtime_error(w) { }
+ virtual ~compile_error() throw() { }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
+++ /dev/null
-#ifndef MSP_GL_EXCEPT_H_
-#define MSP_GL_EXCEPT_H_
-
-#include <msp/core/except.h>
-
-namespace Msp {
-namespace GL {
-
-class IncompatibleData: public Exception
-{
-public:
- IncompatibleData(const std::string &w_): Exception(w_) { }
- ~IncompatibleData() throw() { }
-};
-
-class UnsupportedExtension: public Exception
-{
-public:
- UnsupportedExtension(const std::string &w_): Exception(w_+" is not supported") { }
- ~UnsupportedExtension() throw() { }
-};
-
-class CompileError: public Exception
-{
-public:
- CompileError(const std::string &w_): Exception(w_) { }
- ~CompileError() throw() { }
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
#include "arb_vertex_buffer_object.h"
#include "arb_vertex_program.h"
#include "arb_vertex_shader.h"
+#include "error.h"
#include "ext_framebuffer_blit.h"
#include "ext_framebuffer_multisample.h"
#include "ext_framebuffer_object.h"
-#include "except.h"
#include "extension.h"
#include "gl.h"
#include "nv_primitive_restart.h"
void require_extension(const string &ext)
{
if(!is_supported(ext))
- throw UnsupportedExtension(ext);
+ throw unsupported_extension(ext);
}
const Version &get_gl_version()
void require_version(unsigned a, unsigned b)
{
if(!is_version_at_least(a, b))
- throw UnsupportedExtension(format("OpenGL %d.%d", a, b));
+ throw unsupported_extension(format("OpenGL %d.%d", a, b));
}
ExtFunc *get_proc_address(const string &name)
#ifndef MSP_GL_EXTENSION_H_
#define MSP_GL_EXTENSION_H_
-#include <msp/core/except.h>
+#include <string>
namespace Msp {
namespace GL {
const Texture2D &Font::get_texture() const
{
if(!texture)
- throw InvalidState("No texture");
+ throw logic_error("No texture");
return *texture;
}
+#include "error.h"
#include "extension.h"
#include "ext_framebuffer_blit.h"
#include "ext_framebuffer_object.h"
dirty(0)
{
if(id)
- throw InvalidParameterValue("System framebuffer must have id 0");
+ throw invalid_argument("System framebuffer must have id 0");
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
void Framebuffer::attach(FramebufferAttachment attch, Renderbuffer &rbuf)
{
if(!id)
- throw InvalidState("Can't attach to system framebuffer");
+ throw invalid_operation("Framebuffer::attach");
unsigned i = get_attachment_index(attch);
attachments[i].set(rbuf);
void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, unsigned level)
{
if(!id)
- throw InvalidState("Can't attach to system framebuffer");
+ throw invalid_operation("Framebuffer::attach");
unsigned i = get_attachment_index(attch);
attachments[i].set(tex, level);
void Framebuffer::detach(FramebufferAttachment attch)
{
if(!id)
- throw InvalidState("Can't detach from system framebuffer");
+ throw invalid_operation("Framebuffer::detach");
unsigned i = get_attachment_index(attch);
attachments[i].clear();
#include "batch.h"
+#include "error.h"
#include "immediate.h"
namespace Msp {
void Immediate::reset()
{
if(in_batch)
- throw InvalidState("Can't reset Immediate between begin() and end()");
+ throw invalid_operation("Immediate::reset");
array.clear();
}
-#include "except.h"
+#include <stdexcept>
#include "light.h"
#include "misc.h"
static unsigned max_lights = get_i(GL_MAX_LIGHTS);
if(i>=max_lights)
- throw InvalidParameterValue("Light unit index out of range");
+ throw out_of_range("Light::activate");
if(i>=current_lights.size())
current_lights.resize(i+1);
#include <algorithm>
#include <cmath>
-#include <msp/core/except.h>
+#include "error.h"
#include "matrix.h"
using namespace std;
double Matrix::operator[](unsigned i) const
{
if(i>=16)
- throw InvalidParameterValue("Matrix element index out of range");
+ throw out_of_range("Matrix::operator[]");
return matrix[i];
}
Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f)
{
if(l==r || b==t || n==f)
- throw InvalidParameterValue("Orthogonal projection can't have zero dimension");
+ throw invalid_argument("Matrix::ortho");
Matrix result;
result.matrix[0] = 2/(r-l);
Matrix Matrix::frustum(double l, double r, double b, double t, double n, double f)
{
if(l==r || b==t || n<=0 || f<=n)
- throw InvalidParameterValue("Invalid frustum parameters");
+ throw invalid_argument("Matrix::frustum");
Matrix result;
result.matrix[0] = 2*n/(r-l);
void MatrixStack::pop()
{
if(matrices.size()==1)
- throw InvalidState("Can't pop the last matrix");
+ throw stack_underflow("MatrixStack::pop()");
matrices.pop_back();
update();
else if(m==PROJECTION)
active_stack = &MatrixStack::projection();
else
- throw InvalidParameterValue("Texture matrices are not supported");
+ throw invalid_argument("matrix_mode");
}
void load_identity()
#include <msp/datafile/collection.h>
#include <msp/strings/format.h>
-#include "except.h"
#include "material.h"
#include "mesh.h"
#include "object.h"
void Object::set_mesh(unsigned i, const Mesh *m)
{
if(i>meshes.size())
- throw InvalidParameterValue("LODs must be continuous");
+ throw invalid_argument("Object::set_mesh");
if(i==meshes.size())
meshes.push_back(m);
void Object::Loader::mesh_inline_lod(unsigned l)
{
if(l>obj.meshes.size())
- throw InvalidParameterValue("LODs must be continuous");
+ throw invalid_argument("Object::Loader::mesh_inline_lod");
RefPtr<Mesh> msh = new Mesh;
load_sub(*msh);
-#include "except.h"
+#include <msp/strings/format.h>
#include "pixelformat.h"
using namespace std;
case Graphics::RGBA: return RGBA;
case Graphics::BGR: return BGR;
case Graphics::BGRA: return BGRA;
- default: throw InvalidParameterValue("Unknown Graphics::PixelFormat");
+ default: throw invalid_argument("pixelformat_from_graphics");
}
}
+#include "error.h"
#include "primitivebuilder.h"
+using namespace std;
+
namespace Msp {
namespace GL {
void PrimitiveBuilder::begin(PrimitiveType t)
{
if(in_batch)
- throw InvalidState("begin() already called");
+ throw invalid_operation("PrimitiveBuilder::begin");
type = t;
in_batch = true;
void PrimitiveBuilder::end()
{
if(!in_batch)
- throw InvalidState("end() called without begin()");
+ throw invalid_operation("PrimitiveBuilder::end");
in_batch = false;
void PrimitiveBuilder::offset(unsigned o)
{
if(o>array.size())
- throw InvalidParameterValue("Element offset out of range");
+ throw out_of_range("PrimitiveBuilder::offset");
offs = o;
}
void PrimitiveBuilder::element(unsigned i)
{
if(!in_batch)
- throw InvalidState("Element specification not between begin() and end()");
+ throw invalid_operation("PrimitiveBuilder::element");
if(offs+i>=array.size())
- throw InvalidParameterValue("Element index out of range");
+ throw out_of_range("PrimitiveBuilder::element");
element_(offs+i);
}
PrimitiveType PrimitiveBuilder::get_type() const
{
if(!in_batch)
- throw InvalidState("Not between begin() and end()");
+ throw invalid_operation("PrimitiveBuilder::get_type");
return type;
}
#include <algorithm>
#include "arb_shader_objects.h"
#include "arb_vertex_shader.h"
-#include "except.h"
+#include "error.h"
#include "extension.h"
#include "program.h"
#include "shader.h"
int value;
glGetObjectParameterivARB(id, GL_OBJECT_LINK_STATUS_ARB, &value);
if(!(linked = value))
- throw CompileError(get_info_log());
+ throw compile_error(get_info_log());
glGetObjectParameterivARB(id, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &value);
for(int i=0; i<value; ++i)
void Program::bind() const
{
if(!linked)
- throw InvalidState("Program is not linked");
+ throw invalid_operation("Program::bind");
if(!set_current(this))
return;
-#include <msp/core/except.h>
+#include "error.h"
#include "renderable.h"
#include "renderer.h"
void Renderable::render(const Tag &) const
{
- throw Exception("This Renderable doesn't support rendering without a Renderer");
+ throw invalid_operation("Renderable::render");
}
void Renderable::render(Renderer &renderer, const Tag &tag) const
-#include <msp/core/except.h>
#include "batch.h"
#include "buffer.h"
#include "camera.h"
+#include "error.h"
#include "material.h"
#include "program.h"
#include "programdata.h"
void Renderer::add_shader_data(const ProgramData *d)
{
if(!state->shprog)
- throw InvalidState("No shader program");
+ throw invalid_operation("Renderer::add_shader_data");
state->shdata.push_back(d);
}
void Renderer::pop_state()
{
if(state_stack.size()==1)
- throw InvalidState("Can't pop the last state");
+ throw stack_underflow("Renderer::pop_state");
state_stack.pop_back();
state = &state_stack.back();
void Renderer::draw(const Batch &batch)
{
if(!vertex_array)
- throw InvalidState("Can't draw without a vertex array");
+ throw invalid_operation("Renderer::draw");
apply_state();
#include <msp/core/refptr.h>
#include <msp/datafile/collection.h>
#include <msp/strings/format.h>
+#include "error.h"
#include "material.h"
#include "renderpass.h"
#include "program.h"
void RenderPass::Loader::uniforms()
{
if(!obj.shprog)
- throw InvalidState("Can't load uniforms without a shader program");
+ throw invalid_operation("RenderPass::Loader::uniforms");
if(!obj.shdata)
obj.shdata = new ProgramData(*obj.shprog);
load_sub(*obj.shdata);
void RenderPass::TextureLoader::texenv()
{
- throw Exception("TexEnvs can't be loaded yet");
+ throw runtime_error("TexEnvs can't be loaded yet");
/*env = new TexEnv;
load_sub(*env);*/
}
#include "arb_shader_objects.h"
-#include "except.h"
+#include "error.h"
#include "extension.h"
#include "shader.h"
int value = 0;
glGetObjectParameterivARB(id, GL_OBJECT_COMPILE_STATUS_ARB, &value);
if(!(compiled = value))
- throw CompileError(get_info_log());
+ throw compile_error(get_info_log());
}
string Shader::get_info_log() const
-#include "except.h"
+#include <msp/strings/format.h>
+#include "error.h"
#include "texture.h"
#include "texunit.h"
else if(c.get()=="MIRRORED_REPEAT")
tw = MIRRORED_REPEAT;
else
- throw LexicalError("Invalid input in TextureWrap conversion");
+ throw lexical_error(format("conversion of '%s' to TextureWrap", c.get()));
}
void Texture::bind() const
{
- if(!target)
- throw InvalidState("Attempt to bind a texture without target (should never happen)");
-
const Texture *cur = TexUnit::current().get_texture();
if(cur!=this)
{
#include "bindable.h"
-#include "except.h"
+#include "error.h"
#include "texture2d.h"
using namespace std;
void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht)
{
if(width>0)
- throw InvalidState("Texture storage may only be specified once");
+ throw invalid_operation("Texture2D::storage");
if(wd==0 || ht==0)
- throw InvalidParameterValue("Invalid texture dimensions");
+ throw invalid_argument("Texture2D::storage");
ifmt = fmt;
width = wd;
void Texture2D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
{
- require_storage();
+ if(width==0 || height==0)
+ throw invalid_operation("Texture2D::image");
unsigned w = width;
unsigned h = height;
void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data)
{
- require_storage();
+ if(width==0 || height==0)
+ throw invalid_operation("Texture2D::sub_image");
+
allocate(level);
Bind _bind(this, true);
if(width==0)
storage(fmt, w, h);
else if(w!=width || h!=height)
- throw IncompatibleData("Image does not match texture storage");
+ throw incompatible_data("Texture2D::image");
image(0, fmt, UNSIGNED_BYTE, img.get_data());
}
-void Texture2D::require_storage()
-{
- if(width==0 || height==0)
- throw InvalidState("Texture storage has not been specified");
-}
-
void Texture2D::get_level_size(unsigned level, unsigned &w, unsigned &h)
{
w >>= level;
private:
void image(const Graphics::Image &);
- void require_storage();
void get_level_size(unsigned, unsigned &, unsigned &);
};
#include <cmath>
#include <msp/graphics/image.h>
#include "bindable.h"
-#include "except.h"
+#include "error.h"
#include "extension.h"
#include "texture3d.h"
#include "version_1_2.h"
void Texture3D::storage(PixelFormat f, unsigned w, unsigned h, unsigned d)
{
if(width>0)
- throw InvalidState("Textures storage may only be specified once");
+ throw invalid_operation("Texture3D::storage");
if(w==0 || h==0 || d==0)
- throw InvalidParameterValue("Invalid texture dimensions");
+ throw invalid_argument("Texture3D::storage");
width = w;
height = h;
void Texture3D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
{
- require_storage();
+ if(width==0 || height==0 || depth==0)
+ throw invalid_operation("Texture3D::image");
unsigned w = width;
unsigned h = height;
void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelFormat fmt, DataType type, const void *data)
{
- require_storage();
+ if(width==0 || height==0 || depth==0)
+ throw invalid_operation("Texture3D::image");
+
allocate(level);
Bind _bind(this, true);
if(dp==-1)
{
if(h%w)
- throw IncompatibleData("Image height is not divisible by its width");
+ throw incompatible_data("Texture3D::load_image");
d = h/w;
h = w;
}
for(d=h; d*d>h; d>>=2) ;
for(; d*d<h; ++d) ;
if(d*d!=h)
- throw IncompatibleData("Could not find a square root of texture height");
+ throw incompatible_data("Texture3D::load_image");
h = d;
}
else if(dp>0)
if(width==0)
storage(fmt, w, h, d);
else if(w!=width || h!=height || d!=depth)
- throw IncompatibleData("Image does not match texture storage");
+ throw incompatible_data("Texture3D::load_image");
image(0, fmt, UNSIGNED_INT, img.get_data());
}
-void Texture3D::require_storage()
-{
- if(width==0 || height==0 || depth==0)
- throw InvalidState("Texture storage has not been specified");
-}
-
void Texture3D::get_level_size(unsigned level, unsigned &w, unsigned &h, unsigned &d)
{
w >>= level;
unsigned get_height() const { return height; }
unsigned get_depth() const { return depth; }
private:
- void require_storage();
void get_level_size(unsigned, unsigned &, unsigned &, unsigned &);
};
#include "texturing.h"
#include "texunit.h"
+using namespace std;
+
namespace Msp {
namespace GL {
void Texturing::set_attachment(unsigned attch, const Texture *tex, const TexEnv *env)
{
if(attch>=TexUnit::get_n_units())
- throw InvalidParameterValue("Invalid texture attachment");
+ throw out_of_range("Texturing::set_attachment");
if(attachments.size()<=attch)
attachments.resize(attch+1);
+#include <stdexcept>
#include "extension.h"
#include "gl.h"
#include "texunit.h"
TexUnit &TexUnit::activate(unsigned n)
{
if(n>=get_n_units())
- throw InvalidParameterValue("Invalid texture unit number");
+ throw out_of_range("TexUnit::activate");
if(units.size()<=n)
units.resize(n+1);
#include "arb_vertex_program.h"
#include "buffer.h"
+#include "error.h"
#include "extension.h"
#include "gl.h"
#include "version_1_2.h"
void VertexArray::apply() const
{
if(format.empty())
- throw InvalidState("Trying to apply a vertex array with no data");
+ throw invalid_operation("VertexArray::apply");
if(vbuf)
{
#include <cstring>
+#include <msp/strings/format.h>
#include <msp/strings/lexicalcast.h>
#include <msp/strings/utils.h>
-#include "except.h"
+#include "error.h"
#include "vertexformat.h"
using namespace std;
int VertexFormat::offset(VertexComponent comp, unsigned index) const
{
if((comp<TEXCOORD1 && index>0) || (comp<ATTRIB1 && index>=8) || index>=53)
- throw InvalidParameterValue("Vertex component index out of range");
+ throw out_of_range("VertexFormat::offset");
unsigned type = (comp>>2)+index;
unsigned size = comp&3;
VertexFormat operator,(const VertexFormat &f, unsigned i)
{
if(!f.data)
- throw InvalidState("VertexFormat has no components");
+ throw invalid_operation("VertexFormat::operator,");
VertexFormat r = f;
unsigned char *c = r.data+r.data[0];
if((*c<TEXCOORD1 && i>0) || (*c<ATTRIB1 && i>=8) || i>=53)
- throw InvalidParameterValue("Vertex component index out of range");
+ throw out_of_range("VertexFormat::operator,");
*c += i*4;
return r;
else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='7')
c = static_cast<VertexComponent>(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4);
else
- throw LexicalError("Invalid texture unit in VertexComponent conversion");
+ throw lexical_error(format("conversion of '%s' to VertexComponent", str));
}
else if(str.size()>=9 && !str.compare(0, 6, "ATTRIB") && str[6]>='1' && str[6]<='4' && str[7]=='_')
{
{
n = lexical_cast<unsigned>(str.substr(8));
}
- catch(const LexicalError &)
+ catch(const lexical_error &)
{
- throw LexicalError("Invalid attribute in VertexComponent conversion");
+ throw lexical_error(format("conversion of '%s' to VertexComponent", str));
}
c = static_cast<VertexComponent>(ATTRIB1+(str[6]-'1')+n*4);
}
else
- throw LexicalError("Invalid input in VertexComponent conversion");
+ throw lexical_error(format("conversion of '%s' to VertexComponent", str));
}
// XXX This will go away eventually
+#include <msp/strings/format.h>
#include "windingtest.h"
namespace Msp {
else if(conv.get()=="COUNTERCLOCKWISE")
winding = COUNTERCLOCKWISE;
else
- throw InvalidParameterValue("Invalid FaceWinding");
+ throw lexical_error(format("conversion of '%s' to FaceWinding", conv.get()));
}
WindingTest::WindingTest():