#include "batch.h"
#include "extension.h"
-#include "version_1_2.h"
+#include "vertexarray.h"
using namespace std;
type(t),
min_index(0),
max_index(0)
-{
- require_version(1, 2);
-}
+{ }
Batch &Batch::append(uint i)
{
void Batch::draw() const
{
- glDrawRangeElements(type, min_index, max_index, indices.size(), GL_UNSIGNED_INT, &indices[0]);
+ draw_range_elements(type, min_index, max_index, indices.size(), &indices[0]);
}
void blend_equation(BlendEquation eq)
{
- require_version(1, 2);
+ static RequireVersion _ver(1, 2);
glBlendEquation(eq);
}
*/
void require_extension(const std::string &);
+/**
+RAII version of require_extension. Useful as a static local variable.
+*/
+struct RequireExtension
+{
+ RequireExtension(const std::string &e) { require_extension(e); }
+};
+
/**
Checks that the OpenGL version is at least a.b and throws if it isn't.
*/
void require_version(unsigned a, unsigned b);
+/**
+RAII version of require_version. Useful as a static local variable.
+*/
+struct RequireVersion
+{
+ RequireVersion(unsigned a, unsigned b) { require_version(a, b); }
+};
+
/**
Returns the address of an extension function.
*/
Framebuffer::Framebuffer()
{
- require_extension("GL_EXT_framebuffer_object");
+ static RequireExtension _ext("GL_EXT_framebuffer_object");
glGenFramebuffersEXT(1, &id);
bind();
void Immediate::end_()
{
array.apply();
- glDrawElements(type, indices.size(), UNSIGNED_INT, &indices[0]);
+ draw_elements(type, indices.size(), &indices[0]);
array.clear();
indices.clear();
batches.push_back(b);
}
+void Mesh::clear()
+{
+ vertices.clear();
+ batches.clear();
+}
+
void Mesh::draw() const
{
vertices.apply();
const VertexArray &get_vertices() const { return vertices; }
void add_batch(const Batch &b);
const std::list<Batch> &get_batches() { return batches; }
+ void clear();
void draw() const;
};
namespace GL {
Program::Program():
- del_shaders(false),
- linked(false)
+ del_shaders(false)
{
- require_extension("GL_ARB_shader_objects");
- require_extension("GL_ARB_vertex_shader");
-
- id=glCreateProgramObjectARB();
+ init();
}
Program::Program(const string &vert, const string &frag):
- del_shaders(true),
- linked(false)
+ del_shaders(true)
{
- require_extension("GL_ARB_shader_objects");
- require_extension("GL_ARB_vertex_shader");
+ init();
- id=glCreateProgramObjectARB();
attach_shader(*new Shader(VERTEX_SHADER, vert));
attach_shader(*new Shader(FRAGMENT_SHADER, frag));
link();
}
+void Program::init()
+{
+ static RequireExtension _ext("GL_ARB_shader_objects");
+
+ linked=false;
+ id=glCreateProgramObjectARB();
+}
+
Program::~Program()
{
if(del_shaders)
void Program::bind_attribute(uint index, const string &name)
{
+ static RequireExtension _ext("GL_ARB_vertex_shader");
glBindAttribLocationARB(id, index, name.c_str());
}
return glGetUniformLocationARB(id, n.c_str());
}
-/*void Program::uniform(int i, int v)
-{
- glUniform1iARB(i, v);
-}
-
-void Program::uniform(int i, float x)
-{
- glUniform1fARB(i, x);
-}
-
-void Program::uniform(int i, float x, float y)
-{
- glUniform2fARB(i, x, y);
-}
-
-void Program::uniform(int i, float x, float y, float z)
-{
- glUniform3fARB(i, x, y, z);
-}
-
-void Program::uniform(int i, float x, float y, float z, float w)
-{
- glUniform4fARB(i, x, y, z, w);
-}
-
-void Program::uniform4(int i, const float *v)
-{
- glUniform4fvARB(i, 1, v);
-}
-
-void Program::uniform_matrix4(int i, const float *v)
-{
- glUniformMatrix4fvARB(i, 1, false, v);
-}*/
-
void Program::unbind()
{
if(cur_prog)
Program();
Program(const std::string &, const std::string &);
+private:
+ void init();
+public:
virtual ~Program();
void attach_shader(Shader &shader);
ProgramData::ProgramData()
{
- require_extension("GL_ARB_shader_objects");
+ static RequireExtension _ext("GL_ARB_shader_objects");
}
ProgramData::~ProgramData()
Renderbuffer::Renderbuffer()
{
- require_extension("GL_EXT_framebuffer_object");
+ static RequireExtension _ext("GL_EXT_framebuffer_object");
glGenRenderbuffersEXT(1, &id);
bind();
namespace Msp {
namespace GL {
-Shader::Shader(ShaderType t):
- compiled(false)
+Shader::Shader(ShaderType t)
{
- if(t==FRAGMENT_SHADER)
- require_extension("GL_ARB_fragment_program");
- else if(t==VERTEX_SHADER)
- require_extension("GL_ARB_vertex_program");
+ init(t);
+}
- id=glCreateShaderObjectARB(t);
+Shader::Shader(ShaderType t, const string &src)
+{
+ init(t);
+
+ source(src);
+ compile();
}
-Shader::Shader(ShaderType t, const string &src):
- compiled(false)
+void Shader::init(ShaderType t)
{
+ compiled=false;
+
if(t==FRAGMENT_SHADER)
- require_extension("GL_ARB_fragment_program");
+ static RequireExtension _ext("GL_ARB_fragment_program");
else if(t==VERTEX_SHADER)
- require_extension("GL_ARB_vertex_program");
+ static RequireExtension _ext("GL_ARB_vertex_program");
id=glCreateShaderObjectARB(t);
-
- source(src);
- compile();
}
Shader::~Shader()
public:
Shader(ShaderType t);
Shader(ShaderType t, const std::string &);
+private:
+ void init(ShaderType);
+public:
~Shader();
void source(sizei count, const char **str, const int *len);
height(0),
depth(0)
{
- require_version(1, 3);
+ static RequireVersion _ver(1, 3);
target=GL_TEXTURE_3D;
bind();
if(cur_unit!=&units[n] && (cur_unit || n))
{
- require_version(1, 3);
+ static RequireVersion _ver(1, 3);
glActiveTexture(GL_TEXTURE0+n);
}
cur_unit=&units[n];
Distributed under the LGPL
*/
+#include "extension.h"
#include "gl.h"
+#include "version_1_2.h"
#include "vertexarray.h"
#include "vertexbuffer.h"
add("color4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
}
+
+void array_element(int i)
+{
+ glArrayElement(i);
+}
+
+void draw_arrays(PrimitiveType mode, int first, sizei count)
+{
+ glDrawArrays(mode, first, count);
+}
+
+void draw_elements(PrimitiveType mode, sizei count, DataType type, const void *indices)
+{
+ glDrawElements(mode, count, type, indices);
+}
+
+void draw_range_elements(PrimitiveType mode, uint low, uint high, sizei count, DataType type, const void *indices)
+{
+ static RequireVersion _ver(1, 2);
+ glDrawRangeElements(mode, low, high, count, type, indices);
+}
+
} // namespace GL
} // namespace Msp
static unsigned enabled_arrays;
};
+void array_element(int);
+void draw_arrays(PrimitiveType, int, sizei);
+void draw_elements(PrimitiveType, sizei, DataType, const void *);
+void draw_range_elements(PrimitiveType, uint, uint, sizei, DataType, const void *);
+
+inline void draw_elements(PrimitiveType mode, sizei count, const unsigned *indices)
+{ draw_elements(mode, count, UNSIGNED_INT, indices); }
+
+inline void draw_elements(PrimitiveType mode, sizei count, const unsigned short *indices)
+{ draw_elements(mode, count, UNSIGNED_SHORT, indices); }
+
+inline void draw_range_elements(PrimitiveType mode, uint low, uint high, sizei count, const unsigned short *indices)
+{ draw_range_elements(mode, low, high, count, UNSIGNED_SHORT, indices); }
+
+inline void draw_range_elements(PrimitiveType mode, uint low, uint high, sizei count, const unsigned *indices)
+{ draw_range_elements(mode, low, high, count, UNSIGNED_INT, indices); }
+
} // namespace GL
} // namespace Msp
VertexBuffer::VertexBuffer()
{
- require_extension("GL_ARB_vertex_buffer_object");
+ static RequireExtension _ext("GL_ARB_vertex_buffer_object");
glGenBuffersARB(1, &id);
}