opensurgsim
OsgTextureUniform-inl.h
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2013, SimQuest Solutions Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SURGSIM_GRAPHICS_OSGTEXTUREUNIFORM_INL_H
17 #define SURGSIM_GRAPHICS_OSGTEXTUREUNIFORM_INL_H
18 
19 #include <osg/PointSprite>
20 
22 #include "SurgSim/Graphics/OsgTexture.h"
23 #include "SurgSim/Graphics/OsgTexture1d.h"
24 #include "SurgSim/Graphics/OsgTexture2d.h"
25 #include "SurgSim/Graphics/OsgTexture3d.h"
26 #include "SurgSim/Graphics/OsgTextureCubeMap.h"
27 #include "SurgSim/Graphics/OsgTextureRectangle.h"
29 
30 namespace SurgSim
31 {
32 
33 namespace Graphics
34 {
35 
36 template <class T>
37 OsgTextureUniform<T>::OsgTextureUniform(const std::string& name) :
38  UniformBase(), Uniform<std::shared_ptr<T>>(), OsgUniformBase(name), m_unit(-1), m_minimumTextureUnit(0)
39 {
40  SURGSIM_ADD_RW_PROPERTY(OsgTextureUniform<T>, size_t,
41  MinimumTextureUnit, getMinimumTextureUnit, setMinimumTextureUnit);
42 
43  osg::Uniform::Type osgUniformType = getOsgUniformType<std::shared_ptr<T>>();
44  SURGSIM_ASSERT(osgUniformType != osg::Uniform::UNDEFINED) << "Failed to get OSG uniform type!";
45  SURGSIM_ASSERT(m_uniform->setType(osgUniformType)) << "Failed to set OSG uniform type!";
46  m_uniform->setNumElements(1);
47 }
48 
49 template <class T>
50 void OsgTextureUniform<T>::set(const std::shared_ptr<T>& value)
51 {
52  m_texture = value;
53  if (m_stateset != nullptr)
54  {
55  m_stateset->setTextureAttributeAndModes(m_unit, m_texture->getOsgTexture(), osg::StateAttribute::ON);
56  }
57 }
58 
59 template <class T>
60 void OsgTextureUniform<T>::set(const YAML::Node& value)
61 {
62  m_unit = value.as<int>();
63 }
64 
65 template <class T>
66 const std::shared_ptr<T>& OsgTextureUniform<T>::get() const
67 {
68  return m_texture;
69 }
70 
71 template <class T>
72 void OsgTextureUniform<T>::addToStateSet(osg::StateSet* stateSet)
73 {
74  SURGSIM_ASSERT(m_stateset == nullptr) << "Unexpected addToStateSet for OsgTextureUniform " << getName() << ".";
75 
76  const osg::StateSet::TextureAttributeList& textures = stateSet->getTextureAttributeList();
77 
78  // Grab the smallest unit that is equal or higher than m_minimumTextureUnit
79  // and search through allocated units for free ones
80  int availableUnit = m_minimumTextureUnit;
81  if (textures.size() > m_minimumTextureUnit)
82  {
83  for (auto it = textures.begin() + m_minimumTextureUnit; it != textures.end(); ++it)
84  {
85  if (it->empty())
86  {
87  break;
88  }
89  availableUnit++;
90  }
91  }
92 
93  m_unit = availableUnit;
94 
95  SURGSIM_ASSERT(m_texture != nullptr) << "Tried to add uniform " << getName() << " without a valid Texture";
96  if (m_texture->isPointSprite())
97  {
98  osg::PointSprite* sprite = new osg::PointSprite();
99  stateSet->setTextureAttributeAndModes(m_unit, sprite, osg::StateAttribute::ON);
100  stateSet->setMode(GL_VERTEX_PROGRAM_POINT_SIZE, osg::StateAttribute::ON);
101  }
102  stateSet->setTextureAttributeAndModes(m_unit, m_texture->getOsgTexture(),
103  osg::StateAttribute::ON);
104  SURGSIM_ASSERT(m_uniform->set(static_cast<int>(m_unit))) << "Failed to set OSG texture uniform unit!" <<
105  " Uniform: " << getName() << " unit: " << m_unit;
106  stateSet->addUniform(m_uniform);
107  m_stateset = stateSet;
108 }
109 
110 template <class T>
111 void OsgTextureUniform<T>::removeFromStateSet(osg::StateSet* stateSet)
112 {
113  SURGSIM_ASSERT(m_stateset != stateSet) << "Unexpected Remove for OsgTextureUniform";
114  stateSet->removeTextureAttribute(m_unit, m_texture->getOsgTexture());
115  stateSet->removeUniform(m_uniform);
116  m_stateset = nullptr;
117 }
118 
119 template <class T>
121 {
122  SURGSIM_ASSERT(m_unit == -1) << "Can't set minimumTextureUnit after the unit has been assigned.";
123  m_minimumTextureUnit = unit;
124 }
125 
126 template <class T>
128 {
129  return m_minimumTextureUnit;
130 }
131 
132 template <class T>
133 const std::string OsgTextureUniform<T>::getGlslType() const
134 {
135  return SurgSim::Graphics::getGlslType<T>();
136 }
137 
138 }; // namespace Graphics
139 
140 }; // namespace SurgSim
141 
142 #endif // SURGSIM_GRAPHICS_OSGTEXTUREUNIFORM_INL_H
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
Definition: MockObjects.h:47
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
Functions to get the OSG uniform type enum for a given type.
Base OSG implementation of graphics uniforms.
Definition: OsgUniformBase.h:41
OsgTextureUniform(const std::string &name)
Constructor.
Definition: OsgTextureUniform-inl.h:37
Base class for a graphics uniform with a value of type T.
Definition: Uniform.h:32
The header that provides the assertion API.
OSG implementation of graphics uniform with a texture value.
Definition: OsgTextureUniform.h:30
Common base class for all graphics uniforms.
Definition: UniformBase.h:33