OpenWalnut  1.4.0
WGEShaderVersionPreprocessor.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <algorithm>
00026 #include <ostream>
00027 #include <sstream>
00028 #include <string>
00029 
00030 #include <boost/regex.hpp>
00031 
00032 #include "../../common/WLogger.h"
00033 #include "../../common/WStringUtils.h"
00034 
00035 #include "WGEShaderVersionPreprocessor.h"
00036 
00037 WGEShaderVersionPreprocessor::WGEShaderVersionPreprocessor()
00038 {
00039     // initialize members
00040 }
00041 
00042 WGEShaderVersionPreprocessor::~WGEShaderVersionPreprocessor()
00043 {
00044     // cleanup
00045 }
00046 
00047 std::string WGEShaderVersionPreprocessor::process( const std::string& file, const std::string& code ) const
00048 {
00049     if( !getActive() )
00050     {
00051         return code;
00052     }
00053 
00054     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00055     // Eliminate all #version statements and put it to the beginning.
00056     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00057 
00058     // this is an expression for the #version statement
00059     static const boost::regex versionRegexp( "^[ ]*#[ ]*version[ ]+([123456789][0123456789][0123456789]).*$" );
00060 
00061     // go through each line again
00062     std::string line;
00063     boost::smatch matches;          // the list of matches
00064     bool foundVersion = false;
00065     unsigned int version = 120;     // our default version
00066     std::stringstream completeCode( code );
00067     std::ostringstream cleanedCode;
00068     while( std::getline( completeCode, line ) )
00069     {
00070         if( boost::regex_match( line, matches, versionRegexp ) ) // look for the #version statement
00071         {
00072             unsigned int versionNum = string_utils::fromString< unsigned int >( matches[1] );
00073             version = std::max( versionNum, version );
00074             foundVersion = true;
00075             cleanedCode << "// " << line << std::endl;
00076             continue;
00077         }
00078 
00079         cleanedCode << line << std::endl;
00080     }
00081 
00082     // no version statement found, assume 1.2
00083     if( !foundVersion )
00084     {
00085         wlog::warn( "WGEShader (" + file + ")" ) << "No version statements in unrolled shader file \"" << file << "\" found. Using default: "
00086                                                  << version << ".";
00087     }
00088 
00089     // the ATI compiler needs the version statement to be the first statement in the shader
00090     std::stringstream vs;
00091     vs << "#version " << version << std::endl
00092        << "#line 1 " << std::endl << cleanedCode.str();
00093     return vs.str();
00094 }
00095