]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/output.cpp
Implement the ternary operator in GLSL
[libs/gl.git] / source / glsl / output.cpp
index f440fa8c01cb34ea31cbd9742020165f4b61546e..364e5e4b23c02356a2c72743103ba212a32abd91 100644 (file)
@@ -10,17 +10,17 @@ namespace SL {
 
 Formatter::Formatter():
        stage(0),
-       mode(Compiler::PROGRAM),
        source_index(0),
        source_line(1),
        indent(0),
-       parameter_list(false)
+       parameter_list(false),
+       omit_builtin(false)
 { }
 
-const string &Formatter::apply(Stage &s, Compiler::Mode m)
+const string &Formatter::apply(Stage &s)
 {
-       mode = m;
        stage = &s;
+       omit_builtin = true;
 
        const Version &ver = s.required_features.glsl_version;
 
@@ -73,7 +73,7 @@ void Formatter::set_source(unsigned index, unsigned line)
                else
                {
                        unsigned l = line;
-                       if(mode==Compiler::PROGRAM && stage && stage->required_features.glsl_version<Version(3, 30))
+                       if(stage && stage->required_features.glsl_version && stage->required_features.glsl_version<Version(3, 30))
                                --l;
                        formatted += format("#line %d %d\n", l, index);
                }
@@ -94,7 +94,7 @@ void Formatter::visit(Block &block)
        bool first = true;
        for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
        {
-               if((*i)->source==BUILTIN_SOURCE)
+               if(omit_builtin && (*i)->source<=BUILTIN_SOURCE)
                        continue;
                if(!first)
                        append('\n');
@@ -136,6 +136,12 @@ void Formatter::visit(MemberAccess &memacc)
        append(format(".%s", memacc.member));
 }
 
+void Formatter::visit(Swizzle &swizzle)
+{
+       swizzle.left->visit(*this);
+       append(format(".%s", swizzle.component_group));
+}
+
 void Formatter::visit(UnaryExpression &unary)
 {
        if(unary.oper->type==Operator::PREFIX)
@@ -161,6 +167,16 @@ void Formatter::visit(Assignment &assign)
        assign.right->visit(*this);
 }
 
+void Formatter::visit(TernaryExpression &ternary)
+{
+       ternary.condition->visit(*this);
+       append(ternary.oper->token);
+       ternary.true_expr->visit(*this);
+       if(ternary.oper->token[0]=='?')
+               append(':');
+       ternary.false_expr->visit(*this);
+}
+
 void Formatter::visit(FunctionCall &call)
 {
        append(format("%s(", call.name));
@@ -229,10 +245,10 @@ void Formatter::visit(VariableDeclaration &var)
                append(format("%s ", var.interpolation));
        if(!var.sampling.empty())
                append(format("%s ", var.sampling));
-       if(!var.interface.empty() && var.interface!=block_interface)
+       if(!var.interface.empty())
        {
                string interface = var.interface;
-               if(mode==Compiler::PROGRAM && stage && stage->required_features.glsl_version<Version(1, 30))
+               if(stage && stage->required_features.glsl_version && stage->required_features.glsl_version<Version(1, 30))
                {
                        if(stage->type==Stage::VERTEX && var.interface=="in")
                                interface = "attribute";
@@ -243,7 +259,10 @@ void Formatter::visit(VariableDeclaration &var)
        }
        if(!var.precision.empty())
                append(format("%s ", var.precision));
-       append(format("%s %s", var.type_declaration->name, var.name));
+       string type_name = var.type_declaration->name;
+       if(var.array)
+               type_name = type_name.substr(0, type_name.find('['));
+       append(format("%s %s", type_name, var.name));
        if(var.array)
        {
                append('[');
@@ -262,9 +281,9 @@ void Formatter::visit(VariableDeclaration &var)
 
 void Formatter::visit(InterfaceBlock &iface)
 {
-       SetForScope<string> set(block_interface, iface.interface);
        append(format("%s %s\n", iface.interface, iface.name));
-       iface.members.visit(*this);
+       if(iface.struct_declaration)
+               iface.struct_declaration->members.visit(*this);
        if(!iface.instance_name.empty())
        {
                append(' ');