Пример #1
0
bool initShaders(const char* vertShaderPath, const char* fragShaderPath)
{
	// create a program before linking shaders
	program = glCreateProgram();
	glUseProgram(program);

	// compile shader sources
	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	const char* vertexShaderSource = readShader(vertShaderPath); if (vertexShaderSource == NULL) return false;
	GLint vertexShaderLength = strlen(vertexShaderSource);
	glShaderSource(vertexShader, 1, &vertexShaderSource, &vertexShaderLength);
	glCompileShader(vertexShader);
	if (!checkShader(vertexShader, "vertexShader")){ printf("Unable to compile vertex shader\n"); return false; }
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	const char* fragmentShaderSource = readShader(fragShaderPath); if (fragmentShaderSource == NULL) return false;
	GLint fragmentShaderLength = strlen(fragmentShaderSource);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, &fragmentShaderLength);
	glCompileShader(fragmentShader);
	if (!checkShader(fragmentShader, "fragmentShader")){ printf("Unable to compile fragment shader\n"); return false; }
	// attach vertex/fragments shaders and link program
	glAttachShader(program, vertexShader);
	glAttachShader(program, fragmentShader);
	glLinkProgram(program);
	if (!checkProgram(program, "program")){ printf("Unable to link program\n"); return false; }

	// deallocate string
	free((void*)vertexShaderSource);
	free((void*)fragmentShaderSource);

	return true;
}
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();
	glEnable(GL_DEPTH_TEST);

	//Create shader program
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	program = glCreateProgram();
	glAttachShader(program, vertex_shader);
	glAttachShader(program, fragment_shader);
	glLinkProgram(program);

	//Generate the View Projection matrix
	glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	glm::mat4 proj = glm::perspective(45.0f, 800.0f / 800.0f, 0.1f, 100.0f);
	VP = proj * view;

	//Get uniforms
	uniMVP = glGetUniformLocation(program, "MVP");
	uniHue = glGetUniformLocation(program, "hue");

	//Set options
	glFrontFace(GL_CCW);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
Пример #3
0
/*
    Reads in and compiles shader objects
 */
void glutWidget::makeShaders()
{
    m_program = glCreateProgram();
	
    char *shadercode = readShader("shaders/vertexshader.vert");	//reads shader code (you can edit shader code with a text editor)
    m_vertexsh = glCreateShader(GL_VERTEX_SHADER_ARB);
    glShaderSource(m_vertexsh, 1, (const GLcharARB **)&shadercode,NULL);
    delete[] shadercode;
    glCompileShader(m_vertexsh);    //compiles shader
    printInfoLog(m_vertexsh);       //prints errors during shader compilation
    
    
    shadercode = readShader("shaders/fragmentshader.frag");     //reads shader code (you can edit shader code with a text editor)
    m_fragmentsh = glCreateShader(GL_FRAGMENT_SHADER_ARB);
    glShaderSource(m_fragmentsh, 1, (const GLcharARB **)&shadercode,NULL);
    delete[] shadercode;
    glCompileShader(m_fragmentsh);  //compiles shader
    printInfoLog(m_fragmentsh);     //prints errors during shader compilation

    glAttachShader(m_program,m_vertexsh);
    glAttachShader(m_program,m_fragmentsh);

    glLinkProgram(m_program);   //compiles fragment and vertex shader into a shader program
    printInfoLog(m_program);    //prints errors during program compilation
}
Пример #4
0
int readShaderSource(char *fileName, GLchar **vertexShader, GLchar **fragmentShader) {
	
    int vSize, gSize, fSize;

    //
    // Allocate memory to hold the source of our shaders.
    //
    vSize = shaderSize(fileName, EVertexShader);
    fSize = shaderSize(fileName, EFragmentShader);

    if ((vSize == -1) || (fSize == -1))
    {
        printf("Cannot determine size of the shader %s\n", fileName);
        exit(0);
    }

    *vertexShader = (GLchar *) malloc(vSize);
    *fragmentShader = (GLchar *) malloc(fSize);

    //
    // Read the source code
    //
    if (!readShader(fileName, EVertexShader, *vertexShader, vSize))
    {
        printf("Cannot read the file %s.vert\n", fileName);
        return 0;
    }
    if (!readShader(fileName, EFragmentShader, *fragmentShader, fSize))
    {
        printf("Cannot read the file %s.frag\n", fileName);
        return 0;
    }

    return 1;
}
//Helper function to create,initalize,compile and link shaderprograms.
void shader_HelperFunc(char * shadername)
{
	vShader = glCreateShader(GL_VERTEX_SHADER);
	fShader = glCreateShader(GL_FRAGMENT_SHADER);
	
	char *vtx = readShader("helloshader.vert");
	char *frag = readShader (shadername);
	
	const char * vtx2 =vtx;
	const char * frag2 = frag;
	
	glShaderSource(vShader, 1, &vtx2, NULL);
	glShaderSource(fShader, 1, &frag2, NULL);
	
	glCompileShader(vShader);
	glCompileShader(fShader);
	
	shader_program = glCreateProgram();
	glAttachShader (shader_program, vShader);
	glAttachShader (shader_program, fShader);
	glLinkProgram(shader_program);
	
	//debugging.......
	//printShaderInfoLog(vShader);
	//printShaderInfoLog(fShader);
	//printProgramInfoLog(shader_program);
	//printf("....................\n");
}
Пример #6
0
/**
 * Compiles all GLSL shaders
 */
