From dc1d1159a61f378bda11e5989ad694a86b9a3c77 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 8 Sep 2008 19:39:39 +0000 Subject: [PATCH] Use RAII checks for extensions and versions Add functions for drawing vertex array elements --- source/batch.cpp | 8 +++--- source/blend.cpp | 2 +- source/extension.h | 16 +++++++++++ source/framebuffer.cpp | 2 +- source/immediate.cpp | 2 +- source/mesh.cpp | 6 +++++ source/mesh.h | 1 + source/program.cpp | 59 +++++++++-------------------------------- source/program.h | 3 +++ source/programdata.cpp | 2 +- source/renderbuffer.cpp | 2 +- source/shader.cpp | 28 +++++++++---------- source/shader.h | 3 +++ source/texture3d.cpp | 2 +- source/texunit.cpp | 2 +- source/vertexarray.cpp | 24 +++++++++++++++++ source/vertexarray.h | 17 ++++++++++++ source/vertexbuffer.cpp | 2 +- 18 files changed, 108 insertions(+), 73 deletions(-) diff --git a/source/batch.cpp b/source/batch.cpp index 385b4697..f2a57bcf 100644 --- a/source/batch.cpp +++ b/source/batch.cpp @@ -7,7 +7,7 @@ Distributed under the LGPL #include "batch.h" #include "extension.h" -#include "version_1_2.h" +#include "vertexarray.h" using namespace std; @@ -18,9 +18,7 @@ Batch::Batch(PrimitiveType t): type(t), min_index(0), max_index(0) -{ - require_version(1, 2); -} +{ } Batch &Batch::append(uint i) { @@ -45,7 +43,7 @@ void Batch::append(const vector &ind) 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]); } diff --git a/source/blend.cpp b/source/blend.cpp index 841d88b8..854b2032 100644 --- a/source/blend.cpp +++ b/source/blend.cpp @@ -14,7 +14,7 @@ namespace GL { void blend_equation(BlendEquation eq) { - require_version(1, 2); + static RequireVersion _ver(1, 2); glBlendEquation(eq); } diff --git a/source/extension.h b/source/extension.h index aec516e2..4410cc3c 100644 --- a/source/extension.h +++ b/source/extension.h @@ -38,11 +38,27 @@ Checks that an extension is supported and throws if it isn't. */ 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. */ diff --git a/source/framebuffer.cpp b/source/framebuffer.cpp index d9d873bb..97a0147d 100644 --- a/source/framebuffer.cpp +++ b/source/framebuffer.cpp @@ -16,7 +16,7 @@ namespace GL { Framebuffer::Framebuffer() { - require_extension("GL_EXT_framebuffer_object"); + static RequireExtension _ext("GL_EXT_framebuffer_object"); glGenFramebuffersEXT(1, &id); bind(); diff --git a/source/immediate.cpp b/source/immediate.cpp index 8b62d2c4..e12ac9b5 100644 --- a/source/immediate.cpp +++ b/source/immediate.cpp @@ -18,7 +18,7 @@ Immediate::Immediate(VertexFormat f): void Immediate::end_() { array.apply(); - glDrawElements(type, indices.size(), UNSIGNED_INT, &indices[0]); + draw_elements(type, indices.size(), &indices[0]); array.clear(); indices.clear(); diff --git a/source/mesh.cpp b/source/mesh.cpp index 3a275e5b..fec753d0 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -33,6 +33,12 @@ void Mesh::add_batch(const Batch &b) batches.push_back(b); } +void Mesh::clear() +{ + vertices.clear(); + batches.clear(); +} + void Mesh::draw() const { vertices.apply(); diff --git a/source/mesh.h b/source/mesh.h index e3753f8b..633cf3ab 100644 --- a/source/mesh.h +++ b/source/mesh.h @@ -43,6 +43,7 @@ public: const VertexArray &get_vertices() const { return vertices; } void add_batch(const Batch &b); const std::list &get_batches() { return batches; } + void clear(); void draw() const; }; diff --git a/source/program.cpp b/source/program.cpp index eed8b87a..1b8ffe4d 100644 --- a/source/program.cpp +++ b/source/program.cpp @@ -19,28 +19,29 @@ namespace Msp { 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) @@ -77,6 +78,7 @@ void Program::set_del_shaders(bool ds) void Program::bind_attribute(uint index, const string &name) { + static RequireExtension _ext("GL_ARB_vertex_shader"); glBindAttribLocationARB(id, index, name.c_str()); } @@ -120,41 +122,6 @@ int Program::get_uniform_location(const string &n) const 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) diff --git a/source/program.h b/source/program.h index 82d06a10..fde4d854 100644 --- a/source/program.h +++ b/source/program.h @@ -47,6 +47,9 @@ public: Program(); Program(const std::string &, const std::string &); +private: + void init(); +public: virtual ~Program(); void attach_shader(Shader &shader); diff --git a/source/programdata.cpp b/source/programdata.cpp index 2a8b5970..a7a9b037 100644 --- a/source/programdata.cpp +++ b/source/programdata.cpp @@ -17,7 +17,7 @@ namespace GL { ProgramData::ProgramData() { - require_extension("GL_ARB_shader_objects"); + static RequireExtension _ext("GL_ARB_shader_objects"); } ProgramData::~ProgramData() diff --git a/source/renderbuffer.cpp b/source/renderbuffer.cpp index 49e0b74f..0f52ff59 100644 --- a/source/renderbuffer.cpp +++ b/source/renderbuffer.cpp @@ -14,7 +14,7 @@ namespace GL { Renderbuffer::Renderbuffer() { - require_extension("GL_EXT_framebuffer_object"); + static RequireExtension _ext("GL_EXT_framebuffer_object"); glGenRenderbuffersEXT(1, &id); bind(); diff --git a/source/shader.cpp b/source/shader.cpp index 3c012426..93edafb4 100644 --- a/source/shader.cpp +++ b/source/shader.cpp @@ -15,29 +15,29 @@ using namespace std; 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() diff --git a/source/shader.h b/source/shader.h index cd01f2ac..06f769cc 100644 --- a/source/shader.h +++ b/source/shader.h @@ -26,6 +26,9 @@ class 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); diff --git a/source/texture3d.cpp b/source/texture3d.cpp index 2fc4f997..5f864968 100644 --- a/source/texture3d.cpp +++ b/source/texture3d.cpp @@ -22,7 +22,7 @@ Texture3D::Texture3D(): height(0), depth(0) { - require_version(1, 3); + static RequireVersion _ver(1, 3); target=GL_TEXTURE_3D; bind(); diff --git a/source/texunit.cpp b/source/texunit.cpp index ba3e7ca6..7aced5cc 100644 --- a/source/texunit.cpp +++ b/source/texunit.cpp @@ -34,7 +34,7 @@ TexUnit &TexUnit::activate(unsigned n) 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]; diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index c166e987..3c17141c 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -5,7 +5,9 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include "extension.h" #include "gl.h" +#include "version_1_2.h" #include "vertexarray.h" #include "vertexbuffer.h" @@ -167,5 +169,27 @@ VertexArray::Loader::Loader(VertexArray &a): add("color4", static_cast(&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 diff --git a/source/vertexarray.h b/source/vertexarray.h index 8e72d955..02fa64f7 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -62,6 +62,23 @@ private: 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 diff --git a/source/vertexbuffer.cpp b/source/vertexbuffer.cpp index e3680811..395334b3 100644 --- a/source/vertexbuffer.cpp +++ b/source/vertexbuffer.cpp @@ -14,7 +14,7 @@ namespace GL { VertexBuffer::VertexBuffer() { - require_extension("GL_ARB_vertex_buffer_object"); + static RequireExtension _ext("GL_ARB_vertex_buffer_object"); glGenBuffersARB(1, &id); } -- 2.45.2