Example #1
0
	void __shaderStuff(Shader& s) {
		s.Link();
		s.Use();

		glBindFragDataLocation(s.ProgramHandle, 0, "outColor");
		glUniform1i(glGetUniformLocation(s.ProgramHandle, "tex"), 0);

		GLint posAttrib = glGetAttribLocation(s.ProgramHandle, "position");
		glEnableVertexAttribArray(posAttrib);
		checkGL;
		glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 9, 0);
		checkGL;

		GLint tposAttrib = glGetAttribLocation(s.ProgramHandle, "texpos");
		checkGL;
		glEnableVertexAttribArray(tposAttrib);
		checkGL;
		glVertexAttribPointer(tposAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 9, (void*)(sizeof(float) * 3));
		checkGL;

		GLint colAttrib = glGetAttribLocation(s.ProgramHandle, "color");
		checkGL;
		glEnableVertexAttribArray(colAttrib);
		checkGL;
		glVertexAttribPointer(colAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 9, (void*)(sizeof(float) * 5));
	}
    FPS_UINT32 MaterialManager::CreateShader(
		const MATERIAL_SHADER &p_ShaderInfo,
		std::list< std::string > &p_ShaderParameters,
		MD5_DIGEST &p_ShaderDigest )
    {
		Shader *pMaterialShader = new Shader( );

		if( p_ShaderInfo.Types & SHADER_TYPE_VERTEX )
		{
			if( pMaterialShader->CreateShaderFromSource(
				p_ShaderInfo.VertexSource, SHADER_TYPE_VERTEX,
				p_ShaderInfo.VertexFile ) != FPS_OK )
			{
				std::cout << "[FPS::MaterialManager::CreateShader] <ERROR> "
					"Failed to compile the vertex shader" << std::endl;

				return FPS_FAIL;
			}
		}

		if( p_ShaderInfo.Types & SHADER_TYPE_FRAGMENT )
		{
			if( pMaterialShader->CreateShaderFromSource(
				p_ShaderInfo.FragmentSource, SHADER_TYPE_FRAGMENT,
				p_ShaderInfo.FragmentFile ) != FPS_OK )
			{
				std::cout << "[FPS::MaterialManager::CreateShader] <ERROR> "
					"Failed to compile the vertex shader" << std::endl;

				return FPS_FAIL;
			}
		}

		if( p_ShaderInfo.Types & SHADER_TYPE_GEOMETRY )
		{
			if( pMaterialShader->CreateShaderFromSource(
				p_ShaderInfo.GeometrySource, SHADER_TYPE_GEOMETRY,
				p_ShaderInfo.GeometryFile ) != FPS_OK )
			{
				std::cout << "[FPS::MaterialManager::CreateShader] <ERROR> "
					"Failed to compile the vertex shader" << std::endl;

				return FPS_FAIL;
			}
		}

		pMaterialShader->GetShaderParameters( p_ShaderParameters );
		pMaterialShader->Link( );
		pMaterialShader->GetDigest( p_ShaderDigest );

		std::pair< std::map< MD5_DIGEST, Shader * >::iterator, bool >
			ShaderMapResult;
		
		ShaderMapResult = m_Shaders.insert( std::pair< MD5_DIGEST, Shader * >(
			p_ShaderDigest, pMaterialShader ) );

		if( ShaderMapResult.second == false )
		{
			// The shader wasn't added, so delete it
			std::cout << "[FPS::MaterialManager::CreateShader] <INFO> "
				"Duplicate shader detected, not adding" << std::endl;
			SafeDelete< Shader >( pMaterialShader );
		}

		return FPS_OK;
	}