void Resources::compileShaders() {
  GLuint vert, frag; // Vertex and fragment shader handles
  for(int i = 0; i < NUM_SHADERS; i++) {
    // Create handles for program and shaders
    programs[i] = glCreateProgram();
    vert = glCreateShader(GL_VERTEX_SHADER);
    frag = glCreateShader(GL_FRAGMENT_SHADER);
    // Read shaders from files
    char *vs_source = readShader(vertex_shaders[i]);
    char *fs_source = readShader(fragment_shaders[i]);
    // Loader shader sources
    glShaderSource(vert, 1, (const char**)&vs_source, NULL);
    glShaderSource(frag, 1, (const char**)&fs_source, NULL);
    // Compile shaders
    glCompileShader(vert);
    printShaderLog(vert);
    glCompileShader(frag);
    printShaderLog(frag);
    // Attach shaders to program
    glAttachShader(programs[i], vert);
    glAttachShader(programs[i], frag);
    // Link program
    glLinkProgram(programs[i]);
    printProgramLog(programs[i]);

    // Free memory from shader files
    delete[] vs_source;
    delete[] fs_source;
  }
}
Пример #7
0
bool Shader::readShaderSource()
{
    // Alocar memoria para o source code dos shaders
    m_VertShdStrLen = shaderSize(VERT_SHD);
    m_FragShdStrLen = shaderSize(FRAG_SHD);

    if (m_VertShdStrLen == -1)
    {
//		console->printfAndRender(1.0f, 0.0f, 0.0f, "Vertex Shader '%s.vert' not found", m_FileName);
        return false;
    }

    if (m_FragShdStrLen == -1)
    {
//		console->printfAndRender(1.0f, 0.0f, 0.0f, "Fragment Shader '%s.frag' not found", m_FileName);
		return false;
    }

	m_VertShdStr = (GLcharARB *) malloc(m_VertShdStrLen);
    m_FragShdStr = (GLcharARB *) malloc(m_FragShdStrLen);

    // Ler o source code dos shaders
	if (!readShader(VERT_SHD))
    {
//		console->printfAndRender(1.0f, 0.0f, 0.0f, "Error reading '%s.vert'", m_FileName);
        return false;
    }

    if (!readShader(FRAG_SHD)) {
//		console->printfAndRender(1.0f, 0.0f, 0.0f, "Error reading '%s.frag'", m_FileName);
        return false;
    }

    return true;
}
Пример #8
0
/** Creates a shader program using either the given strings as shader 
 *  source directly, or as filenames to load the shaders from disk, 
 *  depending on the value of the \c loadFromFiles parameter.
 */
