00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <OSGBlendChunk.h>
00041 #include <OSGMakeTransparentGraphOp.h>
00042 #include <OSGPolygonChunk.h>
00043 #include <OSGSimpleMaterial.h>
00044
00045 #include <OSGGLEXT.h>
00046
00047 OSG_USING_NAMESPACE
00048
00049 MakeTransparentGraphOp::MakeTransparentGraphOp(const char* name)
00050 : GraphOp(name),
00051 _transparency(0.5)
00052 {
00053 }
00054
00055 GraphOp* MakeTransparentGraphOp::create()
00056 {
00057 return new MakeTransparentGraphOp();
00058 }
00059
00060
00061
00062
00063 template<typename T>
00064 T next(T t)
00065 {
00066 return ++t;
00067 }
00068
00069
00070 bool MakeTransparentGraphOp::traverse(NodePtr& node)
00071 {
00072
00073 if (!GraphOp::traverse(node)) {
00074 return false;
00075 }
00076
00077
00078 MaterialObjectMap::iterator itr = _materialObjects.begin();
00079 for (; itr != _materialObjects.end(); ++itr)
00080 {
00081 MaterialPtr oldMaterial = itr->first;
00082 MaterialPtr newMaterial = MaterialPtr::dcast(deepClone(oldMaterial));
00083 if (newMaterial != NullFC)
00084 {
00085 std::cout << "Applying transparency: ";
00086
00087 applyTransparency(newMaterial);
00088
00089
00090 MaterialObjectList& currentList = itr->second;
00091 MaterialObjectList::iterator i = currentList.begin();
00092 for (; i != currentList.end(); ++i)
00093 {
00094 i->setMaterial(newMaterial);
00095 }
00096 }
00097 }
00098
00099 return true;
00100 }
00101
00102
00103 void MakeTransparentGraphOp::setParams(const std::string params)
00104 {
00105 ParamSet ps(params);
00106
00107 ps("transparency", _transparency);
00108
00109 std::string out = ps.getUnusedParams();
00110 if(out.length())
00111 {
00112 FWARNING(("MakeTransparentGraphOp doesn't have parameters '%s'.\n",
00113 out.c_str()));
00114 }
00115 }
00116
00117 std::string MakeTransparentGraphOp::usage(void)
00118 {
00119 return
00120 "MakeTransparent: make used Materials transparent\n"
00121 " Based on MaterialMergeGraphOp, merges Materials and sets their\n"
00122 " transparency.\n"
00123 "Params: name (type, default)\n"
00124 " transparency (Real32, 0.5f): transparency value\n";
00125 }
00126
00127 Action::ResultE MakeTransparentGraphOp::traverseEnter(NodePtr& node)
00128 {
00129 GeometryPtr geo = GeometryPtr::dcast(node->getCore());
00130 if (geo != NullFC)
00131 {
00132 addObject(MaterialObject(geo));
00133 return Action::Continue;
00134 }
00135
00136 MaterialGroupPtr mg = MaterialGroupPtr::dcast(node->getCore());
00137 if (mg != NullFC)
00138 {
00139 addObject(MaterialObject(mg));
00140 return Action::Continue;
00141 }
00142
00143
00144 return Action::Continue;
00145 }
00146
00147 Action::ResultE MakeTransparentGraphOp::traverseLeave(NodePtr& node, Action::ResultE res)
00148 {
00149 return res;
00150 }
00151
00152 void MakeTransparentGraphOp::addObject(MaterialObject m)
00153 {
00154 MaterialPtr mat = m.getMaterial();
00155 if (mat == NullFC)
00156 return;
00157
00158 _materialObjects[mat].push_back(m);
00159 }
00160
00161
00162
00163
00164 template<typename T>
00165 struct Type2Type {
00166 typedef T Original;
00167 };
00168
00169
00170 template<typename Chunk>
00171 typename Chunk::Ptr getOrAddChunk(ChunkMaterialPtr cm,
00172 Type2Type<Chunk> = Type2Type<Chunk>()) {
00173 osg::StateChunkPtr stateChunk = cm->find(Chunk::getClassType());
00174 typename Chunk::Ptr chunk = Chunk::Ptr::dcast(stateChunk);
00175 if (!chunk) {
00176 chunk = Chunk::create();
00177 beginEditCP(cm);
00178 cm->addChunk(chunk);
00179 endEditCP(cm);
00180 }
00181 return chunk;
00182 }
00183
00184
00185 void MakeTransparentGraphOp::applyTransparency(MaterialPtr m) {
00186
00187 SimpleMaterialPtr sm = SimpleMaterialPtr::dcast(m);
00188 if (sm != NullFC) {
00189 std::cout << "SimpleMaterial" << std::endl;
00190 beginEditCP(sm);
00191 sm->setTransparency(1.0f - (1.0f - sm->getTransparency()) *
00192 _transparency);
00193 sm->setColorMaterial(GL_NONE);
00194 endEditCP(sm);
00195
00196 PolygonChunkPtr polygonChunk = getOrAddChunk<PolygonChunk>(sm);
00197 beginEditCP(polygonChunk);
00198 polygonChunk->setCullFace(GL_BACK);
00199 endEditCP(polygonChunk);
00200 return;
00201 }
00202
00203 ChunkMaterialPtr cm = ChunkMaterialPtr::dcast(m);
00204 if (cm != NullFC) {
00205 std::cout << "ChunkMaterial" << std::endl;
00206 BlendChunkPtr blendChunk = getOrAddChunk<BlendChunk>(cm);
00207 beginEditCP(blendChunk);
00208 blendChunk->setColor(Color4f(1, 1, 1, 1.f - _transparency));
00209 blendChunk->setSrcFactor(GL_CONSTANT_ALPHA);
00210 blendChunk->setDestFactor(GL_ONE_MINUS_CONSTANT_ALPHA);
00211 endEditCP(blendChunk);
00212 return;
00213 }
00214 }