From 25c81b4953dd38993250321b9407ce8b0139cbeb Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 10 Jan 2011 18:52:05 +0000 Subject: [PATCH] Add a rendering supervisor class Remove bind semantics from RenderPass --- source/camera.h | 1 + source/instancescene.cpp | 11 ++- source/instancescene.h | 5 +- source/mesh.cpp | 12 ++- source/mesh.h | 4 +- source/object.cpp | 48 +++++++--- source/object.h | 24 +---- source/objectinstance.cpp | 12 ++- source/objectinstance.h | 21 ++-- source/orderedscene.cpp | 6 +- source/orderedscene.h | 5 +- source/pipeline.cpp | 10 +- source/pipeline.h | 4 +- source/renderable.cpp | 27 ++++++ source/renderable.h | 7 +- source/renderer.cpp | 196 ++++++++++++++++++++++++++++++++++++++ source/renderer.h | 99 +++++++++++++++++++ source/renderpass.cpp | 44 +-------- source/renderpass.h | 12 +-- source/scene.cpp | 21 ++++ source/scene.h | 5 +- source/simplescene.cpp | 6 +- source/simplescene.h | 5 +- 23 files changed, 459 insertions(+), 126 deletions(-) create mode 100644 source/renderable.cpp create mode 100644 source/renderer.cpp create mode 100644 source/renderer.h create mode 100644 source/scene.cpp diff --git a/source/camera.h b/source/camera.h index cea9c35e..0390607d 100644 --- a/source/camera.h +++ b/source/camera.h @@ -45,6 +45,7 @@ public: const Vector3 &get_position() const { return position; } const Vector3 &get_look_direction() const { return look_dir; } const Vector3 &get_up_direction() const { return up_dir; } + const Matrix &get_matrix() const { return matrix; } Vector3 project(const Vector4 &) const; Vector4 unproject(const Vector4 &) const; diff --git a/source/instancescene.cpp b/source/instancescene.cpp index e3e63767..adaebbba 100644 --- a/source/instancescene.cpp +++ b/source/instancescene.cpp @@ -1,13 +1,14 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #include "object.h" #include "objectinstance.h" #include "instancescene.h" +#include "renderer.h" namespace Msp { namespace GL { @@ -36,13 +37,15 @@ void InstanceScene::remove(const Renderable &r) renderables.erase(&r); } -void InstanceScene::render(const Tag &tag) const +void InstanceScene::render(Renderer &renderer, const Tag &tag) const { + // XXX Check that the object has this pass to avoid some unnecessary function calls for(ObjectMap::const_iterator i=objects.begin(); i!=objects.end(); ++i) - i->first->render(i->second.begin(), i->second.end(), tag); + for(InstanceSet::const_iterator j=i->second.begin(); j!=i->second.end(); ++j) + (*j)->render(renderer, tag); for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - (*i)->render(tag); + (*i)->render(renderer, tag); } } // namespace GL diff --git a/source/instancescene.h b/source/instancescene.h index 1f79d767..55bd266d 100644 --- a/source/instancescene.h +++ b/source/instancescene.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -36,7 +36,8 @@ public: virtual void add(const Renderable &); virtual void remove(const Renderable &); - virtual void render(const Tag &tag = Tag()) const; + using Scene::render; + virtual void render(Renderer &, const Tag &tag = Tag()) const; }; } // namespace GL diff --git a/source/mesh.cpp b/source/mesh.cpp index a1930d75..05be2c37 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -1,13 +1,14 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #include "buffer.h" #include "extension.h" #include "mesh.h" +#include "renderer.h" using namespace std; @@ -107,6 +108,15 @@ void Mesh::draw() const Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); } +void Mesh::draw(Renderer &renderer) const +{ + renderer.set_vertex_array(&vertices); + renderer.set_element_buffer(ibuf); + + for(list::const_iterator i=batches.begin(); i!=batches.end(); ++i) + renderer.draw(*i); +} + Mesh::Loader::Loader(Mesh &m): DataFile::ObjectLoader(m) diff --git a/source/mesh.h b/source/mesh.h index 9ad924f2..1abbefd3 100644 --- a/source/mesh.h +++ b/source/mesh.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -16,6 +16,7 @@ namespace Msp { namespace GL { class Buffer; +class Renderer; class Mesh { @@ -53,6 +54,7 @@ public: const std::list &get_batches() { return batches; } void draw() const; + void draw(Renderer &) const; }; } // namespace GL diff --git a/source/object.cpp b/source/object.cpp index c4787d9f..f710a7a9 100644 --- a/source/object.cpp +++ b/source/object.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -14,9 +14,9 @@ Distributed under the LGPL #include "objectinstance.h" #include "program.h" #include "programdata.h" +#include "renderer.h" #include "technique.h" -#include "texture.h" -#include "texunit.h" +#include "texturing.h" using namespace std; @@ -55,18 +55,44 @@ void Object::render(const Tag &tag) const if(!pass) return; - Bind bind(pass); + Bind bind_shader(pass->get_shader_program()); + if(pass->get_shader_data()) + pass->get_shader_data()->apply(); + Bind bind_material(pass->get_material()); + Bind bind_texturing(pass->get_texturing()); + meshes.front()->draw(); } -void Object::render(const ObjectInstance &inst, const Tag &tag) const +void Object::render(Renderer &renderer, const Tag &tag) const { const RenderPass *pass = get_pass(tag); if(!pass) return; - Bind bind(pass); - render_instance(inst, tag); + Renderer::Push push(renderer); + renderer.set_shader(pass->get_shader_program(), pass->get_shader_data()); + renderer.set_material(pass->get_material()); + renderer.set_texturing(pass->get_texturing()); + + meshes.front()->draw(renderer); +} + +void Object::render(Renderer &renderer, const ObjectInstance &inst, const Tag &tag) const +{ + const RenderPass *pass = get_pass(tag); + if(!pass) + return; + + Renderer::Push push(renderer); + renderer.set_shader(pass->get_shader_program(), pass->get_shader_data()); + renderer.set_material(pass->get_material()); + renderer.set_texturing(pass->get_texturing()); + + inst.setup_render(renderer, tag); + unsigned lod = min(inst.get_level_of_detail(), meshes.size()-1); + meshes[lod]->draw(renderer); + inst.finish_render(renderer, tag); } const RenderPass *Object::get_pass(const Tag &tag) const @@ -76,14 +102,6 @@ const RenderPass *Object::get_pass(const Tag &tag) const return &technique->get_pass(tag); } -void Object::render_instance(const ObjectInstance &inst, const Tag &tag) const -{ - inst.setup_render(tag); - unsigned lod = min(inst.get_level_of_detail(), meshes.size()-1); - meshes[lod]->draw(); - inst.finish_render(tag); -} - Object::Loader::Loader(Object &o): DataFile::CollectionObjectLoader(o, 0) diff --git a/source/object.h b/source/object.h index 4655695b..e84bc9cf 100644 --- a/source/object.h +++ b/source/object.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -65,33 +65,17 @@ public: */ virtual void render(const Tag &tag = Tag()) const; + virtual void render(Renderer &, const Tag & = Tag()) const; + /** Renders the object with an instance. The instance's hook functions are called before and after drawing the mesh. A tag may also be given to render a non-default pass. */ - virtual void render(const ObjectInstance &, const Tag &tag = Tag()) const; + virtual void render(Renderer &, const ObjectInstance &, const Tag & = Tag()) const; - /** - Renders multiple instances of the object in one go. This may improve - performance, as the object-specific render setup only has to be done once. - Each instance's hook functions will be called before and after drawing the - mesh. - */ - template - void render(Iter begin, Iter end, const Tag &tag = Tag()) const - { - const RenderPass *pass = get_pass(tag); - if(!pass) - return; - - Bind bind(pass); - for(Iter i=begin; i!=end; ++i) - render_instance(**i, tag); - } private: const RenderPass *get_pass(const Tag &) const; - void render_instance(const ObjectInstance &, const Tag &) const; }; } // namespace GL diff --git a/source/objectinstance.cpp b/source/objectinstance.cpp index 666d9005..14341561 100644 --- a/source/objectinstance.cpp +++ b/source/objectinstance.cpp @@ -1,13 +1,13 @@ /* $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 "object.h" #include "objectinstance.h" -#include "programdata.h" +#include "renderer.h" using namespace std; @@ -20,7 +20,13 @@ ObjectInstance::ObjectInstance(const Object &obj): void ObjectInstance::render(const Tag &tag) const { - object.render(*this, tag); + Renderer renderer(0); + render(renderer, tag); +} + +void ObjectInstance::render(Renderer &renderer, const Tag &tag) const +{ + object.render(renderer, *this, tag); } } // namespace GL diff --git a/source/objectinstance.h b/source/objectinstance.h index 61ad55d3..d665851f 100644 --- a/source/objectinstance.h +++ b/source/objectinstance.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 */ @@ -21,9 +21,6 @@ class ProgramData; Represents a single instance of an Object. An application can derive another class from this and overload the hook functions to specify location and other instance-specific parameters for the rendered objects. - -The finish_render function generally should clean up everything done by -setup_render, unless the rendering sequence is known to allow otherwise. */ class ObjectInstance: public Renderable { @@ -36,16 +33,16 @@ public: const Object &get_object() const { return object; } virtual void render(const Tag &tag = Tag()) const; + virtual void render(Renderer &, const Tag & = Tag()) const; - /** - Hook function, called from Object just before rendering the mesh. - */ - virtual void setup_render(const Tag &) const { } + /** Hook function, called from Object just before rendering the mesh. + Renderer state will have been pushed before this is called. */ + virtual void setup_render(Renderer &, const Tag &) const { } - /** - Hook function, called from Object right after rendering the mesh. - */ - virtual void finish_render(const Tag &) const { } + /** Hook function, called from Object right after rendering the mesh. Since + Object takes care of pushing Renderer state, this rarely needs to do + anything. */ + virtual void finish_render(Renderer &, const Tag &) const { } virtual unsigned get_level_of_detail() const { return 0; } }; diff --git a/source/orderedscene.cpp b/source/orderedscene.cpp index 38edf696..296ad510 100644 --- a/source/orderedscene.cpp +++ b/source/orderedscene.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 */ @@ -41,10 +41,10 @@ void OrderedScene::insert_after(const Renderable &after, const Renderable &r) renderables.insert(i, &r); } -void OrderedScene::render(const Tag &tag) const +void OrderedScene::render(Renderer &renderer, const Tag &tag) const { for(RenderableList::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - (*i)->render(tag); + (*i)->render(renderer, tag); } } // namespace GL diff --git a/source/orderedscene.h b/source/orderedscene.h index 6bb12192..88321ec9 100644 --- a/source/orderedscene.h +++ b/source/orderedscene.h @@ -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 */ @@ -32,7 +32,8 @@ public: void insert(unsigned, const Renderable &); void insert_after(const Renderable &, const Renderable &); - virtual void render(const Tag & = Tag()) const; + using Scene::render; + virtual void render(Renderer &, const Tag & = Tag()) const; }; } // namespace GL diff --git a/source/pipeline.cpp b/source/pipeline.cpp index 5294ffbd..570014d3 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -14,6 +14,7 @@ Distributed under the LGPL #include "pipeline.h" #include "postprocessor.h" #include "renderbuffer.h" +#include "renderer.h" #include "tests.h" #include "texture2d.h" @@ -133,7 +134,7 @@ void Pipeline::add_postprocessor(PostProcessor &pp) } } -void Pipeline::render(const Tag &tag) const +void Pipeline::render(Renderer &renderer, const Tag &tag) const { const PipelinePass &pass = get_pass(tag); @@ -146,7 +147,7 @@ void Pipeline::render(const Tag &tag) const for(vector::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) if(i->passes.empty() || i->passes.count(tag)) - i->renderable->render(tag); + i->renderable->render(renderer, tag); for(vector::const_iterator i=pass.effects.end(); i!=pass.effects.begin();) (*--i)->cleanup(); @@ -166,8 +167,9 @@ void Pipeline::render_all() const for(vector::const_iterator i=effects.begin(); i!=effects.end(); ++i) (*i)->prepare(); + Renderer renderer(camera); for(vector::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i) - render(*i); + render(renderer, *i); for(vector::const_iterator i=effects.end(); i!=effects.begin();) (*--i)->cleanup(); diff --git a/source/pipeline.h b/source/pipeline.h index a63eeb5f..e4509af8 100644 --- a/source/pipeline.h +++ b/source/pipeline.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 */ @@ -65,7 +65,7 @@ public: void add_effect(Effect &); void add_postprocessor(PostProcessor &); - virtual void render(const Tag &tag = Tag()) const; + virtual void render(Renderer &, const Tag &tag = Tag()) const; void render_all() const; }; diff --git a/source/renderable.cpp b/source/renderable.cpp new file mode 100644 index 00000000..73c4a375 --- /dev/null +++ b/source/renderable.cpp @@ -0,0 +1,27 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include "renderable.h" +#include "renderer.h" + +namespace Msp { +namespace GL { + +void Renderable::render(const Tag &) const +{ + throw Exception("This Renderable doesn't support rendering without a Renderer"); +} + +void Renderable::render(Renderer &renderer, const Tag &tag) const +{ + renderer.escape(); + render(tag); +} + +} // namespace Msp +} // namespace GL diff --git a/source/renderable.h b/source/renderable.h index 44b3c257..8e31d5a7 100644 --- a/source/renderable.h +++ b/source/renderable.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007, 2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -14,6 +14,8 @@ Distributed under the LGPL namespace Msp { namespace GL { +class Renderer; + class Renderable { protected: @@ -21,7 +23,8 @@ protected: public: virtual ~Renderable() { } - virtual void render(const Tag &tag = Tag()) const =0; + virtual void render(const Tag & = Tag()) const; + virtual void render(Renderer &, const Tag & = Tag()) const; }; } // namespace Msp diff --git a/source/renderer.cpp b/source/renderer.cpp new file mode 100644 index 00000000..71a7dedf --- /dev/null +++ b/source/renderer.cpp @@ -0,0 +1,196 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include "batch.h" +#include "buffer.h" +#include "camera.h" +#include "material.h" +#include "program.h" +#include "programdata.h" +#include "renderer.h" +#include "texture.h" +#include "texturing.h" +#include "vertexarray.h" + +using namespace std; + +namespace Msp { +namespace GL { + +Renderer::Renderer(const Camera *c): + mtx_changed(false), + camera(c), + state_stack(1), + state(&state_stack.back()), + vertex_array(0), + vertex_array_changed(false), + element_buffer(0) +{ + MatrixStack::modelview().push(); + if(camera) + { + MatrixStack::projection().push(); + camera->apply(); + mtx_stack = camera->get_matrix(); + } + else + mtx_stack = MatrixStack::modelview().top(); +} + +Renderer::~Renderer() +{ + if(camera) + MatrixStack::projection().pop(); + MatrixStack::modelview().pop(); + + Texturing::unbind(); + Texture::unbind_from(0); + Material::unbind(); + Program::unbind(); + Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); +} + +MatrixStack &Renderer::matrix_stack() +{ + mtx_changed = true; + return mtx_stack; +} + +void Renderer::set_texture(const Texture *t) +{ + state->texture = t; + state->texturing = 0; +} + +void Renderer::set_texturing(const Texturing *t) +{ + state->texturing = t; + state->texture = 0; +} + +void Renderer::set_material(const Material *m) +{ + state->material = m; +} + +void Renderer::set_shader(const Program *p, const ProgramData *d) +{ + state->shprog = p; + if(d) + state->shdata.assign(1, d); + else + state->shdata.clear(); +} + +void Renderer::add_shader_data(const ProgramData *d) +{ + if(!state->shprog) + throw InvalidState("No shader program"); + + state->shdata.push_back(d); +} + +void Renderer::set_vertex_array(const VertexArray *a) +{ + vertex_array_changed = (a!=vertex_array); + vertex_array = a; +} + +void Renderer::set_element_buffer(const Buffer *b) +{ + element_buffer = b; +} + +void Renderer::push_state() +{ + state_stack.push_back(state_stack.back()); + state = &state_stack.back(); + mtx_stack.push(); +} + +void Renderer::pop_state() +{ + if(state_stack.size()==1) + throw InvalidState("Can't pop the last state"); + + state_stack.pop_back(); + state = &state_stack.back(); + mtx_stack.pop(); +} + +void Renderer::escape() +{ + apply_state(); + Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); +} + +void Renderer::draw(const Batch &batch) +{ + if(!vertex_array) + throw InvalidState("Can't draw without a vertex array"); + + apply_state(); + + // Until VertexArray acquires VAO support and becomes Bindable + if(vertex_array_changed) + vertex_array->apply(); + + if(element_buffer) + element_buffer->bind_to(ELEMENT_ARRAY_BUFFER); + else + Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); + + batch.draw(); +} + +void Renderer::apply_state() +{ + // We let the objects themselves figure out if the binding has changed + + if(state->texturing) + state->texturing->bind(); + else + { + Texturing::unbind(); + if(state->texture) + state->texture->bind_to(0); + else + Texture::unbind_from(0); + } + + if(state->material) + state->material->bind(); + else + Material::unbind(); + + if(state->shprog) + { + state->shprog->bind(); + for(vector::const_iterator i=state->shdata.begin(); i!=state->shdata.end(); ++i) + (*i)->apply(); + } + else + Program::unbind(); + + if(mtx_changed) + { + MatrixStack::modelview() = mtx_stack.top(); + mtx_changed = false; + } +} + + +Renderer::State::State(): + texture(0), + texturing(0), + material(0), + shprog(0) +{ } + +} // namespace GL +} // namespace Msp diff --git a/source/renderer.h b/source/renderer.h new file mode 100644 index 00000000..c06c17e9 --- /dev/null +++ b/source/renderer.h @@ -0,0 +1,99 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_RENDERER_H_ +#define MSP_GL_RENDERER_H_ + +#include +#include "matrix.h" + +namespace Msp { +namespace GL { + +class Batch; +class Buffer; +class Camera; +class Material; +class Program; +class ProgramData; +class Texture; +class Texturing; +class VertexArray; + +/** +A class for supervising the rendering process. While many Renderables (in +particular, Objects and Scenes) can by rendered without a Renderer, using one +will often be more efficient. This is especially true for ObjectInstances. + +The Renderer works by deferring GL state changes until something is actually +being drawn. This avoids many unnecessary GL calls. */ +class Renderer +{ +public: + class Push + { + private: + Renderer &renderer; + + public: + Push(Renderer &r): renderer(r) { renderer.push_state(); } + ~Push() { renderer.pop_state(); } + }; + +private: + struct State + { + const Texture *texture; + const Texturing *texturing; + const Material *material; + const Program *shprog; + std::vector shdata; + + State(); + }; + + MatrixStack mtx_stack; + bool mtx_changed; + const Camera *camera; + std::list state_stack; + State *state; + const VertexArray *vertex_array; + bool vertex_array_changed; + const Buffer *element_buffer; + +public: + Renderer(const Camera *); + ~Renderer(); + + MatrixStack &matrix_stack(); + + const Camera *get_camera() const { return camera; } + + void set_texture(const Texture *); + void set_texturing(const Texturing *); + void set_material(const Material *); + void set_shader(const Program *, const ProgramData *); + void add_shader_data(const ProgramData *); + void set_vertex_array(const VertexArray *); + void set_element_buffer(const Buffer *); + + void push_state(); + void pop_state(); + + /** Prepares for temporarily bypassing the Renderer. */ + void escape(); + + void draw(const Batch &); + +private: + void apply_state(); +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/renderpass.cpp b/source/renderpass.cpp index 5b5f7298..b67be717 100644 --- a/source/renderpass.cpp +++ b/source/renderpass.cpp @@ -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 */ @@ -30,7 +30,6 @@ RenderPass::RenderPass(): { } RenderPass::RenderPass(const RenderPass &other): - Bindable(other), shprog(other.shprog), shdata(other.shdata ? new ProgramData(*other.shdata) : 0), material(other.material), @@ -57,47 +56,6 @@ void RenderPass::set_texture(unsigned index, const Texture *tex) texturing->attach(index, *tex); } -void RenderPass::bind() const -{ - const RenderPass *old = current(); - if(!set_current(this)) - return; - - if(shprog) - { - shprog->bind(); - shdata->apply(); - } - else if(old && old->shprog) - Program::unbind(); - - if(material) - material->bind(); - else if(old && old->material) - Material::unbind(); - - if(texturing) - texturing->bind(); - else if(old && old->texturing) - Texturing::unbind(); -} - -void RenderPass::unbind() -{ - const RenderPass *old = current(); - if(!set_current(0)) - return; - - if(old->shprog) - Program::unbind(); - - if(old->material) - Material::unbind(); - - if(old->texturing) - Texturing::unbind(); -} - RenderPass::Loader::Loader(RenderPass &p): DataFile::CollectionObjectLoader(p, 0) diff --git a/source/renderpass.h b/source/renderpass.h index acbe2949..688327bb 100644 --- a/source/renderpass.h +++ b/source/renderpass.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008, 2010-2011 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -28,7 +28,7 @@ This includes shader and data for it, material and texturing. XXX Does not delete inline texture from datafiles properly */ -class RenderPass: public Bindable +class RenderPass { public: class Loader: public DataFile::CollectionObjectLoader @@ -75,12 +75,12 @@ public: RenderPass(const RenderPass &); ~RenderPass(); + const Program *get_shader_program() const { return shprog; } + const ProgramData *get_shader_data() const { return shdata; } void set_material(const Material *); + const Material *get_material() const { return material.get(); } void set_texture(unsigned, const Texture *); - - void bind() const; - - static void unbind(); + const Texturing *get_texturing() const { return texturing; } }; } // namespace GL diff --git a/source/scene.cpp b/source/scene.cpp new file mode 100644 index 00000000..fee81dc2 --- /dev/null +++ b/source/scene.cpp @@ -0,0 +1,21 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "renderer.h" +#include "scene.h" + +namespace Msp { +namespace GL { + +void Scene::render(const Tag &tag) const +{ + Renderer renderer(0); + render(renderer, tag); +} + +} // namespace GL +} // namespace Msp diff --git a/source/scene.h b/source/scene.h index 92a4a171..3b35f45b 100644 --- a/source/scene.h +++ b/source/scene.h @@ -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 */ @@ -27,6 +27,9 @@ public: virtual void add(const Renderable &) = 0; virtual void remove(const Renderable &) = 0; + + using Renderable::render; + virtual void render(const Tag & = Tag()) const; }; } // namespace GL diff --git a/source/simplescene.cpp b/source/simplescene.cpp index b410374e..f5947707 100644 --- a/source/simplescene.cpp +++ b/source/simplescene.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 */ @@ -20,10 +20,10 @@ void SimpleScene::remove(const Renderable &r) renderables.erase(&r); } -void SimpleScene::render(const Tag &tag) const +void SimpleScene::render(Renderer &renderer, const Tag &tag) const { for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - (*i)->render(tag); + (*i)->render(renderer, tag); } } // namespace GL diff --git a/source/simplescene.h b/source/simplescene.h index b28b5c0c..35315926 100644 --- a/source/simplescene.h +++ b/source/simplescene.h @@ -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 */ @@ -28,7 +28,8 @@ public: virtual void add(const Renderable &); virtual void remove(const Renderable &); - virtual void render(const Tag &tag = Tag()) const; + using Scene::render; + virtual void render(Renderer &, const Tag & = Tag()) const; }; } // namespace GL -- 2.45.2