osg::Program* ShaderManager::createProgram( const std::string& name, 
                                            const std::string& vertexSrc, 
                                            const std::string& fragmentSrc, 
                                            bool loadFromFiles )
{
    if (!_shadersEnabled)
        return new osg::Program;

    osg::ref_ptr<osg::Shader> vShader = 0;
    osg::ref_ptr<osg::Shader> fShader = 0;

    if (loadFromFiles)
    {
        vShader = readShader(vertexSrc);
        if (!vShader)
        {
            osg::notify(osg::WARN) << "Could not read shader from file " << vertexSrc << std::endl;
            return NULL;
        }

        fShader = readShader(fragmentSrc);
        if (!fShader)
        {
            osg::notify(osg::WARN) << "Could not read shader from file " << fragmentSrc << std::endl;
            return NULL;
        }
    }
    else
    {
        if (!vertexSrc.empty())
        {
            vShader = new osg::Shader( osg::Shader::VERTEX, vertexSrc );
        }
        if (!fragmentSrc.empty())
        {
            fShader = new osg::Shader( osg::Shader::FRAGMENT, fragmentSrc );
        }
    }

    osg::Program* program = new osg::Program;
    program->setName(name);

    std::string globalDefinitionsList = buildGlobalDefinitionsList(name);
    if (vShader.valid())
    {
        vShader->setShaderSource(globalDefinitionsList + vShader->getShaderSource());
        vShader->setName(name+"_vertex_shader");
        program->addShader( vShader.get() );
    }
    if (fShader.valid())
    {
        fShader->setShaderSource(globalDefinitionsList + fShader->getShaderSource());
        fShader->setName(name+"_fragment_shader");
        program->addShader( fShader.get() );
    }

    return program;
}
Пример #9
0
void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, Refraction* refraction)
{
    // use a define map to conditionally compile the shader
    std::map<std::string, std::string> defineMap;
    defineMap.insert(std::make_pair(std::string("@refraction_enabled"), std::string(refraction ? "1" : "0")));

    osg::ref_ptr<osg::Shader> vertexShader (readShader(osg::Shader::VERTEX, mResourcePath + "/shaders/water_vertex.glsl", defineMap));
    osg::ref_ptr<osg::Shader> fragmentShader (readShader(osg::Shader::FRAGMENT, mResourcePath + "/shaders/water_fragment.glsl", defineMap));

    osg::ref_ptr<osg::Texture2D> normalMap (new osg::Texture2D(readPngImage(mResourcePath + "/shaders/water_nm.png")));
    if (normalMap->getImage())
        normalMap->getImage()->flipVertical();
    normalMap->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
    normalMap->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
    normalMap->setMaxAnisotropy(16);
    normalMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
    normalMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);

    osg::ref_ptr<osg::StateSet> shaderStateset = new osg::StateSet;
    shaderStateset->addUniform(new osg::Uniform("normalMap", 0));
    shaderStateset->addUniform(new osg::Uniform("reflectionMap", 1));

    shaderStateset->setTextureAttributeAndModes(0, normalMap, osg::StateAttribute::ON);
    shaderStateset->setTextureAttributeAndModes(1, reflection->getReflectionTexture(), osg::StateAttribute::ON);
    if (refraction)
    {
        shaderStateset->setTextureAttributeAndModes(2, refraction->getRefractionTexture(), osg::StateAttribute::ON);
        shaderStateset->setTextureAttributeAndModes(3, refraction->getRefractionDepthTexture(), osg::StateAttribute::ON);
        shaderStateset->addUniform(new osg::Uniform("refractionMap", 2));
        shaderStateset->addUniform(new osg::Uniform("refractionDepthMap", 3));
        shaderStateset->setRenderBinDetails(MWRender::RenderBin_Default, "RenderBin");
    }
    else
    {
        shaderStateset->setMode(GL_BLEND, osg::StateAttribute::ON);

        shaderStateset->setRenderBinDetails(MWRender::RenderBin_Water, "RenderBin");

        osg::ref_ptr<osg::Depth> depth (new osg::Depth);
        depth->setWriteMask(false);
        shaderStateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
    }

    shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);

    osg::ref_ptr<osg::Program> program (new osg::Program);
    program->addShader(vertexShader);
    program->addShader(fragmentShader);
    shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON);

    node->setStateSet(shaderStateset);
    node->setUpdateCallback(NULL);
}
Пример #10
0
static void createProgram(const char *vertProgFile,
                          const char *fragProgFile)
{
    GLuint fragShader = 0, vertShader = 0;

    program = glCreateProgram();
    if (vertProgFile) {
        vertShader = glCreateShader(GL_VERTEX_SHADER);
        readShader(vertShader, vertProgFile);
        glAttachShader(program, vertShader);
    }

    if (fragProgFile) {
        fragShader = glCreateShader(GL_FRAGMENT_SHADER);
        readShader(fragShader, fragProgFile);
        glAttachShader(program, fragShader);
    }

    glLinkProgram(program);
    checkLink(program);

    glUseProgram(program);

    assert(glIsProgram(program));
    assert(glIsShader(fragShader));
    assert(glIsShader(vertShader));

    checkError(__LINE__);
    {   /*texture*/
        GLuint texLoc = glGetUniformLocationARB(program, "srcTex");
        glUniform1iARB(texLoc, 0);
    }
    {   /*setup offsets */
        float offsets[] = { 1.0 / texture.width,  1.0 / texture.height,
                            0.0                ,  1.0 / texture.height,
                            -1.0 / texture.width,  1.0 / texture.height,
                            1.0 / texture.width,  0.0,
                            0.0                ,  0.0,
                            -1.0 / texture.width,  0.0,
                            1.0 / texture.width, -1.0 / texture.height,
                            0.0                , -1.0 / texture.height,
                            -1.0 / texture.width, -1.0 / texture.height
                          };
        GLuint offsetLoc = glGetUniformLocationARB(program, "Offset");
        glUniform2fv(offsetLoc, 9, offsets);
    }
    setupConvolution();

    checkError(__LINE__);
}
Пример #11
0
void KeyComputeShader::loadDebugVisualiseShaders() {
    // compile shaders
    // Vertex Shader
    std::stringstream vert_buffer = readShader(VERT_SHADER_PATH_DEBUG);
    GLuint vert_shader = compileShader(GL_VERTEX_SHADER,
                                       vert_buffer.str());

    // Fragment Shader
    std::stringstream frag_buffer = readShader(FRAG_SHADER_PATH_DEBUG);
    GLuint frag_shader = compileShader(GL_FRAGMENT_SHADER,
                                       frag_buffer.str());

    this->key_visualise_shader = createProgram(vert_shader,
                                 frag_shader);
    // load display quad
    this->display_quad = constructQuad();

    // set uniform variables
    glm::vec2 tile_size_f = this->tile_size;
    glm::vec2 colour_step = glm::vec2(1.0 / n_tiles.x,
                                      1.0 / n_tiles.y);

    GLuint p_tile_size = glGetUniformLocation(this->key_visualise_shader,
                         "tile_size");
    GLuint p_colour_step = glGetUniformLocation(this->key_visualise_shader,
                           "colour_step");
    GLuint p_viewport = glGetUniformLocation(this->key_visualise_shader,
                        "viewport");
    GLuint p_k_tex = glGetUniformLocation(this->key_visualise_shader,
                                          "k_tex");


    glUseProgram(this->key_visualise_shader);
    glUniform2f(p_tile_size,
                tile_size_f.x,
                tile_size_f.y);
    glUniform2f(p_colour_step,
                colour_step.x,
                colour_step.y);
    glUniform2f(p_viewport,
                this->viewport.x,
                this->viewport.y);

    glUniform1i(p_k_tex,
                GL_TEXTURE0);

    glUseProgram(0);

    this->display_quad = constructQuad();
}
Пример #12
0
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);
	

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// This gets us a reference to the uniform variable in the vertex shader, which is called "MVP".
	// We're using this variable as a 4x4 transformation matrix
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniMVP = glGetUniformLocation(program, "MVP");

	// Creates the view matrix using glm::lookAt.
	// First parameter is camera position, second parameter is point to be centered on-screen, and the third paramter is the up axis.
	view = glm::lookAt(	glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	// Creates a projection matrix using glm::perspective.
	// First parameter is the vertical FoV (Field of View), second paramter is the aspect ratio, 3rd parameter is the near clipping plane, 4th parameter is the far clipping plane.
	proj = glm::perspective(45.0f, 800.0f / 600.0f, 0.1f, 1000.0f);

	trans = glm::rotate(trans, glm::radians(-30.0f), glm::vec3(1.0f, 0.0f, 0.0f));


	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and 
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
Пример #13
0
        virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
            if(!istream) return ReadResult::FILE_NOT_HANDLED;
            ReadResult rr = readShader(istream, options);
            if(rr.validShader())
            {
                osg::Shader* shader = rr.getShader();
                shader->setFileName(file);
                if (shader->getType() == osg::Shader::UNDEFINED)
                {
                    // set type based on filename extension, where possible
                    if (ext == "frag") shader->setType(osg::Shader::FRAGMENT);
                    if (ext == "vert") shader->setType(osg::Shader::VERTEX);
                    if (ext == "geom") shader->setType(osg::Shader::GEOMETRY);
                    if (ext == "tctrl") shader->setType(osg::Shader::TESSCONTROL);
                    if (ext == "teval") shader->setType(osg::Shader::TESSEVALUATION);
                    if (ext == "compute") shader->setType(osg::Shader::COMPUTE);
                }
            }
            return rr;
        }
