Beispiel #1
0
void glCompileShaderFromFile(GLhandleARB shaderObject,const char* shaderSourceFileName)
	{
	/* Open the source file: */
	IO::FilePtr shaderSourceFile(IO::openFile(shaderSourceFileName));
	
	/* Compile the shader from the source file: */
	glCompileShaderFromFile(shaderObject,shaderSourceFileName,*shaderSourceFile);
	}
const GLuint render::ShaderFactory::getShader(const std::string shaderName, GLenum shaderType) {
	//Check for shader in flyweight pool
	if(shaders.find(shaderName) != shaders.end()) {
		return shaders[shaderName];
	}

	//Shader not in flyweight pool: load and compile shader
	std::ifstream shaderSourceFile(std::string("./shaders/" + shaderName + ".glsl").c_str());

	if(!shaderSourceFile.is_open()) {
		//TODO To logging
		std::cerr << "Could not find shader " << shaderName << std::endl;
		assert(shaderSourceFile.is_open());
	}

	std::stringstream shaderSourceStream;

	while(shaderSourceFile.good()) {
		std::string line;
		std::getline(shaderSourceFile, line);

		shaderSourceStream << line << std::endl;
	}

	//We need to copy the C-string because of the volatile characteristics of std::string.c_str()
	char* shaderSourceCString = new char[shaderSourceStream.str().size()+1];
	std::strcpy(shaderSourceCString, shaderSourceStream.str().c_str());

	GLuint shader = glCreateShader(shaderType);

	glShaderSource(shader, 1, (const GLchar**) &shaderSourceCString, 0);
	glCompileShader(shader);
	checkShaderError(shader);
	
	delete[] shaderSourceCString;
	
	shaders.insert(std::pair<std::string, GLuint>(shaderName, shader));

	return shader;
}
Beispiel #3
0
void GLShader::loadShader(GLhandleARB shaderObject,const char* shaderSourceFileName)
	{
	/* Open the source file: */
	Misc::File shaderSourceFile(shaderSourceFileName,"rt");
	
	/* Determine the length of the source file: */
	shaderSourceFile.seekEnd(0);
	GLint shaderSourceLength=GLint(shaderSourceFile.tell());
	shaderSourceFile.seekSet(0);
	
	/* Read the shader source: */
	GLcharARB* shaderSource=new GLcharARB[shaderSourceLength];
	shaderSourceFile.read<GLcharARB>(shaderSource,shaderSourceLength);
	
	/* Upload the shader source into the shader object: */
	const GLcharARB* ss=shaderSource;
	glShaderSourceARB(shaderObject,1,&ss,&shaderSourceLength);
	delete[] shaderSource;
	
	/* Compile the shader source: */
	glCompileShaderARB(shaderObject);
	
	/* Check if the shader compiled successfully: */
	GLint compileStatus;
	glGetObjectParameterivARB(shaderObject,GL_OBJECT_COMPILE_STATUS_ARB,&compileStatus);
	if(!compileStatus)
		{
		/* Get some more detailed information: */
		GLcharARB compileLogBuffer[2048];
		GLsizei compileLogSize;
		glGetInfoLogARB(shaderObject,sizeof(compileLogBuffer),&compileLogSize,compileLogBuffer);
		
		/* Signal an error: */
		Misc::throwStdErr("%s",compileLogBuffer);
		}
	}
/******************************************************************************
* Loads and compiles a GLSL shader and adds it to the given program object.
******************************************************************************/
void ViewportSceneRenderer::loadShader(QOpenGLShaderProgram* program, QOpenGLShader::ShaderType shaderType, const QString& filename)
{
	// Load shader source.
	QFile shaderSourceFile(filename);
	if(!shaderSourceFile.open(QFile::ReadOnly))
		throw Exception(QString("Unable to open shader source file %1.").arg(filename));
	QByteArray shaderSource;

	// Insert GLSL version string at the top.
	// Pick GLSL language version based on current OpenGL version.
	if((glformat().majorVersion() >= 3 && glformat().minorVersion() >= 2) || glformat().majorVersion() > 3)
		shaderSource.append("#version 150\n");
	else if(glformat().majorVersion() >= 3)
		shaderSource.append("#version 130\n");
	else
		shaderSource.append("#version 120\n");

	// Preprocess shader source while reading it from the file.
	//
	// This is a workaround for some older OpenGL driver, which do not perform the
	// preprocessing of shader source files correctly (probably the __VERSION__ macro is not working).
	//
	// Here, in our own simple preprocessor implementation, we only handle
	//    #if __VERSION__ >= 130
	//       ...
	//    #else
	//       ...
	//    #endif
	// statements, which are used by most shaders to discriminate core and compatibility profiles.
	bool isFiltered = false;
	int ifstack = 0;
	int filterstackpos = 0;
	while(!shaderSourceFile.atEnd()) {
		QByteArray line = shaderSourceFile.readLine();
		if(line.contains("__VERSION__") && line.contains("130")) {
			OVITO_ASSERT(line.contains("#if"));
			OVITO_ASSERT(!isFiltered);
			if(line.contains(">=") && glformat().majorVersion() < 3) isFiltered = true;
			if(line.contains("<") && glformat().majorVersion() >= 3) isFiltered = true;
			filterstackpos = ifstack;
			continue;
		}
		else if(line.contains("#if")) {
			ifstack++;
		}
		else if(line.contains("#else")) {
			if(ifstack == filterstackpos) {
				isFiltered = !isFiltered;
				continue;
			}
		}
		else if(line.contains("#endif")) {
			if(ifstack == filterstackpos) {
				filterstackpos = -1;
				isFiltered = false;
				continue;
			}
			ifstack--;
		}

		if(!isFiltered) {
			shaderSource.append(line);
		}
	}

	// Load and compile vertex shader source.
	if(!program->addShaderFromSourceCode(shaderType, shaderSource)) {
		Exception ex(QString("The shader source file %1 failed to compile.").arg(filename));
		ex.appendDetailMessage(program->log());
		ex.appendDetailMessage(QStringLiteral("Problematic shader source:"));
		ex.appendDetailMessage(shaderSource);
		throw ex;
	}
}