Beispiel #1
0
Shader* ResourceManager::createShader(const std::string& lexical_name, const std::string& vs, const std::string& fs, ShaderDataType data_type){
    if(shader_lexical_names_.find(lexical_name) != shader_lexical_names_.end()){
        std::cerr << "Error: Shader lexical names must not be duplicate" << std::endl;
        return nullptr;
    }
    std::uint32_t id = shader_id_counter_++;

    if(data_type == SHADER_FILE){
        std::ifstream vs_file(vs);
        if(!vs_file.is_open()){
            std::cerr << "Error: unable to find vertex shader file" << std::endl;
            return nullptr;
        }

        std::stringstream vs_stream;
        vs_stream << vs_file.rdbuf();
        std::string vs_dat = vs_stream.str();

        std::ifstream fs_file(fs);
        if(!fs_file.is_open()){
            std::cerr << "Error: unable to find fragment shader file" << std::endl;
            return nullptr;
        }

        std::stringstream fs_stream;
        fs_stream << fs_file.rdbuf();
        std::string fs_dat = vs_stream.str();

        std::unique_ptr<Shader> shader;
        try{
            shader = std::unique_ptr<Shader>(new Shader(lexical_name, id, vs_dat, fs_dat));
        }
        catch(ShaderCompileError e){
            std::cerr << "Error: " << e.what() << std::endl;
            return nullptr;
        }

        shaders_[id] = std::move(shader);
    }
    else{
        std::unique_ptr<Shader> shader;
        try{
            shader = std::unique_ptr<Shader>(new Shader(lexical_name, id, vs, fs));
        }
        catch(ShaderCompileError e){
            std::cerr << "Error: " << e.what() << std::endl;
            return nullptr;
        }

        shaders_[id] = std::move(shader);
    }

    shader_lexical_names_[lexical_name] = id;
}
Beispiel #2
0
	// Reads, compiles, links and returns a shader from the given paths
	GLuint loadShader(const std::string &vertexPath, const std::string &fragmentPath) {

		
		cout << "Loading shader program with shaders:" << endl;
		cout << "    Vertex:   " << std::filesystem::canonical(vertexPath) << endl;
		cout << "    Fragment: " << std::filesystem::canonical(fragmentPath) << endl;
        
        
        // Read our shaders into the appropriate buffers
		std::ifstream vs_file(vertexPath);
        std::string vertexSource{
            std::istreambuf_iterator<char>(vs_file),
            std::istreambuf_iterator<char>()
        };

		std::ifstream fs_file(fragmentPath);
        std::string fragmentSource{
            std::istreambuf_iterator<char>(fs_file), 
            std::istreambuf_iterator<char>()
        };

#if 0
        DIR* vertFile = opendir(vertexPath.c_str());
        if (vertFile == nullptr) {
            glutil::fatal_error("Vertex file not found.");
        }

        DIR* fragFile = opendir(fragmentPath.c_str());
        if (fragFile == nullptr) {
            glutil::fatal_error("Fragment file not found.");
        }
#endif // 0
#if 1
        const char *vs = vertexSource.c_str();
        const char *fs = fragmentSource.c_str();
        cout << "Vertex shader:" << endl
            << vs << endl
            << endl
            << "Fragment shader:" << endl
            << fs << endl;
#endif // 0



		// Create an empty vertex shader handle
		GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

		// Send the vertex shader source code to GL
		// Note that std::string's .c_str is NULL character terminated.
		const GLchar *source = (const GLchar *)vertexSource.c_str();
		glShaderSource(vertexShader, 1, &source, NULL);

		// Compile the vertex shader
		glCompileShader(vertexShader);

		GLint isCompiled = 0;
		glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
		if (isCompiled == GL_FALSE)
		{
			GLint maxLength = 0;
			glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

			// The maxLength includes the NULL character
			std::vector<GLchar> infoLog(maxLength);
			glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);

			// We don't need the shader anymore.
			glDeleteShader(vertexShader);

			// Time to use the infoLog.
			for (unsigned int i = 0; i < infoLog.size(); i++)
			{
				std::cerr << infoLog[i];
			}
			std::cerr << endl;


			// In this simple program, we'll just leave
			return -1;
		}

		// Create an empty fragment shader handle
		GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

		// Send the fragment shader source code to GL
		// Note that std::string's .c_str is NULL character terminated.
		source = (const GLchar *)fragmentSource.c_str();
		glShaderSource(fragmentShader, 1, &source, NULL);

		// Compile the fragment shader
		glCompileShader(fragmentShader);

		glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
		if (isCompiled == GL_FALSE)
		{
			GLint maxLength = 0;
			glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);

			// The maxLength includes the NULL character
			std::vector<GLchar> infoLog(maxLength);
			glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);

			// We don't need the shader anymore.
			glDeleteShader(fragmentShader);
			// Either of them. Don't leak shaders.
			glDeleteShader(vertexShader);

			// Time to use the infoLog.
			for (unsigned int i = 0; i < infoLog.size(); i++)
			{
				std::cerr << infoLog[i];
			}
			std::cerr << endl;
			// In this simple program, we'll just leave
			return -1;
		}

		// Vertex and fragment shaders are successfully compiled.
		// Now time to link them together into a program.
		// Get a program object.
		GLuint program = glCreateProgram();

		// Attach our shaders to our program
		glAttachShader(program, vertexShader);
		glAttachShader(program, fragmentShader);

		// Link our program
		glLinkProgram(program);

		// Note the different functions here: glGetProgram* instead of glGetShader*.
		GLint isLinked = 0;
		glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);

		if (isLinked == GL_FALSE)
		{
			GLint maxLength = 0;
			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

			// The maxLength includes the NULL character
			std::vector<GLchar> infoLog(maxLength);
			glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);

			// We don't need the program anymore.
			glDeleteProgram(program);
			// Don't leak shaders either.
			glDeleteShader(vertexShader);
			glDeleteShader(fragmentShader);

			// Time to use the infoLog.
			for (unsigned int i = 0; i < infoLog.size(); i++)
			{
				std::cerr << infoLog[i];
			}
			std::cerr << endl;
            
			// In this simple program, we'll just leave
			return -1;
		}

		GLint maxLength = 0;
		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

		if (maxLength > 0) {

			// The maxLength includes the NULL character
			std::vector<GLchar> infoLog(maxLength);
			glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
			for (unsigned int i = 0; i < infoLog.size(); i++)
			{
				std::cerr << infoLog[i];
			}
			std::cerr << endl;
		
		}
		// Detach shaders after a successful link.
		glDetachShader(program, vertexShader);
		glDetachShader(program, fragmentShader);


		cout << "Shader loaded." << endl;
		return program;
	}