Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Shader : how to pass vertex attibutes to an sf::Shader ?  (Read 2500 times)

0 Members and 1 Guest are viewing this topic.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Hi!
glEnable and glDisable client states are deprecated and doesn't work anymore with vbo until opengl 3.

So I've decided to write modern opengl source code for graphics cards which support new opengl versions.

#include <SFML/Graphics.hpp>
#include <glew.h>
#include <SFML/OpenGL.hpp>
#include <fstream>
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){

    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if(VertexShaderStream.is_open())
    {
        std::string Line = "";
        while(getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if(FragmentShaderStream.is_open()){
        std::string Line = "";
        while(getline(FragmentShaderStream, Line))
            FragmentShaderCode += "\n" + Line;
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s\n", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> VertexShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);

    // Compile Fragment Shader
    printf("Compiling shader : %s\n", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);

    // Link the program
    fprintf(stdout, "Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage(std::max(InfoLogLength, int(1)) );
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;
}
int main()
{
    // create the window
    sf::Window window(sf::VideoMode(800, 600), "My window", sf::Style::Default, sf::ContextSettings(32));
    glewInit();
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);
    static const GLfloat g_vertex_buffer_data[] = {
       -1.0f, -1.0f, 0.0f,
       1.0f, -1.0f, 0.0f,
       0.0f,  1.0f, 0.0f,
    };

    // This will identify our vertex buffer
    GLuint vertexbuffer;
    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    glGenBuffers(1, &vertexbuffer);
    // The following commands will talk about our 'vertexbuffer' buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    // Give our vertices to OpenGL.
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    //Unbind the buffer.
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    // Create and compile our GLSL program from the shaders
    GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
    // run the program as long as the window is open
    glBindAttribLocation(programID, 0, "vertexPosition_modelspace");
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::Resized)
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
        }

        // clear the window with black color
        glClear(GL_COLOR_BUFFER_BIT);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        //const char* data = reinterpret_cast<const char*>(&vertices[0]);
        glVertexAttribPointer(
           0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
           3,                  // size
           GL_FLOAT,           // type
           GL_FALSE,           // normalized?
           0,                  // stride
           (void*)0            // array buffer offset
        );
        // Use our shader
        glUseProgram(programID);
        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        // draw everything here...
        // window.draw(...);

        // end the current frame
        window.display();
    }
    glDeleteBuffers(1, &vertexbuffer);
    return 0;
}
 
The shaders :
#version 130
attribute vec3 vertexPosition_modelspace;
void main() {
    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;
}
 
#version 130
out vec3 color;
 
void main(){
    color = vec3(1,0,0);
}
 

In your tutorials it only explain how to pass uniform variables to sf::Shaders but in modern opengl we need to pass attributes to sf::Shader because glVertexPointer, glColorPointer, ... are deprecated.

Should I modify the class sf::Shader myself to pass vertex attributes into my shader ?

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: sf::Shader : how to pass vertex attibutes to an sf::Shader ?
« Reply #1 on: May 04, 2014, 04:50:41 pm »
sf::Shader doesn't support generic vertex attributes. So yes if you want to use vertex attributes you'll have to add them yourself or avoid sf::Shader.
For 3D I don't use sf::Shader and I directly use openGL shaders.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: sf::Shader : how to pass vertex attibutes to an sf::Shader ?
« Reply #2 on: May 04, 2014, 08:50:04 pm »
Ok, I've added these functionnality in the sf::Shader class.  :)

hoogamaphone

  • Newbie
  • *
  • Posts: 1
    • View Profile
    • Email
Re: sf::Shader : how to pass vertex attibutes to an sf::Shader ?
« Reply #3 on: June 26, 2014, 12:13:35 am »
I'm new to SFML, OpenGl, and Shaders, but I'd like to be able to pass attributes to the shader. Would you be willing to share some of the modifications you made to the Shader class to be able to pass attributes?