bool TGlslOutputTraverser::traverseLoop( bool preVisit, TIntermLoop *node, TIntermTraverser *it ) { TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it); GlslFunction *current = goit->current; std::stringstream& out = current->getActiveOutput(); current->beginStatement(); if ( node->getTerminal()) { // Process for loop, initial statement was promoted outside the loop out << "for ( ; "; node->getTest()->traverse(goit); out << "; "; node->getTerminal()->traverse(goit); out << ") "; current->beginBlock(); if (node->getBody()) node->getBody()->traverse(goit); current->endBlock(); } else { if ( node->testFirst()) { // Process while loop out << "while ( "; node->getTest()->traverse(goit); out << " ) "; current->beginBlock(); if (node->getBody()) node->getBody()->traverse(goit); current->endBlock(); } else { // Process do loop out << "do "; current->beginBlock(); if (node->getBody()) node->getBody()->traverse(goit); current->endBlock(); current->indent(); out << "while ( "; node->getTest()->traverse(goit); out << " )\n"; } } return false; }
bool TGlslOutputTraverser::traverseDeclaration(bool preVisit, TIntermDeclaration* decl, TIntermTraverser* it) { TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it); GlslFunction *current = goit->current; std::stringstream& out = current->getActiveOutput(); EGlslSymbolType symbol_type = translateType(decl->getTypePointer()); TType& type = *decl->getTypePointer(); bool emit_osx10_6_arrays = goit->m_EmitSnowLeopardCompatibleArrayInitializers && decl->containsArrayInitialization(); if (emit_osx10_6_arrays) { assert(decl->isSingleInitialization() && "Emission of multiple in-line array declarations isn't supported when running in OS X 10.6 compatible mode."); current->indent(out); out << "#if defined(OSX_SNOW_LEOPARD)" << std::endl; current->increaseDepth(); TQualifier q = type.getQualifier(); if (q == EvqConst) q = EvqTemporary; current->beginStatement(); if (q != EvqTemporary && q != EvqGlobal) out << type.getQualifierString() << " "; TIntermBinary* assign = decl->getDeclaration()->getAsBinaryNode(); TIntermSymbol* sym = assign->getLeft()->getAsSymbolNode(); TIntermSequence& init = assign->getRight()->getAsAggregate()->getSequence(); writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined); out << "[" << type.getArraySize() << "] " << sym->getSymbol(); current->endStatement(); unsigned n_vals = init.size(); for (unsigned i = 0; i != n_vals; ++i) { current->beginStatement(); sym->traverse(goit); out << "[" << i << "]" << " = "; init[i]->traverse(goit); current->endStatement(); } current->decreaseDepth(); current->indent(out); out << "#else" << std::endl; current->increaseDepth(); } current->beginStatement(); if (type.getQualifier() != EvqTemporary && type.getQualifier() != EvqGlobal) out << type.getQualifierString() << " "; if (type.getBasicType() == EbtStruct) out << type.getTypeName(); else writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined); if (type.isArray()) out << "[" << type.getArraySize() << "]"; out << " "; decl->getDeclaration()->traverse(goit); current->endStatement(); if (emit_osx10_6_arrays) { current->decreaseDepth(); current->indent(out); out << "#endif" << std::endl; } return false; }
bool TGlslOutputTraverser::traverseSelection( bool preVisit, TIntermSelection *node, TIntermTraverser *it ) { TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it); GlslFunction *current = goit->current; std::stringstream& out = current->getActiveOutput(); current->beginStatement(); if (node->getBasicType() == EbtVoid) { // if/else selection out << "if ("; node->getCondition()->traverse(goit); out << ')'; current->beginBlock(); node->getTrueBlock()->traverse(goit); current->endBlock(); if (node->getFalseBlock()) { current->indent(); out << "else"; current->beginBlock(); node->getFalseBlock()->traverse(goit); current->endBlock(); } } else if (node->isVector() && node->getCondition()->getAsTyped()->isVector()) { // ?: selection on vectors, e.g. bvec4 ? vec4 : vec4 // emulate HLSL's component-wise selection here current->addLibFunction(EOpVecTernarySel); out << "xll_vecTSel ("; node->getCondition()->traverse(goit); out << ", "; node->getTrueBlock()->traverse(goit); out << ", "; if (node->getFalseBlock()) { node->getFalseBlock()->traverse(goit); } else assert(0); out << ")"; } else { // simple ?: selection out << "(( "; node->getCondition()->traverse(goit); out << " ) ? ( "; node->getTrueBlock()->traverse(goit); out << " ) : ( "; if (node->getFalseBlock()) { node->getFalseBlock()->traverse(goit); } else assert(0); out << " ))"; } return false; }