Пример #14
0
/////////////////////////////////////////////////////////////////////////////
// Reads shader source code from file fileName. 
// It allocates memory for the null-terminated text string, 
// pointed to by *shaderSource.
// Returns 0 on error, otherwise return 1.
/////////////////////////////////////////////////////////////////////////////
int readShaderSource( const char *fileName, GLchar **shaderSource )
{
    // Allocate memory to hold the source of the shader.

    int fsize = fileSize(fileName);

    if (fsize == -1)
    {
		printf("ERROR: Cannot determine size of the shader %s.\n", fileName);
        return 0;
    }

    *shaderSource = (GLchar *) malloc(fsize + 1);  // Extra byte for null character.
    if (*shaderSource == NULL)
    {
        printf("ERROR: Cannot allocate memory for shader source.\n");
        return 0;
    }

    // Read the source code.

    if (!readShader(fileName, *shaderSource, fsize + 1))
    {
        printf("ERROR: Cannot read the file %s.\n", fileName);
        return 0;
    }

    return 1;
}
Пример #15
0
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// This gets us a reference to the uniform variable in the vertex shader, which is called "color".
	// We're using this variable to change color during runtime, without changing the buffer values.
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniMVP = glGetUniformLocation(program, "colorAndPos");

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face 
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CCW);

	// This is also not necessary, but more efficient and is generally good practice. By default, OpenGL will render both sides of a triangle that you draw. By enabling GL_CULL_FACE, 
	// we are telling OpenGL to only render the front face. This means that if you rotated the triangle over the X-axis, you wouldn't see the other side of the triangle as it rotated.
	glEnable(GL_CULL_FACE);

	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and 
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT, GL_FILL);
}
void DeferredHashedShader::loadShaders(const std::string& path_geometry_vert_shader,
                                       const std::string& path_geometry_frag_shader,
                                       const std::string& path_light_vert_shader,
                                       const std::string& path_light_frag_shader) {
  // -------------
  // Geometry pass
  // -------------
  // Vertex Shader
  // -----------------------------------------------------------------
  std::stringstream geometry_vert_shader_buffer =
    readShader(path_geometry_vert_shader);
  GLuint geometry_vert_shader = compileShader(GL_VERTEX_SHADER,
                                              geometry_vert_shader_buffer.str());

  // Fragment Shader
  // -----------------------------------------------------------------
  std::stringstream geometry_frag_shader_buffer = 
    readShader(path_geometry_frag_shader);

  GLuint geometry_frag_shader = compileShader(GL_FRAGMENT_SHADER,
                                              geometry_frag_shader_buffer.str());
  this->geometry_pass_sp = createProgram(geometry_vert_shader, geometry_frag_shader);

  // -------------
  // Light pass
  // -------------
  // Vertex Shader
  // -----------------------------------------------------------------
  std::stringstream light_vert_shader_buffer =
    readShader(path_light_vert_shader);
  GLuint light_vert_shader = compileShader(GL_VERTEX_SHADER,
                                           light_vert_shader_buffer.str());

  // Fragment Shader
  // -----------------------------------------------------------------
  std::stringstream light_frag_shader_buffer = 
    readShaderWithLightsAndOctreeMaps(
      path_light_frag_shader,
      this->world.p_lights.size(),
      this->p_light_manager->getLinklessOctree()->getNLevels());

  GLuint light_frag_shader = compileShader(GL_FRAGMENT_SHADER,
                                           light_frag_shader_buffer.str());
  this->light_pass_sp = createProgram(light_vert_shader, light_frag_shader);
}
Пример #17
0
bool CreateProgram(GLuint &programID, std::string shadernames[], GLenum shaderType[], int numberOfShaders)
{
	programID = glCreateProgram();

	bool success = true;

	for (int i = 0; i < numberOfShaders && success; i++)
	{
		std::string shaderStr = readShader(shadernames[i].c_str());
		const char *shaderChar = shaderStr.c_str();
		GLuint shader = glCreateShader(shaderType[i]);
		glShaderSource(shader, 1, &shaderChar, nullptr);
		glCompileShader(shader);

		GLint isCompiled = 0;
		glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
		if (isCompiled == GL_FALSE)
		{
			success = false;
			fprintf(stderr, "Failed to compile shader %s\n", shadernames[i].c_str());

			GLchar log[10240];
			GLsizei length;
			glGetShaderInfoLog(shader, 10239, &length, log);
			fprintf(stderr, "Compiler log:\n%s\n", log);
		}
		glAttachShader(programID, shader);
		glDeleteShader(shader);

	}

	// if we can link all shaders
	glLinkProgram(programID);

	GLint linked;
	glGetProgramiv(programID, GL_LINK_STATUS, &linked);
	if (linked != GL_TRUE)
	{
		success = false;
		fprintf(stderr, "Failed to link shader program %d\n", programID);
	}

	if (success)
	{
		return true;
	}
	else
	{
		glDeleteProgram(programID);
		programID = 0;
		return false;
	}
}
Пример #18
0
        virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
            if(!istream) return ReadResult::FILE_NOT_HANDLED;
            ReadResult rr = readShader(istream, options);
            if(rr.validShader()) rr.getShader()->setFileName(file);
            return rr;
        }
