diff --git a/modules/gfx/pymod/CMakeLists.txt b/modules/gfx/pymod/CMakeLists.txt index 386dba45cfc14e32c41471e35407b62c2999d33a..a3d8b251dda72f07f6e7394ad4fb3d0996fb4bd4 100644 --- a/modules/gfx/pymod/CMakeLists.txt +++ b/modules/gfx/pymod/CMakeLists.txt @@ -21,7 +21,7 @@ if (ENABLE_IMG) set(OST_GFX_PYMOD_SOURCES ${OST_GFX_PYMOD_SOURCES} export_map.cc) endif() -pymod(NAME gfx CPP ${OST_GFX_PYMOD_SOURCES} PY __init__.py) +pymod(NAME gfx CPP ${OST_GFX_PYMOD_SOURCES} PY __init__.py py_gfx_obj.py) set(GRADIENT_FILE gradients.xml diff --git a/modules/gfx/pymod/__init__.py b/modules/gfx/pymod/__init__.py index 4d96c534e4e7978849ae4406dc2b828524d860c2..be887c4ab071e3c4f2da12a771e7e1edad6b8b30 100644 --- a/modules/gfx/pymod/__init__.py +++ b/modules/gfx/pymod/__init__.py @@ -17,6 +17,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #------------------------------------------------------------------------------ from _ost_gfx import * +from py_gfx_obj import PyGfxObj WHITE=Color(1.0,1.0,1.0) BLACK=Color(0.0,0.0,0.0) diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index 1d2ed62cd446fa5689230ff4eeda73cb5f7d787a..e05fb239c545b17a9ab3f11b7fb92bfadef5c66b 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -58,6 +58,50 @@ namespace { LOG_INFO("AALines(bool) is deprecated, use SetAALines(bool) instead"); b->SetAALines(f); } + + class GfxObjWrap: public GfxObj, public wrapper<GfxObj> + { + public: + GfxObjWrap(const std::string& name): + GfxObj(name) + {} + + virtual void CustomRenderGL(RenderPass pass) { + if(override f = this->get_override("_CustomRenderGL")) { + f(pass); + } else { + GfxObj::CustomRenderGL(pass); + } + } + + void default_CustomRenderGL(RenderPass pass) { + GfxObj::CustomRenderGL(pass); + } + + virtual void CustomPreRenderGL(bool rebuild) { + if(override f = this->get_override("_CustomPreRenderGL")) { + f(rebuild); + } else { + GfxObj::CustomPreRenderGL(rebuild); + } + } + + void default_CustomPreRenderGL(bool rebuild) { + GfxObj::CustomPreRenderGL(rebuild); + } + + virtual void InitGL() { + if(override f = this->get_override("_InitGL")) { + f(); + } else { + GfxObj::InitGL(); + } + } + + void default_InitGL() { + GfxObj::InitGL(); + } + }; } void export_GfxObj() @@ -102,9 +146,13 @@ void export_GfxObj() .add_property("opacity",&GfxObjBase::GetOpacity,&GfxObjBase::SetOpacity) COLOR_BY_DEF() ; - //register_ptr_to_python<GfxObjBaseP>(); - class_<GfxObj, boost::shared_ptr<GfxObj>, bases<GfxObjBase>, boost::noncopyable>("GfxObj",no_init) + enum_<RenderPass>("RenderPass") + .value("STANDARD_RENDER_PASS",STANDARD_RENDER_PASS) + .value("TRANSPARENT_RENDER_PASS",TRANSPARENT_RENDER_PASS) + ; + + class_<GfxObjWrap, bases<GfxObjBase>, boost::noncopyable>("GfxObj",init<const std::string&>()) .def("GetTF", &GfxObj::GetTF, return_value_policy<copy_const_reference>()) .def("SetTF", &GfxObj::SetTF) .def("FlagRebuild",&GfxObj::FlagRebuild) @@ -116,7 +164,9 @@ void export_GfxObj() .def("GetAALines",&GfxObj::GetAALines) .def("GetLineWidth",&GfxObj::GetLineWidth) .def("GetLineHalo",&GfxObj::GetLineHalo) - ; - //register_ptr_to_python<GfxObjP>(); + .def("_CustomRenderGL",&GfxObj::CustomRenderGL, &GfxObjWrap::default_CustomRenderGL) + .def("_CustomPreRenderGL",&GfxObj::CustomPreRenderGL, &GfxObjWrap::default_CustomPreRenderGL) + .def("_InitGL",&GfxObj::InitGL, &GfxObjWrap::default_InitGL) + ; } diff --git a/modules/gfx/pymod/py_gfx_obj.py b/modules/gfx/pymod/py_gfx_obj.py new file mode 100644 index 0000000000000000000000000000000000000000..ac91e9073a47b061ee57145e0d3d7b6b6a51dcc5 --- /dev/null +++ b/modules/gfx/pymod/py_gfx_obj.py @@ -0,0 +1,79 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ +import traceback +from _ost_gfx import * + +class PyGfxObj(GfxObj): + def __init__(self,name): + """ + requires a unique name not yet utilized in the Scene; + do not place OpenGL calls in the ctor, use InitGL for + that purpose + """ + GfxObj.__init__(self,name) + self._valid_flag=False + + def _InitGL(self): + try: + self.InitGL() + self._valid_flag=True + except: + traceback.print_exc() + + def InitGL(self): + """ + called once for each OpenGL context (usually one time), + allows one-time OpenGL initialization to be implemented, + such as vbo allocation + """ + pass + + + def _CustomPreRenderGL(self,rebuild): + if not self._valid_flag: + return + try: + self.CustomPreRenderGL(rebuild) + except: + self._valid_flag=False + traceback.print_exc() + + def CustomPreRenderGL(self,rebuild): + """ + called just before CustomRenderGL is called; the flag + indicates that a rebuild is required or was requested + """ + pass + + + def _CustomRenderGL(self,render_pass): + if not self._valid_flag: + return + try: + self.CustomRenderGL(render_pass) + except: + self._valid_flag=False + traceback.print_exc() + + def CustomRenderGL(self,render_pass): + """ + called for each scene refresh + """ + pass + diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 10f6f53c2c648e171416fc98925a84cafab02f53..1f0486017c6139adc74134f712d72409486744cd 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -181,6 +181,9 @@ void GfxObj::RenderGL(RenderPass pass) } } +void GfxObj::InitGL() +{ +} void GfxObj::RenderPov(PovState& pov) { diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index e4b800f3253877d3ae389be666de9c947b25b443..d241be75e19f15158d173554f01384b26cdab15f 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -120,6 +120,15 @@ public: */ virtual void CustomRenderGL(RenderPass pass); + // implemented in derived classes to deal with initialization etc + // called just before CustomRenderGL is called + // the boolean flag indicated that a re-build was requested + virtual void CustomPreRenderGL(bool rebuild); + + // implemented in derived classes for first GL initialization + // which should be done here, not in the ctor + virtual void InitGL(); + // implemented in derived classes for the actual POVray export virtual void CustomRenderPov(PovState& pov); @@ -188,7 +197,6 @@ public: protected: void PreRenderGL(bool flag); - virtual void CustomPreRenderGL(bool flag); private: GfxObj(const GfxObj& o); diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index bbc615ee5d0ae3a66861509bc6fc7e12a3a74b1c..68ba5111af78c1e62e36d2bbd99d0e1f41e5a7bb 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -311,12 +311,18 @@ void Scene::SetBeaconOff() namespace { -void set_light_dir(Vec3 ld) -{ - GLfloat l_pos[]={0.0, 0.0, 0.0, 0.0}; - l_pos[0]=-ld[0]; l_pos[1]=-ld[1]; l_pos[2]=-ld[2]; - glLightfv(GL_LIGHT0, GL_POSITION, l_pos); -} + void set_light_dir(Vec3 ld) + { + GLfloat l_pos[]={0.0, 0.0, 0.0, 0.0}; + l_pos[0]=-ld[0]; l_pos[1]=-ld[1]; l_pos[2]=-ld[2]; + glLightfv(GL_LIGHT0, GL_POSITION, l_pos); + } + + struct GfxObjInitGL: public GfxNodeVisitor { + virtual void VisitObject(GfxObj* o, const Stack& st) { + o->InitGL(); + } + }; } @@ -460,6 +466,10 @@ void Scene::InitGL(bool full) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); + LOG_DEBUG("Scene: calling gl init for all objects"); + GfxObjInitGL initgl; + this->Apply(initgl); + LOG_DEBUG("Scene: gl init done"); gl_init_=true; @@ -778,9 +788,13 @@ void Scene::Add(const GfxNodeP& n, bool redraw) LOG_DEBUG("Scene: graphical object added @" << n.get() << std::endl); - if(root_node_->GetChildCount()==0) { - GfxObjP go = boost::dynamic_pointer_cast<GfxObj>(n); - if(go) { + GfxObjP go = boost::dynamic_pointer_cast<GfxObj>(n); + + if(go) { + if(gl_init_) { + go->InitGL(); + } + if(root_node_->GetChildCount()==0) { SetCenter(go->GetCenter()); } do_autoslab_=true; diff --git a/modules/gfx/tests/test_gfx.py b/modules/gfx/tests/test_gfx.py index 5214a3dd751302c6aa3d218b5b12fac2f56845bc..362535b28229333910947f350269ef41bcdf5e82 100644 --- a/modules/gfx/tests/test_gfx.py +++ b/modules/gfx/tests/test_gfx.py @@ -21,12 +21,26 @@ else: def col_delta(c1,c2): return geom.Distance(geom.Vec3(c1[0],c1[1],c1[2]),geom.Vec3(c2[0],c2[1],c2[2])) +class MyGfxObj(gfx.GfxObj): + def __init__(self,name): + gfx.GfxObj.__init__(self,name) + self.rendered=False + + def CustomRenderGL(self,render_pass): + self.rendered=True + class TestGfx(unittest.TestCase): def runTest(self): self.test_gradient() self.test_color() self.test_primlist() self.test_entity_reset() + self.test_custom_gfx_obj() + + def test_custom_gfx_obj(self): + myobj=MyGfxObj("foo") + gfx.Scene().Add(myobj) + #self.assertTrue(myobj.rendered) def test_entity_reset(self): eh=mol.CreateEntity()