示例#1
0
//--------------------------------------------------------------
bool ofShader::setupShaderFromSource(GLenum type, string source, string sourceDirectoryPath) {
    unload();

    // create program if it doesn't exist already
    checkAndCreateProgram();
    GLuint clearErrors = glGetError(); //needed for some users to clear gl errors
    if( clearErrors != GL_NO_ERROR ) {
        ofLogVerbose("ofShader") << "setupShaderFromSource(): OpenGL error after checkAndCreateProgram() (probably harmless): error " << clearErrors;
    }

    // create shader
    GLuint shader = glCreateShader(type);
    if(shader == 0) {
        ofLogError("ofShader") << "setupShaderFromSource(): failed creating " << nameForType(type) << " shader";
        return false;
    }

    // parse for includes
    string src = parseForIncludes( source , sourceDirectoryPath);

    // store source code (that's the expanded source with all includes copied in)
    shaderSource[type] = src;

    // compile shader
    const char* sptr = src.c_str();
    int ssize = src.size();
    glShaderSource(shader, 1, &sptr, &ssize);
    glCompileShader(shader);

    // check compile status
    GLint status = GL_FALSE;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    GLuint err = glGetError();
    if (err != GL_NO_ERROR) {
        ofLogError("ofShader") << "setupShaderFromSource(): OpenGL generated error " << err << " trying to get the compile status for a " << nameForType(type) << " shader, does your video card support this?";
        return false;
    }

    if(status == GL_TRUE) {
        ofLogVerbose("ofShader") << "setupShaderFromSource(): " << nameForType(type) + " shader compiled";
#ifdef TARGET_EMSCRIPTEN
        checkShaderInfoLog(shader, type, OF_LOG_VERBOSE);
#else
        checkShaderInfoLog(shader, type, OF_LOG_WARNING);
#endif
    } else if (status == GL_FALSE) {
        ofLogError("ofShader") << "setupShaderFromSource(): " << nameForType(type) + " shader failed to compile";
        checkShaderInfoLog(shader, type, OF_LOG_ERROR);
        return false;
    }

    shaders[type] = shader;
    retainShader(shader);

    return true;
}
示例#2
0
string ofShader::parseForIncludes( const string& source, vector<string>& included, int level, const string& sourceDirectoryPath) {
    
	if ( level > 32 ) {
		ofLogError( "ofShader", "glsl header inclusion depth limit reached, might be caused by cyclic header inclusion" );
		return "";
	}
	
	stringstream output;
	stringstream input;
	input << source;
	
	Poco::RegularExpression re("^\\s*#\\s*pragma\\s+include\\s+[\"<](.*)[\">].*");
	Poco::RegularExpression::MatchVec matches;
	
	string line;
	while( std::getline( input, line ) ) {
		
		if ( re.match( line, 0, matches ) < 2 ) {
			output << line << endl;
			continue;
		}
		
		string include = line.substr(matches[1].offset, matches[1].length);
		
		if ( std::find( included.begin(), included.end(), include ) != included.end() ) {
			ofLogVerbose("ofShader") << include << " already included";
			continue;
		}
		
		// we store the absolute paths so as have (more) unique file identifiers.
		
		include = ofFile(sourceDirectoryPath + include).getAbsolutePath();
		included.push_back( include );
		
		
		ofBuffer buffer = ofBufferFromFile( include );
		if ( !buffer.size() ) {
			ofLogError("ofShader") <<"Could not open glsl include file " << include;
			continue;
		}
		
		string currentDir = ofFile(include).getEnclosingDirectory();
		output << parseForIncludes( buffer.getText(), included, level + 1, currentDir ) << endl;
	}
	
	return output.str();
}
示例#3
0
string ofShader::parseForIncludes( const string& source, const string& sourceDirectoryPath) {
	vector<string> included;
	return parseForIncludes( source, included, 0, sourceDirectoryPath);
}