From 5172d32d67595ea0b70184fadcfcb8e023cccbc8 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 12 Jan 2011 19:11:50 +0000 Subject: [PATCH] Bind ProgramData to a Program upon construction Add uniform overloads to ProgramData for Vector3, Vector4 and Color Also add overloads that take a uniform name instead of index Implement the uniform_matrix4 method that has been in the header for ages --- source/ambientocclusion.cpp | 24 ++++--- source/bloom.cpp | 33 ++++----- source/bloom.h | 6 +- source/programdata.cpp | 136 ++++++++++++++++++++++++++++++------ source/programdata.h | 35 ++++++++-- source/renderpass.cpp | 11 +-- source/renderpass.h | 1 - source/uniform.cpp | 19 ++++- source/uniform.h | 15 +++- 9 files changed, 210 insertions(+), 70 deletions(-) diff --git a/source/ambientocclusion.cpp b/source/ambientocclusion.cpp index 2775e854..9e376a45 100644 --- a/source/ambientocclusion.cpp +++ b/source/ambientocclusion.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -82,7 +82,9 @@ namespace GL { AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio): occlude_shader(vertex_shader, occlude_fs), + occlude_shdata(occlude_shader), combine_shader(vertex_shader, combine_fs), + combine_shdata(combine_shader), quad(VERTEX2) { occlusion.storage(GL::RGB, w, h); @@ -110,14 +112,14 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio): occlude_texturing.attach(1, rotate_lookup); - occlude_shdata.uniform(occlude_shader.get_uniform_location("depth"), 0); - occlude_shdata.uniform(occlude_shader.get_uniform_location("rotate"), 1); - occlude_shdata.uniform(occlude_shader.get_uniform_location("screen_size"), w, h); + occlude_shdata.uniform("depth", 0); + occlude_shdata.uniform("rotate", 1); + occlude_shdata.uniform("screen_size", w, h); - combine_shdata.uniform(combine_shader.get_uniform_location("color"), 1); - combine_shdata.uniform(combine_shader.get_uniform_location("depth"), 0); - combine_shdata.uniform(combine_shader.get_uniform_location("occlusion"), 2); - combine_shdata.uniform(combine_shader.get_uniform_location("screen_size"), w, h); + combine_shdata.uniform("color", 1); + combine_shdata.uniform("depth", 0); + combine_shdata.uniform("occlusion", 2); + combine_shdata.uniform("screen_size", w, h); set_depth_ratio(depth_ratio); set_darkness(1.5); @@ -135,13 +137,13 @@ void AmbientOcclusion::set_depth_ratio(float depth_ratio) { depth_ratio = 1/depth_ratio; - occlude_shdata.uniform(occlude_shader.get_uniform_location("depth_ratio"), depth_ratio, 1+depth_ratio); - combine_shdata.uniform(combine_shader.get_uniform_location("depth_ratio"), depth_ratio, 1+depth_ratio); + occlude_shdata.uniform("depth_ratio", depth_ratio, 1+depth_ratio); + combine_shdata.uniform("depth_ratio", depth_ratio, 1+depth_ratio); } void AmbientOcclusion::set_darkness(float darkness) { - occlude_shdata.uniform(occlude_shader.get_uniform_location("darkness"), darkness); + occlude_shdata.uniform("darkness", darkness); } void AmbientOcclusion::render(const Texture2D &color, const Texture2D &depth) diff --git a/source/bloom.cpp b/source/bloom.cpp index 1760a6b2..0c2dccec 100644 --- a/source/bloom.cpp +++ b/source/bloom.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -64,23 +64,26 @@ namespace GL { Bloom::Bloom(unsigned w, unsigned h): blur_shader(blur_vs, blur_fs), + blur_shdata_common(blur_shader), + blur_shdata_x(blur_shader), + blur_shdata_y(blur_shader), combine_shader(combine_vs, combine_fs), + combine_shdata(combine_shader), quad(VERTEX2) { int loc = blur_shader.get_uniform_location("delta"); - blur_shdata[0].uniform(loc, 1.0f/w, 0.0f); - blur_shdata[1].uniform(loc, 0.0f, 1.0f/h); + blur_shdata_x.uniform(loc, 1.0f/w, 0.0f); + blur_shdata_y.uniform(loc, 0.0f, 1.0f/h); - loc = blur_shader.get_uniform_location("source"); + blur_shdata_common.uniform("source", 0); for(unsigned i=0; i<2; ++i) { - blur_shdata[i].uniform(loc, 0); tex[i].set_min_filter(NEAREST); tex[i].storage(RGB16F, w, h); } - combine_shdata.uniform(combine_shader.get_uniform_location("source"), 1); - combine_shdata.uniform(combine_shader.get_uniform_location("blurred"), 0); + combine_shdata.uniform("source", 1); + combine_shdata.uniform("blurred", 0); combine_texturing.attach(0, tex[1]); @@ -102,9 +105,7 @@ void Bloom::set_radius(float r) throw InvalidParameterValue("Radius must be positive"); int size = min(static_cast(r*3.0f), 9); - int loc = blur_shader.get_uniform_location("size"); - blur_shdata[0].uniform(loc, size); - blur_shdata[1].uniform(loc, size); + blur_shdata_common.uniform("size", size); vector factors(size*2+1); float sum = 0.0f; @@ -113,19 +114,14 @@ void Bloom::set_radius(float r) sum += (factors[size+i] = exp(-i*i/r)); for(int i=0; i<=size*2; ++i) - { - loc = blur_shader.get_uniform_location(format("factors[%d]", i)); - float f = factors[i]/sum; - blur_shdata[0].uniform(loc, f); - blur_shdata[1].uniform(loc, f); - } + blur_shdata_common.uniform(format("factors[%d]", i), factors[i]/sum); } 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]"); - combine_shdata.uniform(combine_shader.get_uniform_location("strength"), s); + combine_shdata.uniform("strength", s); } void Bloom::render(const Texture2D &src, const Texture2D &) @@ -135,12 +131,13 @@ void Bloom::render(const Texture2D &src, const Texture2D &) { Bind bind_shader(blur_shader); + blur_shdata_common.apply(); Bind bind_fbo(fbo, true); for(unsigned i=0; i<2; ++i) { Bind bind_tex(i ? tex[0] : src); fbo.attach(COLOR_ATTACHMENT0, tex[i], 0); - blur_shdata[i].apply(); + (i ? blur_shdata_y : blur_shdata_x).apply(); quad.draw(); } } diff --git a/source/bloom.h b/source/bloom.h index f930f1cd..2900175f 100644 --- a/source/bloom.h +++ b/source/bloom.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -33,7 +33,9 @@ private: Framebuffer fbo; Texture2D tex[2]; Program blur_shader; - ProgramData blur_shdata[2]; + ProgramData blur_shdata_common; + ProgramData blur_shdata_x; + ProgramData blur_shdata_y; Program combine_shader; ProgramData combine_shdata; Texturing combine_texturing; diff --git a/source/programdata.cpp b/source/programdata.cpp index 9ab0731d..77ff7f50 100644 --- a/source/programdata.cpp +++ b/source/programdata.cpp @@ -1,26 +1,31 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include "color.h" #include "extension.h" +#include "matrix.h" #include "program.h" #include "programdata.h" #include "uniform.h" +#include "vector.h" using namespace std; namespace Msp { namespace GL { -ProgramData::ProgramData() +ProgramData::ProgramData(const Program &p): + program(p) { static RequireExtension _ext("GL_ARB_shader_objects"); } ProgramData::ProgramData(const ProgramData &other): + program(other.program), data(other.data) { for(map::iterator i=data.begin(); i!=data.end(); ++i) @@ -35,12 +40,6 @@ ProgramData::~ProgramData() void ProgramData::uniform(int index, Uniform *uni) { - if(index<0) - { - delete uni; - return; - } - map::iterator i = data.find(index); if(i!=data.end()) { @@ -53,17 +52,20 @@ void ProgramData::uniform(int index, Uniform *uni) void ProgramData::uniform(int index, int v) { - uniform(index, new Uniform1i(v)); + if(index>=0) + uniform(index, new Uniform1i(v)); } void ProgramData::uniform(int index, float v) { - uniform(index, new Uniform1f(v)); + if(index>=0) + uniform(index, new Uniform1f(v)); } void ProgramData::uniform(int index, float v0, float v1) { - uniform(index, new Uniform2f(v0, v1)); + if(index>=0) + uniform(index, new Uniform2f(v0, v1)); } void ProgramData::uniform2(int index, const float *v) @@ -73,7 +75,13 @@ void ProgramData::uniform2(int index, const float *v) void ProgramData::uniform(int index, float v0, float v1, float v2) { - uniform(index, new Uniform3f(v0, v1, v2)); + if(index>=0) + uniform(index, new Uniform3f(v0, v1, v2)); +} + +void ProgramData::uniform(int index, const Vector3 &v) +{ + uniform(index, v.x, v.y, v.z); } void ProgramData::uniform3(int index, const float *v) @@ -83,7 +91,18 @@ void ProgramData::uniform3(int index, const float *v) void ProgramData::uniform(int index, float v0, float v1, float v2, float v3) { - uniform(index, new Uniform4f(v0, v1, v2, v3)); + if(index>=0) + uniform(index, new Uniform4f(v0, v1, v2, v3)); +} + +void ProgramData::uniform(int index, const Vector4 &v) +{ + uniform(index, v.x, v.y, v.z, v.w); +} + +void ProgramData::uniform(int index, const Color &c) +{ + uniform(index, c.r, c.g, c.b, c.a); } void ProgramData::uniform4(int index, const float *v) @@ -91,6 +110,82 @@ void ProgramData::uniform4(int index, const float *v) uniform(index, v[0], v[1], v[2], v[3]); } +void ProgramData::uniform_matrix4(int index, const float *v) +{ + if(index>=0) + uniform(index, new UniformMatrix4x4f(v)); +} + +void ProgramData::uniform_matrix4(int index, const Matrix &m) +{ + if(index>=0) + { + float v[16]; + copy(m.data(), m.data()+16, v); + uniform_matrix4(index, v); + } +} + +void ProgramData::uniform(const string &name, int v) +{ + uniform(program.get_uniform_location(name), v); +} + +void ProgramData::uniform(const string &name, float v) +{ + uniform(program.get_uniform_location(name), v); +} + +void ProgramData::uniform(const string &name, float v0, float v1) +{ + uniform(program.get_uniform_location(name), v0, v1); +} + +void ProgramData::uniform2(const string &name, const float *v) +{ + uniform2(program.get_uniform_location(name), v); +} + +void ProgramData::uniform(const string &name, float v0, float v1, float v2) +{ + uniform(program.get_uniform_location(name), v0, v1, v2); +} + +void ProgramData::uniform(const string &name, const Vector3 &v) +{ + uniform(program.get_uniform_location(name), v); +} + +void ProgramData::uniform3(const string &name, const float *v) +{ + uniform3(program.get_uniform_location(name), v); +} + +void ProgramData::uniform(const string &name, float v0, float v1, float v2, float v3) +{ + uniform(program.get_uniform_location(name), v0, v1, v2, v3); +} + +void ProgramData::uniform(const string &name, const Vector4 &v) +{ + uniform(program.get_uniform_location(name), v); +} + +void ProgramData::uniform4(const string &name, const float *v) +{ + uniform4(program.get_uniform_location(name), v); +} + +void ProgramData::uniform_matrix4(const string &name, const float *v) +{ + uniform_matrix4(program.get_uniform_location(name), v); +} + +void ProgramData::uniform_matrix4(const string &name, const Matrix &m) +{ + uniform_matrix4(program.get_uniform_location(name), m); +} + void ProgramData::apply() const { for(map::const_iterator i=data.begin(); i!=data.end(); ++i) @@ -98,9 +193,8 @@ void ProgramData::apply() const } -ProgramData::Loader::Loader(ProgramData &pd, Program &pr): - DataFile::ObjectLoader(pd), - prog(pr) +ProgramData::Loader::Loader(ProgramData &pd): + DataFile::ObjectLoader(pd) { add("uniform1i", &Loader::uniform1i); add("uniform1f", &Loader::uniform1f); @@ -111,27 +205,27 @@ ProgramData::Loader::Loader(ProgramData &pd, Program &pr): void ProgramData::Loader::uniform1i(const string &n, int v) { - obj.uniform(prog.get_uniform_location(n), v); + obj.uniform(n, v); } void ProgramData::Loader::uniform1f(const string &n, float v) { - obj.uniform(prog.get_uniform_location(n), v); + obj.uniform(n, v); } void ProgramData::Loader::uniform2f(const string &n, float v0, float v1) { - obj.uniform(prog.get_uniform_location(n), v0, v1); + obj.uniform(n, v0, v1); } void ProgramData::Loader::uniform3f(const string &n, float v0, float v1, float v2) { - obj.uniform(prog.get_uniform_location(n), v0, v1, v2); + obj.uniform(n, v0, v1, v2); } void ProgramData::Loader::uniform4f(const string &n, float v0, float v1, float v2, float v3) { - obj.uniform(prog.get_uniform_location(n), v0, v1, v2, v3); + obj.uniform(n, v0, v1, v2, v3); } } // namespace GL diff --git a/source/programdata.h b/source/programdata.h index 51ecc579..4cc2398e 100644 --- a/source/programdata.h +++ b/source/programdata.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -14,8 +14,12 @@ Distributed under the LGPL namespace Msp { namespace GL { +class Color; +class Matrix; class Program; class Uniform; +class Vector3; +class Vector4; /** Stores uniform variables for a shader program. @@ -25,11 +29,8 @@ class ProgramData public: class Loader: public DataFile::ObjectLoader { - private: - Program &prog; - public: - Loader(ProgramData &, Program &); + Loader(ProgramData &); private: void uniform1i(const std::string &, int); void uniform1f(const std::string &, float); @@ -39,24 +40,46 @@ public: }; private: + const Program &program; std::map data; ProgramData &operator=(const ProgramData &); public: - ProgramData(); + explicit ProgramData(const Program &); ProgramData(const ProgramData &); ~ProgramData(); +private: void uniform(int, Uniform *); +public: void uniform(int, int); void uniform(int, float); void uniform(int, float, float); void uniform2(int, const float *); void uniform(int, float, float, float); + void uniform(int, const Vector3 &); void uniform3(int, const float *); void uniform(int, float, float, float, float); + void uniform(int, const Vector4 &); + void uniform(int, const Color &); void uniform4(int, const float *); void uniform_matrix4(int, const float *); + void uniform_matrix4(int, const Matrix &); + + void uniform(const std::string &, int); + void uniform(const std::string &, float); + void uniform(const std::string &, float, float); + void uniform2(const std::string &, const float *); + void uniform(const std::string &, float, float, float); + void uniform(const std::string &, const Vector3 &); + void uniform3(const std::string &, const float *); + void uniform(const std::string &, float, float, float, float); + void uniform(const std::string &, const Vector4 &); + void uniform(const std::string &, const Color &); + void uniform4(const std::string &, const float *); + void uniform_matrix4(const std::string &, const float *); + void uniform_matrix4(const std::string &, const Matrix &); + void apply() const; }; diff --git a/source/renderpass.cpp b/source/renderpass.cpp index 8c4048ca..d15a7098 100644 --- a/source/renderpass.cpp +++ b/source/renderpass.cpp @@ -80,13 +80,6 @@ void RenderPass::Loader::init() add("uniforms", &Loader::uniforms); } -void RenderPass::Loader::finish() -{ - // XXX Make shdata optional - if(obj.shprog && !obj.shdata) - obj.shdata = new ProgramData; -} - void RenderPass::Loader::material_inline() { RefPtr mat = new Material; @@ -113,8 +106,8 @@ void RenderPass::Loader::uniforms() if(!obj.shprog) throw InvalidState("Can't load uniforms without a shader program"); if(!obj.shdata) - obj.shdata = new ProgramData; - load_sub(*obj.shdata, *obj.shprog); + obj.shdata = new ProgramData(*obj.shprog); + load_sub(*obj.shdata); } diff --git a/source/renderpass.h b/source/renderpass.h index 405b813b..5c1b8452 100644 --- a/source/renderpass.h +++ b/source/renderpass.h @@ -39,7 +39,6 @@ public: private: void init(); - virtual void finish(); void material_inline(); void material(const std::string &); void texunit(unsigned); diff --git a/source/uniform.cpp b/source/uniform.cpp index 641552e7..37868e79 100644 --- a/source/uniform.cpp +++ b/source/uniform.cpp @@ -1,10 +1,11 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include #include "arb_shader_objects.h" #include "uniform.h" @@ -94,5 +95,21 @@ Uniform4f *Uniform4f::clone() const return new Uniform4f(v[0], v[1], v[2], v[3]); } + +UniformMatrix4x4f::UniformMatrix4x4f(const float *vp) +{ + std::copy(vp, vp+16, v); +} + +void UniformMatrix4x4f::apply(int index) const +{ + glUniformMatrix4fvARB(index, 1, false, v); +} + +UniformMatrix4x4f *UniformMatrix4x4f::clone() const +{ + return new UniformMatrix4x4f(v); +} + } // namespace GL } // namespace Msp diff --git a/source/uniform.h b/source/uniform.h index ac73e99d..72a1bd2c 100644 --- a/source/uniform.h +++ b/source/uniform.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -92,6 +92,19 @@ public: virtual Uniform4f *clone() const; }; + +class UniformMatrix4x4f: public Uniform +{ +private: + float v[16]; + +public: + UniformMatrix4x4f(const float *); + + virtual void apply(int index) const; + virtual UniformMatrix4x4f *clone() const; +}; + } // namespace GL } // namespace Msp -- 2.43.0