GLuint Shaders::loadShaders(std::string vertexShader, std::string fragmentShader)
{
	GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
	GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);

	std::string vertexShaderData;
	std::ifstream vertexShaderFile(vertexShader);

	
	if (!vertexShaderFile)
	{
		std::cout << "Can't open vertex shader" << std::endl;

		return 0;
	}
	
	std::string line;
	while (std::getline(vertexShaderFile, line))
	{
		vertexShaderData += "\n" + line;
	}
	vertexShaderFile.close();

	std::string fragmentShaderData;
	std::ifstream fragmentShaderFile(fragmentShader);

	if (!fragmentShaderFile)
	{
		std::cout << "Can't open fragment shader" << std::endl;

		return 0;
	}
	std::string line2;
	while (std::getline(fragmentShaderFile, line2))
	{
		fragmentShaderData += "\n" + line2;
	}
	fragmentShaderFile.close();

	const char * vertexPtr = vertexShaderData.c_str();
	const char * fragmentPtr = fragmentShaderData.c_str();

	glShaderSource(vertexShaderId, 1, &vertexPtr, NULL);
	glShaderSource(fragmentShaderId, 1, &fragmentPtr, NULL);

	glCompileShader(vertexShaderId);
	glCompileShader(fragmentShaderId);

	GLuint shaderProgram = glCreateProgram();

	glAttachShader(shaderProgram, vertexShaderId);
	glAttachShader(shaderProgram, fragmentShaderId);
	glLinkProgram(shaderProgram);

	glDeleteShader(vertexShaderId);
	glDeleteShader(fragmentShaderId);

	return shaderProgram;
}
Shader ResourceManager::loadShaderFromFile(const GLchar* vShaderFile, const GLchar* fShaderFile, const GLchar* gShaderFile)
{
    // Define variables
    std::string vertexCode;
    std::string fragmentCode;
    std::string geometryCode;
    
    try
    {
        // Vertex
        std::ifstream vertexShaderFile(vShaderFile);
        std::stringstream vShaderStream;

        vShaderStream << vertexShaderFile.rdbuf();
        vertexShaderFile.close();

        vertexCode = vShaderStream.str();

        // Fragment
        std::ifstream fragmentShaderFile(fShaderFile);
        std::stringstream fShaderStream;

        fShaderStream << fragmentShaderFile.rdbuf();
        fragmentShaderFile.close();

        fragmentCode = fShaderStream.str();

        // Geometry
        if (gShaderFile != nullptr)
        {
            std::ifstream geometryShaderFile(gShaderFile);
            std::stringstream gShaderStream;

            gShaderStream << geometryShaderFile.rdbuf();
            geometryShaderFile.close();

            geometryCode = gShaderStream.str();
        }
    }
    catch (std::ifstream::failure e)
    {
        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
    }
    
    Shader shader;
    shader.Compile(vertexCode.c_str(), fragmentCode.c_str(), gShaderFile != nullptr ? geometryCode.c_str() : nullptr);
    return shader;
}
Exemple #3
0
Shader::Shader(string filename, GLenum shader_type) {
	name = filename;
	type = shader_type;

	// load the fragment shader.
	fstream fragmentShaderFile(filename, std::ios::in);
	string fragmentShaderSource;

	if (fragmentShaderFile.is_open()) {
		stringstream buffer;
		buffer << fragmentShaderFile.rdbuf();
		fragmentShaderSource = buffer.str();
	}
	else {
		fragmentShaderFile.close();
		ShaderHandle = 0;
		cerr << "could not find " << filename << endl;
		return;
	}
	fragmentShaderFile.close();

	ShaderHandle = glCreateShader( type );
	const char *g = fragmentShaderSource.c_str();
	glShaderSource( ShaderHandle, 1, &g, NULL );
	glCompileShader( ShaderHandle );

	//Error checking.
	int isCompiled;
	glGetShaderiv( ShaderHandle, GL_COMPILE_STATUS, &isCompiled );
	if( !isCompiled )
	{
	        GLint maxLength = 0;
	        glGetShaderiv( ShaderHandle, GL_INFO_LOG_LENGTH, &maxLength );

	        //The maxLength includes the NULL character
	        std::vector<char> errorLog( maxLength );
	        glGetShaderInfoLog( ShaderHandle, maxLength, &maxLength, errorLog.data() ); // &errorLog[0]
	        cerr << "error in file " << filename << endl;
	        cerr << errorLog.data() << endl;
	        glDeleteShader( ShaderHandle ); //Don't leak the shader.
	        return;
	}
}
Shader resourceManagerClass::loadShaderFromFile(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile)
{
    // 1. Retrieve the vertex/fragment source code from filePath
    std::string vertexCode;
    std::string fragmentCode;
    std::string geometryCode;
    try
    {
        // Open files
        std::ifstream vertexShaderFile(vShaderFile);
        std::ifstream fragmentShaderFile(fShaderFile);
        std::stringstream vShaderStream, fShaderStream;
        // Read file's buffer contents into streams
        vShaderStream << vertexShaderFile.rdbuf();
        fShaderStream << fragmentShaderFile.rdbuf();
        // close file handlers
        vertexShaderFile.close();
        fragmentShaderFile.close();
        // Convert stream into string
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
        // If geometry shader path is present, also load a geometry shader
        if (gShaderFile != nullptr)
        {
            std::ifstream geometryShaderFile(gShaderFile);
            std::stringstream gShaderStream;
            gShaderStream << geometryShaderFile.rdbuf();
            geometryShaderFile.close();
            geometryCode = gShaderStream.str();
        }
    }
    catch (std::exception e)
    {
        std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl;
    }
    const GLchar *vShaderCode = vertexCode.c_str();
    const GLchar *fShaderCode = fragmentCode.c_str();
    const GLchar *gShaderCode = geometryCode.c_str();
    // 2. Now create shader object from source code
    Shader shader;
    shader.Compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr);
    return shader;
}
Shader ResourceManager::loadShaderFromFile(const GLchar* vShaderFile, const GLchar* fShaderFile, const GLchar* gShaderFile) {
	std::string vertexCode, fragmentCode, geometryCode;

	try {
		// open the files
		std::ifstream vertexShaderFile(vShaderFile);
		std::ifstream fragmentShaderFile(fShaderFile);
		std::stringstream vShaderStream, fShaderStream;

		// read file's buffer contents into streams
		vShaderStream << vertexShaderFile.rdbuf();
		fShaderStream << fragmentShaderFile.rdbuf();
		vertexShaderFile.close();
		fragmentShaderFile.close();

		// convert stream to string
		vertexCode = vShaderStream.str();
		fragmentCode = fShaderStream.str();

		// if geometry path was passed in, load the geometry shader
		if (gShaderFile != nullptr) {
			std::ifstream geoShaderFile(gShaderFile);
			std::stringstream gShaderStream;
			gShaderStream << geoShaderFile.rdbuf();
			geoShaderFile.close();
			geometryCode = gShaderStream.str();
		}
	}
	catch (std::exception e) {
		std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl;
	}

	const GLchar* vShaderCode = vertexCode.c_str();
	const GLchar* fShaderCode = fragmentCode.c_str();
	const GLchar* gShaderCode = geometryCode.c_str();

	// create the shader object from source code
	Shader shader;
	shader.compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr);
	return shader;
}
Exemple #6
0
int main(int argc, char * argv[]) {

    // Load GLFW and Create a Window
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    auto mWindow = glfwCreateWindow(mWidth, mHeight, "OpenGL", nullptr, nullptr);

    // Check for Valid Context
    if (mWindow == nullptr) {
        fprintf(stderr, "Failed to Create OpenGL Context");
        return EXIT_FAILURE;
    }

    // Create Context and Load OpenGL Functions
    glfwMakeContextCurrent(mWindow);
    gladLoadGL();
    fprintf(stderr, "OpenGL %s\n", glGetString(GL_VERSION));

    glfwSetErrorCallback(&errorCallback);

    float vertices[] = {
        0.0f, 0.5f,
        0.5f, -0.5f,
        -0.5f, -0.5f,
    };

    // Create Vertex Array Object
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    std::ifstream vertexShaderFile(PROJECT_SOURCE_DIR "/Glitter/Shaders/main.vert");
    std::string vertexShaderStr((std::istreambuf_iterator<char>(vertexShaderFile)),
                                std::istreambuf_iterator<char>());
    auto vertexSource = vertexShaderStr.c_str();
    // Create and compile the vertex shader
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, NULL);
    glCompileShader(vertexShader);
    assertShaderCompile(vertexShader);

    std::ifstream fragmentShaderFile(PROJECT_SOURCE_DIR "/Glitter/Shaders/main.frag");
    std::string fragmentShaderStr((std::istreambuf_iterator<char>(fragmentShaderFile)),
                                  std::istreambuf_iterator<char>());
    auto fragmentSource = fragmentShaderStr.c_str();
    // Create and compile the fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    glCompileShader(fragmentShader);
    assertShaderCompile(fragmentShader);

    // Link the vertex and fragment shader into a shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);
    std::cout << glGetError() << std::endl;
    glUseProgram(shaderProgram);
    std::cout << glGetError() << std::endl;
    std::cout << glGetError() << std::endl;
    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    std::cout << glGetError() << std::endl;

    // Rendering Loop
    while (glfwWindowShouldClose(mWindow) == false) {
        if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(mWindow, true);

        // Background Fill Color
        glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw a triangle from the 3 vertices
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Flip Buffers and Draw
        glfwSwapBuffers(mWindow);
        glfwPollEvents();
    }
    glfwTerminate();

    glDeleteProgram(shaderProgram);
    glDeleteShader(fragmentShader);
    glDeleteShader(vertexShader);

    glDeleteBuffers(1, &vbo);

    glDeleteVertexArrays(1, &vao);

    return EXIT_SUCCESS;
}
    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;
    }