X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fprogramdata.cpp;h=68a6715d419c847c173ba56ab5cc0dac6c329878;hb=5f78db03b3285c977760a41da1e3927720e50352;hp=dba6b06f2cc8a94ca25d1006020fc567f9d1619d;hpb=d971f8d4848c0b3b453c626a2dafe19445e3e5a8;p=libs%2Fgl.git diff --git a/source/programdata.cpp b/source/programdata.cpp index dba6b06f..68a6715d 100644 --- a/source/programdata.cpp +++ b/source/programdata.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include #include "buffer.h" #include "color.h" #include "error.h" @@ -24,7 +26,7 @@ ProgramData::ProgramData(const Program *p): // Blocks are intentionally left uncopied ProgramData::ProgramData(const ProgramData &other): - tied_program(0), + tied_program(other.tied_program), uniforms(other.uniforms), last_block(0), buffer(0), @@ -34,6 +36,23 @@ ProgramData::ProgramData(const ProgramData &other): i->value = i->value->clone(); } +ProgramData::ProgramData(const ProgramData &other, const Program *p): + tied_program(p), + last_block(0), + buffer(0), + dirty(0) +{ + if(tied_program) + { + for(vector::const_iterator i=other.uniforms.begin(); i!=other.uniforms.end(); ++i) + tied_program->get_uniform_info(i->name); + } + + uniforms = other.uniforms; + for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + i->value = i->value->clone(); +} + ProgramData &ProgramData::operator=(const ProgramData &other) { tied_program = other.tied_program; @@ -75,10 +94,15 @@ void ProgramData::uniform(const string &name, Uniform *uni) else if(name[name.size()-1]==']') throw invalid_argument("ProgramData::uniform"); } - catch(...) + catch(const exception &e) { delete uni; +#ifdef DEBUG + IO::print(IO::cerr, "Error while setting uniform %s: %s: %s\n", name, Debug::demangle(typeid(e).name()), e.what()); + return; +#else throw; +#endif } int i = find_uniform_index(name); @@ -404,6 +428,12 @@ const Uniform &ProgramData::get_uniform(const string &name) const return *uniforms[i].value; } +const Uniform *ProgramData::find_uniform(const string &name) const +{ + int i = find_uniform_index(name); + return (i>=0 ? uniforms[i].value : 0); +} + bool ProgramData::uniform_name_compare(const NamedUniform &nu, const string &name) { return nu.name::const_iterator j=info.uniforms.begin(); (!any_found && j!=info.uniforms.end()); ++j) - any_found = (find_uniform_index((*j)->name)>=0); + bool all_found = true; + for(vector::const_iterator j=info.uniforms.begin(); j!=info.uniforms.end(); ++j) + { + if(find_uniform_index((*j)->name)>=0) + any_found = true; + else + all_found = false; + } - // TODO throw if all uniforms for a buffer-backed block are not found if(!any_found) return 0; + else if(!all_found && info.bind_point>=0) + { +#ifdef DEBUG + IO::print(IO::cerr, "Warning: not all uniforms for block %s are present\n", info.name); +#else + throw incomplete_uniform_block(info.name); +#endif + } UniformBlock *block; if(info.bind_point>=0) @@ -516,6 +559,7 @@ void ProgramData::apply() const const Program::UniformBlockMap &prog_blocks = prog->get_uniform_blocks(); + UniformBlock *old_last_block = last_block; if(pu.dirty==ALL_ONES) { /* The set of uniforms has changed since this program was last used. @@ -557,6 +601,13 @@ void ProgramData::apply() const to avoid state thrashing. */ if(buffered_blocks_updated && !ARB_direct_state_access) buffer->bind(); + + if(last_block!=old_last_block) + { + unsigned required_size = last_block->get_required_buffer_size(); + if(last_block->get_required_buffer_size()>buffer->get_size()) + buffer->data(required_size, 0); + } } for(vector::iterator i=pu.blocks.begin(); i!=pu.blocks.end(); ++i)