Пример #19
0
Shader& Shader::add(GLenum type, std::string filename) {
    std::string str = readShader(filename);
    const GLchar* shaderCode = str.c_str();

    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &shaderCode, NULL);
    glCompileShader(shader);
    
    GLint compiled;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    if (!compiled) {
        compilationErrors(shader);
        exit(EXIT_FAILURE);
    }
    
    shaders.push_back(shader);
    
    return *this;
}
Пример #20
0
// Initialization code
void init()
{	
	// Initializes the glew library
	glewInit();

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);

	// An element array, which determines which of the vertices to display in what order. This is sometimes known as an index array.
	GLuint elements[] = {
		0, 1, 2, 0, 2, 3
	};
	// These are the indices for a square

	vertices.push_back(VertexFormat(glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
	vertices.push_back(VertexFormat(glm::vec3(-1.0f, 1.0f, 0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
	vertices.push_back(VertexFormat(glm::vec3(1.0f, 1.0f, 0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
	vertices.push_back(VertexFormat(glm::vec3(1.0f, -1.0f, 0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
	
	// Create our square model from the data.
	square = new Model(vertices.size(), vertices.data(), 6, elements);

	// Create two GameObjects based off of the square model (note that they are both holding pointers to the square, not actual copies of the square vertex data).
	obj1 = new GameObject(square);
	obj2 = new GameObject(square);

	// Set beginning properties of GameObjects.
	obj1->SetVelocity(glm::vec3(0, 0.0f, 0.0f)); // The first object doesn't move.
	obj2->SetVelocity(glm::vec3(-speed, 0.0f, 0.0f));
	obj1->SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
	obj2->SetPosition(glm::vec3(0.7f, 0.0f, 0.0f));
	obj1->SetScale(glm::vec3(0.25f, 0.25f, 0.25f));
	obj2->SetScale(glm::vec3(0.05f, 0.05f, 0.05f));

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// This gets us a reference to the uniform variable in the vertex shader, which is called "MVP".
	// We're using this variable as a 4x4 transformation matrix
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniMVP = glGetUniformLocation(program, "MVP");

	// Creates the view matrix using glm::lookAt.
	// First parameter is camera position, second parameter is point to be centered on-screen, and the third paramter is the up axis.
	view = glm::lookAt(	glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	// Creates a projection matrix using glm::perspective.
	// First parameter is the vertical FoV (Field of View), second paramter is the aspect ratio, 3rd parameter is the near clipping plane, 4th parameter is the far clipping plane.
	proj = glm::perspective(45.0f, 800.0f / 600.0f, 0.1f, 100.0f);

	// Allows us to make one less calculation per frame, as long as we don't update the projection and view matrices every frame.
	PV = proj * view;

	// Create your MVP matrices based on the objects' transforms.
	MVP = PV * *obj1->GetTransform();
	MVP2 = PV * *obj2->GetTransform();

	// Calculate the Axis-Aligned Bounding Box for your object.
	obj1->CalculateAABB();
	obj2->CalculateAABB();

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face 
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CW);

	// This is also not necessary, but more efficient and is generally good practice. By default, OpenGL will render both sides of a triangle that you draw. By enabling GL_CULL_FACE, 
	// we are telling OpenGL to only render the front face. This means that if you rotated the triangle over the X-axis, you wouldn't see the other side of the triangle as it rotated.
	glEnable(GL_CULL_FACE);

	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and 
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT, GL_FILL);
}
Пример #21
0
int installShaders()
{
   GLuint verShader, fragShader;
   GLhandleARB vHandle, fHandle;
   GLint verCompiled,fragCompiled;
   GLint linked;
   const char *vertexShader,  *fragmentShader;  
   fprintf(stderr, "Attempting to create shaders\n");
   verShader = glCreateShader(GL_VERTEX_SHADER);
   fragShader = glCreateShader(GL_FRAGMENT_SHADER);
   fprintf(stderr, "Created Shaders\n");
  // vertexShader = readShader("Verts.vert", EVertexShader);
   vertexShader = readShader("cvert.vert", EVertexShader);
   fprintf(stderr, "Printing Vertex Shader:\n");
   fprintf(stderr, "%s\n", vertexShader);
   if (!vertexShader)
   {
     glDeleteShader(verShader);
     glDeleteShader(fragShader);
     fprintf(stderr, "Vertex Shader not found...exiting\n");
     exit(1);
   }

   //fragmentShader = readShader("Frags.frag", EFragmentShader);
   fragmentShader = readShader("cfrag.frag", EFragmentShader);
   fprintf(stderr, "Printing Fragment Shader:\n");
   fprintf(stderr, "%s\n", fragmentShader);
   if (!fragmentShader)
   {
     glDeleteShader(verShader);
     glDeleteShader(fragShader);
     fprintf(stderr, "Fragment Shader not found...exiting\n");
     exit(1);

   }


   fprintf(stderr, "\nSetting Vertex source\n");
   glShaderSource(verShader, 1, &vertexShader, NULL);
   fprintf(stderr, "\nSetting the Fragment  source\n");
   glShaderSource(fragShader, 1, &fragmentShader, NULL);
  
   fprintf(stderr, "Compiling Vertex Shader\n");
   glCompileShader(verShader);
   glGetShaderiv(verShader, GL_COMPILE_STATUS, &verCompiled);
   if (verCompiled == GL_FALSE){
      fprintf(stderr, "Vertex Shader not compiled\n");
      glDeleteShader(verShader);
      glDeleteShader(fragShader);
      return 0; 
      }

   fprintf(stderr, "Compiling Fragment Shader\n");
   glCompileShader(fragShader);
   glGetShaderiv(fragShader, GL_COMPILE_STATUS, &fragCompiled);
   if (fragCompiled == GL_FALSE){
      fprintf(stderr, "Fragment Shader not compiled\n");
      glDeleteShader(verShader);
      glDeleteShader(fragShader);
      return 0; 
      }

    
    prog = glCreateProgram();
    glAttachShader(prog, verShader);
    glAttachShader(prog, fragShader);
    //glBindAttribLocation(prog, 0, "VertexPosition");
    //glBindAttribLocation(prog, 1, "VertexColor");
    glLinkProgram(prog);
    glDeleteShader(verShader);
    glDeleteShader(fragShader);
    glGetProgramiv(prog, GL_LINK_STATUS, &linked);
    if (linked == GL_FALSE){
       fprintf(stderr, "Problems with linking\n");
      // glGetShaderInfoLog(prog, 1024, NULL, infoLog);
      // fprintf(stderr, "%s\n", infoLog);
       glDeleteProgram(prog);
       return 0;
       }
     else fprintf(stderr, "Linking prog was successful\n");
    fprintf(stderr, "Using Vertex and Frag Shaders\n");
    //glUseProgram(prog);
    //Now output vertices to see control points
    return 1;
}
	bool COGLES2SLMaterialRenderer::readFragmentShader( const c8 *fragmentShaderFile )
	{
		return readShader( GL_FRAGMENT_SHADER, fragmentShaderFile );
	}
	bool COGLES2SLMaterialRenderer::readVertexShader( const c8 *vertexShaderFile )
	{
		return readShader( GL_VERTEX_SHADER, vertexShaderFile );
	}
Пример #24
0
// Function to initialize shaders.
// TODO: Set multiple shader program integers
void SceneDrawer::setShaders(char* vertexShaderFile, char* fragmentShaderFile)
{
    // Error Debugging
    int IsCompiled_VS, IsCompiled_FS;
    int maxLength;
    char *vertexInfoLog;
    char *fragmentInfoLog;

    char* vertexShader = readShader(vertexShaderFile);
    char* fragmentShader = readShader(fragmentShaderFile);

    vertexShaderHandle = glCreateShader(GL_VERTEX_SHADER);
    fragmentShaderHandle = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(vertexShaderHandle, 1, (const char**) &vertexShader, NULL);
    glShaderSource(fragmentShaderHandle, 1, (const char**) &fragmentShader, NULL);

    glCompileShader(vertexShaderHandle);

    glGetShaderiv(vertexShaderHandle, GL_COMPILE_STATUS, &IsCompiled_VS);
    if(IsCompiled_VS == FALSE)
    {
        glGetShaderiv(vertexShaderHandle, GL_INFO_LOG_LENGTH, &maxLength);

        /* The maxLength includes the NULL character */
        vertexInfoLog = (char *)malloc(maxLength);

        glGetShaderInfoLog(vertexShaderHandle, maxLength, &maxLength, vertexInfoLog);

        /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
        /* In this simple program, we'll just leave */
        free(vertexInfoLog);
        return;
    }

    glCompileShader(fragmentShaderHandle);

    glGetShaderiv(fragmentShaderHandle, GL_COMPILE_STATUS, &IsCompiled_FS);
    if(IsCompiled_FS == FALSE)
    {
        glGetShaderiv(fragmentShaderHandle, GL_INFO_LOG_LENGTH, &maxLength);

        /* The maxLength includes the NULL character */
        fragmentInfoLog = (char *)malloc(maxLength);

        glGetShaderInfoLog(fragmentShaderHandle, maxLength, &maxLength, fragmentInfoLog);

        /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
        /* In this simple program, we'll just leave */
        free(fragmentInfoLog);
        return;
    }

    programHandle = glCreateProgram();

    glAttachShader(programHandle, vertexShaderHandle);
    glAttachShader(programHandle, fragmentShaderHandle);

    //glLinkProgram(programHandle);
    //glUseProgram(programHandle);
}
Пример #25
0
 virtual ReadResult readObject(std::istream& fin,const Options* options) const
 {
     return readShader(fin, options);
 }
Пример #26
0
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// Creates the view matrix using glm::lookAt.
	// First parameter is camera position, second parameter is point to be centered on-screen, and the third paramter is the up axis.
	view = glm::lookAt(glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	// Creates a projection matrix using glm::perspective.
	// First parameter is the vertical FoV (Field of View), second paramter is the aspect ratio, 3rd parameter is the near clipping plane, 4th parameter is the far clipping plane.
	proj = glm::perspective(45.0f, 800.0f / 800.0f, 0.1f, 100.0f);

	PV = proj * view;

	glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));

	MVP = PV* translation;
	MVP1 = MVP;

	view = glm::lookAt(glm::vec3(3.0f, 3.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	//Create another position and perspective for camera, and compute the MVP matrix for that position.
	//Since we'll be just interchanging between two positions of the camera, there is no point in computing the MVP every frame. We will do that later while implementing camera controls.
	MVP2 = (proj * view) * translation;
	// This gets us a reference to the uniform variable in the vertex shader, which is called "color".
	// We're using this variable to change color during runtime, without changing the buffer values.
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniMVP = glGetUniformLocation(program, "MVP");
	color = glGetUniformLocation(program, "blue");

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face 
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CCW);

	// This is also not necessary, but more efficient and is generally good practice. By default, OpenGL will render both sides of a triangle that you draw. By enabling GL_CULL_FACE, 
	// we are telling OpenGL to only render the front face. This means that if you rotated the triangle over the X-axis, you wouldn't see the other side of the triangle as it rotated.
	//glEnable(GL_CULL_FACE);
	//We are disabling hte cull face, because we wish to see both the front and back of the objects in wireframe mode for better understanding the depth.

	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and 
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
Пример #27
0
///
/// Adds shader to the shader vector.
///
/// @param type shaderType enum which represents the type of the shader
/// @param filePath Filepath of the shader
///
/// @return ID of the shader
unsigned int addShader(shaderType type, const char* filePath)
{
    //Adds a new shader to the vector and returns it's id
    shaders.push_back(Shader(type, readShader(filePath)));
    return shaders.capacity() - 1;
}
Пример #28
0
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();

	// Create an std::vector and put our vertices into it. These are just hardcoded values here defined once.
	std::vector<VertexFormat> vertices;

	vertices.push_back(VertexFormat(glm::vec2(1.0, 1.0), glm::vec3(0.25, -0.25, 0.0)));	// bottom right
	vertices.push_back(VertexFormat(glm::vec2(0.0, 1.0), glm::vec3(-0.25, -0.25, 0.0)));// bottom left
	vertices.push_back(VertexFormat(glm::vec2(1.0, 0.0), glm::vec3(0.25, 0.25, 0.0)));	// top right

	vertices.push_back(VertexFormat(glm::vec2(1.0, 0.0), glm::vec3(0.25, 0.25, 0.0)));	// top right
	vertices.push_back(VertexFormat(glm::vec2(0.0, 1.0), glm::vec3(-0.25, -0.25, 0.0)));// bottom left
	vertices.push_back(VertexFormat(glm::vec2(0.0, 0.0), glm::vec3(-0.25, 0.25, 0.0)));	// top left

	// This generates buffer object names
	// The first parameter is the number of buffer objects, and the second parameter is a pointer to an array of buffer objects (yes, before this call, vbo was an empty variable)
	// (In this example, there's only one buffer object.)
	glGenBuffers(1, &vbo);

	// Binds a named buffer object to the specified buffer binding point. Give it a target (GL_ARRAY_BUFFER) to determine where to bind the buffer.
	// There are several different target parameters, GL_ARRAY_BUFFER is for vertex attributes, feel free to Google the others to find out what else there is.
	// The second paramter is the buffer object reference. If no buffer object with the given name exists, it will create one.
	// Buffer object names are unsigned integers (like vbo). Zero is a reserved value, and there is no default buffer for each target (targets, like GL_ARRAY_BUFFER).
	// Passing in zero as the buffer name (second parameter) will result in unbinding any buffer bound to that target, and frees up the memory.
	glBindBuffer(GL_ARRAY_BUFFER, vbo);

	// Creates and initializes a buffer object's data.
	// First parameter is the target, second parameter is the size of the buffer, third parameter is a pointer to the data that will copied into the buffer, and fourth parameter is the 
	// expected usage pattern of the data. Possible usage patterns: GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, 
	// GL_DYNAMIC_READ, or GL_DYNAMIC_COPY
	// Stream means that the data will be modified once, and used only a few times at most. Static means that the data will be modified once, and used a lot. Dynamic means that the data 
	// will be modified repeatedly, and used a lot. Draw means that the data is modified by the application, and used as a source for GL drawing. Read means the data is modified by 
	// reading data from GL, and used to return that data when queried by the application. Copy means that the data is modified by reading from the GL, and used as a source for drawing.
	glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 6, &vertices[0], GL_STATIC_DRAW);

	// By default, all client-side capabilities are disabled, including all generic vertex attribute arrays.
	// When enabled, the values in a generic vertex attribute array will be accessed and used for rendering when calls are made to vertex array commands (like glDrawArrays/glDrawElements)
	// A GL_INVALID_VALUE will be generated if the index parameter is greater than or equal to GL_MAX_VERTEX_ATTRIBS
	glEnableVertexAttribArray(0);

	// Defines an array of generic vertex attribute data. Takes an index, a size specifying the number of components (in this case, floats)(has a max of 4)
	// The third parameter, type, can be GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, or GL_FLOAT
	// The fourth parameter specifies whether to normalize fixed-point data values, the fifth parameter is the stride which is the offset (in bytes) between generic vertex attributes
	// The fifth parameter is a pointer to the first component of the first generic vertex attribute in the array. If named buffer object is bound to GL_ARRAY_BUFFER (and it is, in this case) 
	// then the pointer parameter is treated as a byte offset into the buffer object's data.
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)8);
	// You'll note sizeof(VertexFormat) is our stride, because each vertex contains data that adds up to that size.
	// You'll also notice we offset this parameter by 8 bytes, this is because the vec3 position attribute is after the vec2 texCoord attribute. A vec2 has 2 floats, each being 4 bytes 
	// so we offset by 4*2=8 to make sure that our first attribute is actually the position. The reason we put position after texCoord in the struct has to do with padding.
	// For more info on padding, Google it.

	// This is our texCoord attribute, so the offset is 0, and the size is 2 since there are 2 floats for texCoord.
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)0);

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation
	glUseProgram(program);

	// This generates texture object names
	// The first parameter is the number of texture objects, and the second parameter is a pointer to an array of texture objects (yes, before this call, tex was an empty variable)
	// (In this example, there's only one texture object.)
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);

	int width, height; // Variables to store the width and height of the loaded texture. These will be empty until SOIL_load_image is called.

	// SOIL loads an image from the given filepath. The fourth parameter is the number of channels, and the last parameter is the format to load the data in.
	// This will load the data from your file into an "image", which is just a char array.
	unsigned char* image = SOIL_load_image("texture.png", &width, &height, 0, SOIL_LOAD_RGBA);

	// Using this image, we can call glTexImage2D to create a 2D texture. Parameters: target GL_TEXTURE_2D, level of detail (0 is base, x is xth mipmap reduction), internal format, 
	// width, height, border (if we're drawing a border around the image), format of texel data (must match internal format), type of texel data, and a pointer to image data in memory.
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

	// Now that we've created our texture on GL_TEXTURE_2D, we don't need the image anymore. So we free that memory using SOIL.
	SOIL_free_image_data(image);

	// Sets texture parameters, given a target, symbolic name of the texture parameter, and a value for that parameter.
	// Valid symbolic names are GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_WRAP_S, or GL_TEXTURE_WRAP_T.
	// Each has their own different set of values as well.
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);

	// Generates a mipmap for the texture, and there's no reason not to.
	glGenerateMipmap(GL_TEXTURE_2D);

	// This gets us a reference to the uniform variable in the vertex shader, which is called "trans".
	// We're using this variable as a 4x4 transformation matrix
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniTrans = glGetUniformLocation(program, "trans");

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face 
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CW);

	// This is also not necessary, but more efficient and is generally good practice. By default, OpenGL will render both sides of a triangle that you draw. By enabling GL_CULL_FACE, 
	// we are telling OpenGL to only render the front face. This means that if you rotated the triangle over the X-axis, you wouldn't see the other side of the triangle as it rotated.
	glEnable(GL_CULL_FACE);

	// Enables blending, which we will use for Alpha Blending our texture.
	// Basically, all color data for pixels has 4 floats, RGB is straightforward. It's just the value of Red, Green, and Blue. The fourth value is A, for Alpha. Alpha is the 
	// transparency value, basically determining that 1.0 means it is fully visible, and 0.0 is invisible, meaning 0.5 is halfway see-through. The sample texture we are using 
	// has transparency, so we are enabling blending to allow that transparency to be visible in our engine (otherwise, it will just be rendered black wherever it is transparent).
	// Note that this can have unwanted effects in other applications, and only certain file types actually include transparency (such as PNG).
	glEnable(GL_BLEND);

	// The glBlendFunc controls how the blending actually occurs. This particular setting modifies the incoming color by its alpha value, and then modifies the destination color by 
	// one minus the alpha value of the incoming color. Then the two are summed up and displayed.
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and 
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT, GL_FILL);
}
Пример #29
0
// Initialization code
void init()
{
	glewExperimental = GL_TRUE;
	// Initializes the glew library
	glewInit();

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// Tell our code to use the program
	glUseProgram(program);

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);

	// We are drawing a quad, what this means is that we're drawing two triangles to create a rectangle that covers the entire view area.
	// Thus, we're only passing in 4 vertices in a triangle fan to the vertex shader. It will then call the pixel shader and draw the pixel at it's appropriate coordinate.
	glm::vec2 quadVerts[4];
	quadVerts[0] = glm::vec2(1.0, -1.0);
	quadVerts[1] = glm::vec2(-1.0, -1.0);
	quadVerts[2] = glm::vec2(-1.0, 1.0);
	quadVerts[3] = glm::vec2(1.0, 1.0);
	// No reason to bother with a Z parameter, as the quad will fill up the entire screen, facing the camera directly, making depth irrelevant.

	// Generate your vertex array object name.
	glGenVertexArrays(1, &vao);
	
	// Bind the vertex array object
	glBindVertexArray(vao);

	// This generates buffer object names
	// The first parameter is the number of buffer objects, and the second parameter is a pointer to an array of buffer objects (yes, before this call, vbo was an empty variable)
	// (In this example, there's only one buffer object.)
	glGenBuffers(1, &vbo);

	// Binds a named buffer object to the specified buffer binding point. Give it a target (GL_ARRAY_BUFFER) to determine where to bind the buffer.
	// There are several different target parameters, GL_ARRAY_BUFFER is for vertex attributes, feel free to Google the others to find out what else there is.
	// The second paramter is the buffer object reference. If no buffer object with the given name exists, it will create one.
	// Buffer object names are unsigned integers (like vbo). Zero is a reserved value, and there is no default buffer for each target (targets, like GL_ARRAY_BUFFER).
	// Passing in zero as the buffer name (second parameter) will result in unbinding any buffer bound to that target, and frees up the memory.
	glBindBuffer(GL_ARRAY_BUFFER, vbo);	

	// Creates and initializes a buffer object's data.
	// First parameter is the target, second parameter is the size of the buffer, third parameter is a pointer to the data that will copied into the buffer, and fourth parameter is the 
	// expected usage pattern of the data. Possible usage patterns: GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, 
	// GL_DYNAMIC_READ, or GL_DYNAMIC_COPY
	// Stream means that the data will be modified once, and used only a few times at most. Static means that the data will be modified once, and used a lot. Dynamic means that the data 
	// will be modified repeatedly, and used a lot. Draw means that the data is modified by the application, and used as a source for GL drawing. Read means the data is modified by 
	// reading data from GL, and used to return that data when queried by the application. Copy means that the data is modified by reading from the GL, and used as a source for drawing.
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 4, &quadVerts[0], GL_STATIC_DRAW);
	// GL_ARRAY_BUFFER is for vertices in an array, all drawing commands of glDrawArrays will use vertices from that buffer.

	// By default, all client-side capabilities are disabled, including all generic vertex attribute arrays.
	// When enabled, the values in a generic vertex attribute array will be accessed and used for rendering when calls are made to vertex array commands (like glDrawArrays/glDrawElements)
	// A GL_INVALID_VALUE will be generated if the index parameter is greater than or equal to GL_MAX_VERTEX_ATTRIBS
	glEnableVertexAttribArray(0);

	// Defines an array of generic vertex attribute data. Takes an index, a size specifying the number of components (in this case, floats)(has a max of 4)
	// The third parameter, type, can be GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, or GL_FLOAT
	// The fourth parameter specifies whether to normalize fixed-point data values, the fifth parameter is the stride which is the offset (in bytes) between generic vertex attributes
	// The fifth parameter is a pointer to the first component of the first generic vertex attribute in the array. If a named buffer object is bound to GL_ARRAY_BUFFER (and it is, in this case) 
	// then the pointer parameter is treated as a byte offset into the buffer object's data.
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), (void*)0);
	// You'll note sizeof(glm::vec2) is our stride, because each vertex is that size.

	// This gets us a reference to the uniform variables in the vertex shader, which are called by the same name here as in the shader.
	// We're using these variables to define the camera. The eye is the camera position, and teh rays are the four corner rays of what the camera sees.
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	eye = glGetUniformLocation(program, "eye");
	ray00 = glGetUniformLocation(program, "ray00");
	ray01 = glGetUniformLocation(program, "ray01");
	ray10 = glGetUniformLocation(program, "ray10");
	ray11 = glGetUniformLocation(program, "ray11");

	// This is where we'll set up our camera location at.
	cameraPos = glm::vec3(4.0f, 8.0f, 8.0f);

	// These are four corner ray variables to store the output from our calcCameraRays function.
	glm::vec4 r00;
	glm::vec4 r01;
	glm::vec4 r10;
	glm::vec4 r11;

	// Call our function to calculate the four corner rays. We're choosing to make the point the camera centeras on at 0, 0.5, 0.
	// Our FoV angle is 60 degrees and our ratio is 800/600 which is just the pixel ratio.
	calcCameraRays(cameraPos, glm::vec3(0.0f, 0.5f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), 60.0f, 800.0f/600.0f, &r00, &r01, &r10, &r11);

	// Now set the uniform variables in the shader to match our camera variables (cameraPos = eye, then four corner rays)
	glUniform3f(eye, cameraPos.x, cameraPos.y, cameraPos.z);
	glUniform3f(ray00, r00.x, r00.y, r00.z);
	glUniform3f(ray01, r01.x, r01.y, r01.z);
	glUniform3f(ray10, r10.x, r10.y, r10.z);
	glUniform3f(ray11, r11.x, r11.y, r11.z);

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face 
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CW);
}
Пример #30
0
 virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
 {
     return readShader(file, options);
 }