Example #3
0
Shader* ShadersLoader::LoadFromFile(const std::string& Filename)
{
	TiXmlDocument doc(Filename.c_str());
	if (!doc.LoadFile())
	{
		Logger::Log() << "[ERROR] TinyXML error : " << doc.ErrorDesc() << "\n";
		throw CLoadingFailed(Filename, "unable to load xml with TinyXML");
	}
	// Get the root
	TiXmlHandle hdl(&doc);
	TiXmlElement *root = hdl.FirstChild("Shader").Element();
	// Problem to find the root
	if (!root)
	{
		throw CLoadingFailed(Filename, "unable to find root (Shader)");
	}
	// Get the shader name and display it
	std::string name;
	std::string shaderTypeName;
	TinyXMLGetAttributeValue<std::string>(root, "name", &name);
	TinyXMLGetAttributeValue<std::string>(root, "type", &shaderTypeName);
	Logger::Log() << "[INFO] Load shader : " << name << " ( " << shaderTypeName
			<< " ) ... \n";
	ShaderType shaderType;
	if (shaderTypeName == "Basic")
		shaderType = BASIC_SHADER;
	else if (shaderTypeName == "GBuffer")
		shaderType = GBUFFER_SHADER;
	else
		throw CException("unknow shader type");

	// Load the shader compiler config
	ShaderCompilerConfig config = LoadShaderCompilerConfig(root);

	// Get the 2 files name
	// * Vertex shader
	TiXmlElement *shadername = root->FirstChildElement("VertexShader");
	if (!shadername)
	{
		throw CLoadingFailed(Filename, "unable to find VertexShader (Shader)");
	}
	std::string vertexShadername = std::string(
			shadername->Attribute("filename"));
	Logger::Log() << "   * Vertex shader : " << vertexShadername << "\n";
	// * Fragment shader
	shadername = root->FirstChildElement("FragmentShader");
	if (!shadername)
	{
		throw CLoadingFailed(Filename, "unable to find VertexShader (Shader)");
	}
	std::string fragmentShadername = std::string(
			shadername->Attribute("filename"));
	Logger::Log() << "   * Fragment shader : " << fragmentShadername << "\n";

	/*
	 * Find full path
	 */
	vertexShadername =
			CMediaManager::Instance().FindMedia(vertexShadername).Fullname();
	fragmentShadername =
			CMediaManager::Instance().FindMedia(fragmentShadername).Fullname();

	Shader* shader = 0;
	shadername = root->FirstChildElement("GeometryShader");
	if (shadername != 0)
	{
		std::string geometryShadername = std::string(
				shadername->Attribute("filename"));
		Logger::Log() << "   * Geometry shader : " << geometryShadername
				<< "\n";
		geometryShadername = CMediaManager::Instance().FindMedia(
				geometryShadername).Fullname();

		std::string in, out;
		TinyXMLGetAttributeValue(shadername, "in", &in);
		TinyXMLGetAttributeValue(shadername, "out", &out);
		shader = CShaderManager::Instance().loadfromFile(
				vertexShadername.c_str(), fragmentShadername.c_str(),
				geometryShadername.c_str(), shaderType, config);
		shader->SetGeometryShaderParameters(OpenGLEnumFromString(in),
				OpenGLEnumFromString(out));
	}
	else
	{
		Logger::Log() << "   * No Geometry shader\n";
		// Shader creation ....
		shader = CShaderManager::Instance().loadfromFile(
				vertexShadername.c_str(), fragmentShadername.c_str(),
				shaderType, config);
	}
	shader->Link();

	// Attrib blinding ...
	LoadShaderAttributs(shader, root);
	// Textures uniform
	LoadShaderTextures(shader, root);
	// Matrix uniform
	LoadShaderMatrix(shader, root);
	// FBO
	LoadShaderFBO(shader, root);
	// Materials
	LoadMaterials(shader, root);
	// Update all bindings
	// * Warning : Need to relink after
	shader->UpdateAll();
	return shader;
}
    Shader* ShaderManager::LoadShader(const string& aVertexShader, const string& aFragmentShader, vector<string> aAttributes)
    {
        //Safety check the filenames
        if(aVertexShader.length() == 0 || aFragmentShader.length() == 0)
        {
            Error(false, "Failed to load the shader, either the Vertex shader or fragment shader length is 0");
            return nullptr;
        }
        
        //If the asserts are hit either the vertex shader or the fragment shader files have no length
        assert(aVertexShader.length() > 0);
        assert(aFragmentShader.length() > 0);
        
        //Check to see if they v and f are the same
        string key = aVertexShader == aFragmentShader ? aVertexShader : aVertexShader + aFragmentShader;

        //Get the pair from the texture map
        Shader* shader = m_ShaderMap[key];
        
        //Is the shader pointer null?
        if(shader == nullptr)
        {
        	//Determine if GLSL version 140 is supported by this context.
            //We'll use this info to generate a GLSL shader source string
            //with the proper version preprocessor string prepended
            float glLanguageVersion;
            
            if(ServiceLocator::GetPlatformLayer()->GetPlatformType() == PlatformType_iOS)
            {
                sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "OpenGL ES GLSL ES %f", &glLanguageVersion);
            }
            else
            {
                sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "%f", &glLanguageVersion);	
            }
            
            //GL_SHADING_LANGUAGE_VERSION returns the version standard version form
            //with decimals, but the GLSL version preprocessor directive simply
            //uses integers (thus 1.10 should 110 and 1.40 should be 140, etc.)
            //We multiply the floating point number by 100 to get a proper
            //number for the GLSL preprocessor directive
            GLuint version = (GLuint)(100 * glLanguageVersion);
        	
            //Get the size of the version preprocessor string info so we know
            //how much memory to allocate for our sourceString
            GLsizei versionStringSize = sizeof("#version 123\n");
            
            //
            if(ServiceLocator::GetPlatformLayer()->GetPlatformType() == PlatformType_iOS)
            {
                versionStringSize = sizeof("#version 123 es\n");
            }

            //Was .vsh appended to the filename? If it was, remove it
            string vertexShader = string(aVertexShader);
            size_t found = vertexShader.find(".vsh");
            if(found != std::string::npos)
            {
                vertexShader.erase(found, 4);
            }
            
            //Which directory do we load?
            bool appendVersion = true;
            string directory = "Shaders";
            if(ServiceLocator::GetPlatformLayer()->GetPlatformType() == PlatformType_iOS && version < 300)
            {
                directory = "Shaders/ES2";
                appendVersion = false;
            }
            
            //Get the path for the vertex shader file
            string vertexPath = ServiceLocator::GetPlatformLayer()->GetPathForResourceInDirectory(vertexShader.c_str(), "vsh", directory.c_str());
            
            //Load the vertex shader
            File vertexShaderFile(vertexPath);
            
            //Safety check the vertex shader
            if(vertexShaderFile.GetBufferSize() == 0)
            {
                Error(false, "Failed to load the vertex shader");
                return nullptr;
            }
            
            //Allocate memory for the source string including the version preprocessor information
            GLchar* vertexSource = nullptr;
            
            //Do we append a version to the vertex source?
            if(appendVersion == true)
            {
                vertexSource = (GLchar*)malloc(vertexShaderFile.GetBufferSize() + versionStringSize);
        
                //Prepend our vertex shader source string with the supported GLSL version so
                //the shader will work on ES, Legacy, and OpenGL 3.2 Core Profile contexts
                if(ServiceLocator::GetPlatformLayer()->GetPlatformType() == PlatformType_iOS)
                {
                    sprintf(vertexSource, "#version %d es\n%s", version, vertexShaderFile.GetBuffer());
                }
                else
                {
                    sprintf(vertexSource, "#version %d\n%s", version, vertexShaderFile.GetBuffer());
                }
            }
            else
            {
                vertexSource = (GLchar*)malloc(vertexShaderFile.GetBufferSize());
                sprintf(vertexSource, "%s", vertexShaderFile.GetBuffer());
            }
            
            //Was .fsh appended to the filename? If it was, remove it
            string fragmentShader = string(aFragmentShader);
            found = fragmentShader.find(".fsh");
            if(found != std::string::npos)
            {
                fragmentShader.erase(found, 4);
            }
            
            //Get the path for the fragment shader file
            string fragmentPath = ServiceLocator::GetPlatformLayer()->GetPathForResourceInDirectory(fragmentShader.c_str(), "fsh", directory.c_str());
            
            //Load the fragment shader
            File fragmentShaderFile(fragmentPath);
            
            //Safety check the fragment shader
            if(fragmentShaderFile.GetBufferSize() == 0)
            {
                Error(false, "Failed to load the fragment shader");
                return nullptr;
            }
            
            //Allocate memory for the source string including the version preprocessor information
            GLchar* fragmentSource = nullptr;
            
            //Do we append a version to the fragment source?
            if(appendVersion == true)
            {
                fragmentSource = (GLchar*)malloc(fragmentShaderFile.GetBufferSize() + versionStringSize);
        
                //Prepend our fragment shader source string with the supported GLSL version so
                //the shader will work on ES, Legacy, and OpenGL 3.2 Core Profile contexts
                if(ServiceLocator::GetPlatformLayer()->GetPlatformType() == PlatformType_iOS)
                {
                    sprintf(fragmentSource, "#version %d es\n%s", version, fragmentShaderFile.GetBuffer());
                }
                else
                {
                    sprintf(fragmentSource, "#version %d\n%s", version, fragmentShaderFile.GetBuffer());
                }
            }
            else
            {
                fragmentSource = (GLchar*)malloc(fragmentShaderFile.GetBufferSize());
                sprintf(fragmentSource, "%s", fragmentShaderFile.GetBuffer());
            }
            
            //Create a new shader with the vertex and fragment shaders
            Shader* shader = new Shader(vertexSource, fragmentSource);
            shader->SetKey(key);
            
            //Cycle through the attributes and add them to the shader
            for(unsigned int i = 0; i < aAttributes.size(); i++)
            {
                shader->AddAttribute(aAttributes.at(i).c_str());
            }
            
            //Link the shader
            shader->Link();
            
            //Set the shader map pair for the filename key
            m_ShaderMap[key] = shader;
            
            //Free the memory for the vertex and fragment sources
            free(vertexSource);
            free(fragmentSource);
        }
        
        //Return the shader object
        return shader;
    }